-
Notifications
You must be signed in to change notification settings - Fork 161
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
volatile's to be used in libgap-calling functions? #5714
Comments
Never seen anything like this before. Reading the gcc bugzilla, the issue seems to be incorrect longjmp/setjmp in sage itself, needing more volatile? Or did I read it wrong? |
My understanding is that there some arguments of IMHO it might be a defect of Sage's interface (hello, side-effects :-)), which always creates a refcounted Python object to hold a GAP @embray - have you encountered this? |
see also https://trofi.github.io/posts/312-the-sagemath-saga.html - it does say that Sage needs more |
Yes, this is just normal GAP rules, you need lots more volatile. Might be tricky to do with pyx, not sure if it is making variables behind the scenes you can't attach volatile to? The best option is probably to make a small GAP wrapper which does the GAP call, and setjmp / longjmp, and then returns some method of identifying an error occurred. That's not a hard function to write, but it would need an API designing. |
For each GAP object, Sage's interface creates/updates a refcount, with a pointer pointing to the object - to prevent GAP's GC from collecting it prematurely. But often one can get away without it, as far as I understand. E.g. we can hold a GAP object in a local variable, Obj foo(int bar) {
Obj gbar;
gbar = GAP_NewObjIntFromInt(bar);
return GAP_FooBar(gbar);
} Correct - in the sense that it does not create any uncollectable garbage, even if one of Right? My preliminary tests with a modified Sage interface, which optionally skips doing a refcount for particular GAP objects, indicates that no crashes happen this way. I'd like to add more examples along these lines in GAP's
|
As I understand it, the issue isn't anything to do with libgap, or GAP at all. It's all about longjmp, and the following text from longjmp's docs. We could write some tests, nothing wrong with that, but I would expect they'll be fine, as long as they follow the longjmp rules (from man longjmp): the values of automatic variables are unspecified after a call to longjmp() if they meet all the following criteria: • they are local to the function that made the corresponding setjmp() call; |
It has to do with GAP's GC, as longjmp was breaking Sage's manual management of GC-able GAP objects - specifically, decrementing refcount/destroying the pointer if refcount reached 0.
this bullet actually is not 100% correct, IMHO, as it includes the case of an automatic variable being held in a register (as an optimising compiler might arrange for - and actually does in this case). Then "changed" means "reused", as often happens to registers. One of these values, to be used by refcount processing in longjmp recovery, is held in a register, and gets invalidated by longjmp. |
I don't see anything we could do here. As far as I can tell, the issue is purely on the caller side: code using It is technically impossible to add those I have no idea if this is applicable in your code, but: It may help to keep uses of ok = GAP_Enter();
if (ok) {
callSubDoingActualWork(args);
}
GAP_Leave();
which minimizes the need of inserting That said, I see nothing we can do. But if you find a fix that requires changes in libgap after all, of course don't hesitate to submit a PR. |
Observed behaviour
Crash upon calling a GAP function with wrong number of arguments via
GAP_CallFunc3Args
, (e.g. Sum(1,2,3))as described in sagemath/sage#37026
and sagemath/sage#37951 - and also
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114872
Expected behaviour
normal return with a GAP error
GAP etc. versions
GAP 4.13.0, GAP 4.12.2, gcc 13.2.1 (important - not reproducible with other compilers), Python 3.12
From assembly code GCC people (see GCC link above) established that a parameter is held in a register (something that can be worked around by compiling with
-O0
), and, naturally, after GAP's longjmp, it gets trashed, etc.Do you see this happening with other uses of libgap, or SageMath is a pioneer here?
The text was updated successfully, but these errors were encountered: