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

Wrapped functions no longer cooperate with unwinder #1467

Open
Bike opened this issue Jun 14, 2023 · 0 comments
Open

Wrapped functions no longer cooperate with unwinder #1467

Bike opened this issue Jun 14, 2023 · 0 comments
Labels

Comments

@Bike
Copy link
Member

Bike commented Jun 14, 2023

A while back I made the unwinder work more efficiently by using setjmp/longjmp instead of C++ exceptions. In order for this to work with C++ functions, C++ functions that aren't written with unwinding in mind are assumed to be "uncooperative", which is indicated by their pushing an "Unknown" dynenv marker to the stack of Lisp dynamic environments. The scraper determines whether a function is cooperative with the CL_UNWIND_COOP macro. CL_UNWIND_COOP(true) means a function is cooperative, so the wrapper doesn't need to push the marker; otherwise it does need to push the marker.

Changes made around the bytecode wrapper switchover appear to have changed the wrappers so they no longer go through the scraper-generated c-wrappers.h. The new wrappers now ignore the cooperativity mark, meaning that all functions are assumed to cooperate. This is a problem because not all of them do.

Simple example:

(defvar *test* 7)
(block nil (core:call-with-variable-bound '*test* 8 (lambda () (return))))
*test* ; => 8

The nonlocal exit leaves call-with-variable-bound, but because the unknown dynenv marker is not pushed, the unwinder does not resort to a C++ exception, and so the destructor that resets the symbol value is never executed.

This can cause more severe problems. Gleefre's initial report was that the package local nicknames compatibility library has tests that hang. The hang occurs because add-package-local-nickname uses core:call-with-package-read-write-lock, which uses RAII to grab a package lock; if the body signals an error, as happens in the test, the lock is never relinquished, causing a lot of further uses of whatever package is in question to hang.

@Bike Bike added the bug label Jun 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant