Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discriminants/variant numbers are checked too late, causing assertion violations in user-defined functor #2508

Closed
markusscherer opened this issue Sep 2, 2024 · 2 comments · Fixed by #2509
Labels
bug - identified Bugs with an identified cause enhancement

Comments

@markusscherer
Copy link
Contributor

Hi everybody!

I encountered an issue very similar to #2373.

When executing the following code (with the functors.cpp file below; both minified from actual code the bug appeared in), I can consistently trigger an assertion violation in the current master (e6cc668).

.functor id(symbol): symbol stateful
.functor decode(symbol): symbol stateful

.type T = C1 {A0 : symbol} | C2 {A0: number}

.decl A(A2: T)
.decl B()

A($C2(10000000)).
.output B

B() :-
  A($C1(X)),
  (@decode(X) = @id("Y")).
//functors.cpp
#include "souffle/SymbolTable.h"
#include "souffle/RecordTable.h"

extern "C" {

souffle::RamDomain id(souffle::SymbolTable* symbolTable, souffle::RecordTable* recordTable, souffle::RamDomain x) {
  return x;
}

souffle::RamDomain decode(souffle::SymbolTable* symbolTable, souffle::RecordTable* recordTable, souffle::RamDomain x) {
  symbolTable->decode(x);
  return x;
}

}

Error:

souffle: /build/source/src/include/souffle/datastructure/ConcurrentFlyweight.h:296: const Key& souffle::ConcurrentFlyweight<LanesPolicy, Key, Hash, KeyEqual, KeyFactory>::fetch(lane_id, index_type) const [with LanesPolicy = souffle::ConcurrentLanes; Key = std::__cxx11::basic_string<char>; Hash = std::hash<std::__cxx11::basic_string<char> >; KeyEqual = std::equal_to<std::__cxx11::basic_string<char> >; KeyFactory = souffle::details::Factory<std::__cxx11::basic_string<char> >; lane_id = long unsigned int; index_type = long unsigned int]: Assertion `Idx < SlotCount.load(std::memory_order_relaxed)' failed.
[1]    674346 IOT instruction (core dumped)  souffle min-rules.dl

The problem (as in #2373) seems to be that the discriminant is checked after the "payload" of the ADT is passed into the functor (which then does a lookup using an improperly constrained ordinal). I first found the problem by checking the C++ code, but it is better visible in the transformed RAM

// annotated output of `souffle --show=transformed-ram min-rules.dl | cat -n`
// ...SNIP...
     9	   QUERY
    10	    IF (ISEMPTY(+disconnected0) AND (NOT ISEMPTY(A)))
    11	     FOR t0 IN A
    12	      IF (NOT ISEMPTY(+disconnected0)) BREAK
    13	       UNPACK t1 ARITY 2 FROM t0.0
    14	        IF ((@decode(t1.1) = @id(STRING("Y"))) AND (t1.0 = NUMBER(0)))
                     ^^^^^^^ functor call      before check ^^^^^^^^^^^^^^^^
    15	         INSERT () INTO +disconnected0
    16	   END QUERY
// ...SNIP...
@markusscherer
Copy link
Contributor Author

I'm not well-acquainted with the code that does the ordering of premises, but one thing I deem possible is that returning the maximum integer here, might cause an integer overflow somewhere else (maybe here?). That would cause the return value to be std::numeric_limits<int>::max() + std::numeric_limits<int>::max() which is -2.

I'm wildly conjecturing here, but it might be that ordering the premises by purely looking at one premise at a time is not even possible. Maybe something like a topological sort on a graph describing the "constrainedness" of ADT values has to come first with the current numerical sorting as a tie-breaker.

@quentin
Copy link
Member

quentin commented Sep 2, 2024

I confirm there is an overflow occurring in the complexity analysis. A simple fix is to set complexity to a smaller value like std::numeric_limits<int>::max() >> 6 that is still safe for expressions with less than 64 user-defined functors.

I agree with you that in a more general case, ADT branch constraints should be evaluated strictly before accessing any other part of the ADT value.

@quentin quentin added bug - identified Bugs with an identified cause enhancement labels Sep 2, 2024
quentin added a commit to quentin/souffle that referenced this issue Sep 2, 2024
quentin added a commit to quentin/souffle that referenced this issue Sep 2, 2024
quentin added a commit that referenced this issue Sep 4, 2024
* fix: integer overflow in Complexity analysis

fixes #2508
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug - identified Bugs with an identified cause enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants