Menu

#564 Node sigtraps when heap exhausted

Backlog
open
nobody
None
2Critical
2024-07-08
2024-05-22
No

This is quite a critical error. What we want is to throw an exception when memory is exhausted (std::new would normally do that), which will correctly unwind the stack and report an error message back to the GUI.

Unfortunately, nodejs gets in the way, and raises a SIGTRAP signal. I have added a handler for this, and thrown a suitable exception at that point - unfortunately, it appears that the signal handler is not running in a try black, and the exception is propagated through to terminate().

More research is required as to how to deal with this. StackOverflow is not looking too promising at this stage.

Discussion

  • High Performance Coder

    I've tried multiple solutions to this problem. You cannot increase the heap limitation in electron (4GB), because of shared pointer compression cage. I tried catching the SIGTRAP signal and then a) throwing an exception; b) posting a message to the user, saving the current state of the model and exiting; c) returning to the app to allow the C++ library to throw and exception and b) ignoring SIGTRAP. In all but the first case (where terminate() gets called), the app hangs.

    So my strategy now is to make the checkMemUsage hard code its notion of physical memory to 4GB, and to be conservative in throwing an memory exhausted message. This may need to be revised by using a custom allocator down the line, perhaps by overriding std::new/std::delete. I also found an unnecessary initialisation of the parameter variable in the import routine (ite gets done later anyway).

    I'm considering this done for Pascal, but backlogging this issue for consideration as we go into production.

     
  • High Performance Coder

    • Milestone: Pascal --> Backlog
     
  • High Performance Coder

    I have now succeeded in trapping the signal, posting a message to the user and saving the current state of the model before exiting. This constitutes a partial solution to this problem.

    Note: we cannot override operator new nor malloc. It looks like we can access the glibc version of malloc via __libc_malloc and __libc_free (not tested on Windows), but we can't globally drop in a replacement. We will need to provide this in the form of custom allocators, or custom new commands where appropriate, so this will require a major redesign of civita to allow such drop ins. This will be a substantial piece of work, but can wait until after release.

     
  • High Performance Coder

    Turns out this trapping sigtrap kludge is not necessary on Windows - it throws a bad_alloc anyway.

     

Log in to post a comment.