-
Notifications
You must be signed in to change notification settings - Fork 19
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
GAP.Globals.Display once a GAP error has occured #516
Comments
@zickgraf Thanks for this report. I have played around more with this problem (in Julia 1.4.0).
Can you reproduce this behaviour? Concerning the question to which stream the output of |
Not exactly, but in general yes. The result seems to depend on the width of the terminal. Observation: If I
I assume something buffers the output until some condition (newline?) is reached. If I immediately print a newline, everything works as expected:
I can confirm that it does not work from Julia, not even in |
Previously, we threw a Julia exception in the `error_handler` function, which is called by GAP's `JUMP_TO_CATCH`, which in turn is invoked by GAP's `ErrorInner`. The problem with that is that by throwing a Julia exception, we aborted the GAP exception handling prematurely. As a result, any surrounding `GAP_CATCH` blocks had no chance to run. This had primarily two noticeable effects: 1. Input/output redirection set up by surrounding GAP code via `OpenInput`, `OpenInputStream`, `OpenOutput`, `OpenOutputStream` was not reverted. 2. The pointer GAP uses to keep track of which code is currently being executed ("LVars") was not reset. Effect 2 could be counteracted by calling `SWITCH_TO_BOTTOM_LVARS`. Effect 1 in past GAP versions mostly lead to some output which was not showing up, see <oscar-system#516>. With the current GAP kernel code, though, the "stack of outputs" was changed into a "linked list of outputs", with most outputs residing on the execution stack. As a result, failing to close outputs now can lead to crashes or general weirdness. To fix this, we need to let GAP follow its sequence of exception handlers, and only throw a Julia exception at the very end. The standard way to do this is to surround any calls into the GAP kernel by `GAP_TRY` and `GAP_CATCH`. But the way these C macros work would mean that we couldn't simply use `ccall` anymore. We'd have to add tons of wrapper functions. Plus, we'd loose performance even in the common case were no exception is generated. So instead, I modified the GAP kernel to track how many nested `GAP_TRY` there are, and pass this value to the callback already present in `GAP_THROW`. We now install such a callback in `GAP.jl` in addition to the `JUMP_TO_CATCH` callback: the latter now only records the error message in a global variable, and then returns (i.e., it doesn't throw an exception anymore). The `ThrowObserver` callback then throws the actual exception using this error messages. This is done in PR <gap-system/gap#4617>. All this together almost fixes "everything", except some GAP kernel code failed to use `GAP_TRY` / `GAP_CATCH` and thus sometimes failed to clean up its input/output stream overrides, even with our tricks. This is fixed in PR <gap-system/gap#4616>. Of course to test all this, I also had to write scripts which makes it "easy enough" to test a custom GAP build inside of GAP.jl; the result is in PR <oscar-system#667>. The final patch here is very small in the end; the difficult part was getting there. Oh, and lots of time waiting for configure scripts, C compilers, Julia precompatilation and more, cf. <https://xkcd.com/303/>.
Previously, we threw a Julia exception in the `error_handler` function, which is called by GAP's `JUMP_TO_CATCH`, which in turn is invoked by GAP's `ErrorInner`. The problem with that is that by throwing a Julia exception, we aborted the GAP exception handling prematurely. As a result, any surrounding `GAP_CATCH` blocks had no chance to run. This had primarily two noticeable effects: 1. Input/output redirection set up by surrounding GAP code via `OpenInput`, `OpenInputStream`, `OpenOutput`, `OpenOutputStream` was not reverted. 2. The pointer GAP uses to keep track of which code is currently being executed ("LVars") was not reset. Effect 2 could be counteracted by calling `SWITCH_TO_BOTTOM_LVARS`. Effect 1 in past GAP versions mostly lead to some output which was not showing up, see <oscar-system#516>. With the current GAP kernel code, though, the "stack of outputs" was changed into a "linked list of outputs", with most outputs residing on the execution stack. As a result, failing to close outputs now can lead to crashes or general weirdness. To fix this, we need to let GAP follow its sequence of exception handlers, and only throw a Julia exception at the very end. The standard way to do this is to surround any calls into the GAP kernel by `GAP_TRY` and `GAP_CATCH`. But the way these C macros work would mean that we couldn't simply use `ccall` anymore. We'd have to add tons of wrapper functions. Plus, we'd loose performance even in the common case were no exception is generated. So instead, I modified the GAP kernel to track how many nested `GAP_TRY` there are, and pass this value to the callback already present in `GAP_THROW`. We now install such a callback in `GAP.jl` in addition to the `JUMP_TO_CATCH` callback: the latter now only records the error message in a global variable, and then returns (i.e., it doesn't throw an exception anymore). The `ThrowObserver` callback then throws the actual exception using this error messages. This is done in PR <gap-system/gap#4617>. All this together almost fixes "everything", except some GAP kernel code failed to use `GAP_TRY` / `GAP_CATCH` and thus sometimes failed to clean up its input/output stream overrides, even with our tricks. This is fixed in PR <gap-system/gap#4616>. Of course to test all this, I also had to write scripts which makes it "easy enough" to test a custom GAP build inside of GAP.jl; the result is in PR <oscar-system#667>. The final patch here is very small in the end; the difficult part was getting there. Oh, and lots of time waiting for configure scripts, C compilers, Julia precompatilation and more, cf. <https://xkcd.com/303/>.
Previously, we threw a Julia exception in the `error_handler` function, which is called by GAP's `JUMP_TO_CATCH`, which in turn is invoked by GAP's `ErrorInner`. The problem with that is that by throwing a Julia exception, we aborted the GAP exception handling prematurely. As a result, any surrounding `GAP_CATCH` blocks had no chance to run. This had primarily two noticeable effects: 1. Input/output redirection set up by surrounding GAP code via `OpenInput`, `OpenInputStream`, `OpenOutput`, `OpenOutputStream` was not reverted. 2. The pointer GAP uses to keep track of which code is currently being executed ("LVars") was not reset. Effect 2 could be counteracted by calling `SWITCH_TO_BOTTOM_LVARS`. Effect 1 in past GAP versions mostly lead to some output which was not showing up, see <oscar-system#516>. With the current GAP kernel code, though, the "stack of outputs" was changed into a "linked list of outputs", with most outputs residing on the execution stack. As a result, failing to close outputs now can lead to crashes or general weirdness. To fix this, we need to let GAP follow its sequence of exception handlers, and only throw a Julia exception at the very end. The standard way to do this is to surround any calls into the GAP kernel by `GAP_TRY` and `GAP_CATCH`. But the way these C macros work would mean that we couldn't simply use `ccall` anymore. We'd have to add tons of wrapper functions. Plus, we'd loose performance even in the common case were no exception is generated. So instead, I modified the GAP kernel to track how many nested `GAP_TRY` there are, and pass this value to the callback already present in `GAP_THROW`. We now install such a callback in `GAP.jl` in addition to the `JUMP_TO_CATCH` callback: the latter now only records the error message in a global variable, and then returns (i.e., it doesn't throw an exception anymore). The `ThrowObserver` callback then throws the actual exception using this error messages. This is done in PR <gap-system/gap#4617>. All this together almost fixes "everything", except some GAP kernel code failed to use `GAP_TRY` / `GAP_CATCH` and thus sometimes failed to clean up its input/output stream overrides, even with our tricks. This is fixed in PR <gap-system/gap#4616>. Of course to test all this, I also had to write scripts which makes it "easy enough" to test a custom GAP build inside of GAP.jl; the result is in PR <oscar-system#667>. The final patch here is very small in the end; the difficult part was getting there. Oh, and lots of time waiting for configure scripts, C compilers, Julia precompatilation and more, cf. <https://xkcd.com/303/>.
Previously, we threw a Julia exception in the `error_handler` function, which is called by GAP's `JUMP_TO_CATCH`, which in turn is invoked by GAP's `ErrorInner`. The problem with that is that by throwing a Julia exception, we aborted the GAP exception handling prematurely. As a result, any surrounding `GAP_CATCH` blocks had no chance to run. This had primarily two noticeable effects: 1. Input/output redirection set up by surrounding GAP code via `OpenInput`, `OpenInputStream`, `OpenOutput`, `OpenOutputStream` was not reverted. 2. The pointer GAP uses to keep track of which code is currently being executed ("LVars") was not reset. Effect 2 could be counteracted by calling `SWITCH_TO_BOTTOM_LVARS`. Effect 1 in past GAP versions mostly lead to some output which was not showing up, see <oscar-system#516>. With the current GAP kernel code, though, the "stack of outputs" was changed into a "linked list of outputs", with most outputs residing on the execution stack. As a result, failing to close outputs now can lead to crashes or general weirdness. To fix this, we need to let GAP follow its sequence of exception handlers, and only throw a Julia exception at the very end. The standard way to do this is to surround any calls into the GAP kernel by `GAP_TRY` and `GAP_CATCH`. But the way these C macros work would mean that we couldn't simply use `ccall` anymore. We'd have to add tons of wrapper functions. Plus, we'd loose performance even in the common case were no exception is generated. So instead, I modified the GAP kernel to track how many nested `GAP_TRY` there are, and pass this value to the callback already present in `GAP_THROW`. We now install such a callback in `GAP.jl` in addition to the `JUMP_TO_CATCH` callback: the latter now only records the error message in a global variable, and then returns (i.e., it doesn't throw an exception anymore). The `ThrowObserver` callback then throws the actual exception using this error messages. This is done in PR <gap-system/gap#4617>. All this together almost fixes "everything", except some GAP kernel code failed to use `GAP_TRY` / `GAP_CATCH` and thus sometimes failed to clean up its input/output stream overrides, even with our tricks. This is fixed in PR <gap-system/gap#4616>. Of course to test all this, I also had to write scripts which makes it "easy enough" to test a custom GAP build inside of GAP.jl; the result is in PR <oscar-system#667>. The final patch here is very small in the end; the difficult part was getting there. Oh, and lots of time waiting for configure scripts, C compilers, Julia precompatilation and more, cf. <https://xkcd.com/303/>.
Previously, we threw a Julia exception in the `error_handler` function, which is called by GAP's `JUMP_TO_CATCH`, which in turn is invoked by GAP's `ErrorInner`. The problem with that is that by throwing a Julia exception, we aborted the GAP exception handling prematurely. As a result, any surrounding `GAP_CATCH` blocks had no chance to run. This had primarily two noticeable effects: 1. Input/output redirection set up by surrounding GAP code via `OpenInput`, `OpenInputStream`, `OpenOutput`, `OpenOutputStream` was not reverted. 2. The pointer GAP uses to keep track of which code is currently being executed ("LVars") was not reset. Effect 2 could be counteracted by calling `SWITCH_TO_BOTTOM_LVARS`. Effect 1 in past GAP versions mostly lead to some output which was not showing up, see <#516>. With the current GAP kernel code, though, the "stack of outputs" was changed into a "linked list of outputs", with most outputs residing on the execution stack. As a result, failing to close outputs now can lead to crashes or general weirdness. To fix this, we need to let GAP follow its sequence of exception handlers, and only throw a Julia exception at the very end. The standard way to do this is to surround any calls into the GAP kernel by `GAP_TRY` and `GAP_CATCH`. But the way these C macros work would mean that we couldn't simply use `ccall` anymore. We'd have to add tons of wrapper functions. Plus, we'd loose performance even in the common case were no exception is generated. So instead, I modified the GAP kernel to track how many nested `GAP_TRY` there are, and pass this value to the callback already present in `GAP_THROW`. We now install such a callback in `GAP.jl` in addition to the `JUMP_TO_CATCH` callback: the latter now only records the error message in a global variable, and then returns (i.e., it doesn't throw an exception anymore). The `ThrowObserver` callback then throws the actual exception using this error messages. This is done in PR <gap-system/gap#4617>. All this together almost fixes "everything", except some GAP kernel code failed to use `GAP_TRY` / `GAP_CATCH` and thus sometimes failed to clean up its input/output stream overrides, even with our tricks. This is fixed in PR <gap-system/gap#4616>. Of course to test all this, I also had to write scripts which makes it "easy enough" to test a custom GAP build inside of GAP.jl; the result is in PR <#667>. The final patch here is very small in the end; the difficult part was getting there. Oh, and lots of time waiting for configure scripts, C compilers, Julia precompatilation and more, cf. <https://xkcd.com/303/>.
Consider the following code and output:
The string
test3
is not printed. In fact, nothing seems to be printed usingGAP.Globals.Display
after an error has occured.GAP.Display
seems to work fine.A related question we are interested in: Which stream is
Display
outputting to? We would like to turn the print formatting off for this stream as we did in #513.The text was updated successfully, but these errors were encountered: