Opened 12 years ago

Closed 9 years ago

Last modified 9 years ago

#2090 closed defect (fixed)

Stack overflow detection

Reported by: Martin Sjölund Owned by: Martin Sjölund
Priority: high Milestone: 1.9.4
Component: MetaModelica Version: trunk
Keywords: Cc: Adrian Pop, Peter Fritzson, Adeel Asghar, Per Östlund

Description

Because OMEdit requires omc to never crash, we need a way to recover from stack overflow.
As far as I can tell there are ways to get the maximum stack size in boehm's GC (since they inspect the stack). If we get the threshold at program start, we can check this in every called function (with rather low overhead).

We would need one thing in the runtime: Another point to longjmp to when we overflow the stack. Same as far matchcontinue; just another stack to add.

In the MetaModelica language, we would need another builtin function (external C would not be enough since it creates a new stack frame even if a macro is called). You call the new builtin operator something like:

(stackOverflow,message) := checkStackOverflow();
if not stackOverflow then
  // stuff that can cause stack overflow
  popStackOverflowBuffer(); // ugly, but I think needed
else
  // error-handling
  // popStackOverflowBuffer() might not be needed
  // it depends how you implement checkStackOverflow()
  // it might be nicer to have the clean-up always called
end if;

It would look nicer if we added special syntax for it, but I think it's fine to simply add an operator. Or maybe even external "C-macro" ;)

As for getting the backtrace so we can add the messages, there are some ways given here:
http://stackoverflow.com/questions/3151779/how-its-better-to-invoke-gdb-from-program-to-print-its-stacktrace

Change History (9)

comment:1 by Martin Sjölund, 12 years ago

Owner: changed from somebody to Martin Sjölund
Status: newaccepted

comment:2 by Martin Sjölund, 12 years ago

The omc main function now detects overflows. For later we need some additional code to not crash (right now, the main function prints the error and exits).

I did consider some new syntax to be something like:

matchcontinue (a,b,c) /* We could possibly allow match, but it's weird since the stack overflow is a continuation... */
  local
    list<Integer> positions;
    list<String> symbols;
  case (1,2,3) then ...;
  case (_,_,_) then ...;
  case STACKOVERFLOW(messages) /* Requires language extension, but looks nice */
    equation
      symbols = System.backtrace_symbols(positions);
      Error.addMessage(Error.STACK_OVERFLOW, {stringDelimitList(symbols,"\n")});
    then fail();
  case SIGSEGV(messages) /* We could possibly catch more interrupt signals, too */
    equation
      symbols = System.backtrace_symbols(positions);
      Error.addMessage(Error.SIGSEGV, {stringDelimitList(symbols,"\n")});
    then fail();
  else ...; // error-handling as usual
end matchcontinue;

An alternative would be something more explicit:

matchcontinue signal()
  local
    list<Integer> positions;
    list<String> symbols;
  case NOSIGNAL() then ...; /* Regular code */
  case STACKOVERFLOW(messages) /* Requires language extension, but looks nice */
    equation
      symbols = System.backtrace_symbols(positions);
      Error.addMessage(Error.STACK_OVERFLOW, {stringDelimitList(symbols,"\n")});
    then fail();
  case SIGSEGV(messages) /* We could possibly catch more interrupt signals, too. Like SIGUSR1, SIGUSR2 */
    equation
      symbols = System.backtrace_symbols(positions);
      Error.addMessage(Error.SIGSEGV, {stringDelimitList(symbols,"\n")});
      /* Just in case we know that we are calling some external function that might fail */
    then fail();
  else ...; // error-handling as usual
end matchcontinue;

I kinda like the first one. I think it's possible to detect these things and add the required macros in the generated code.

Version 0, edited 12 years ago by Martin Sjölund (next)

comment:3 by Martin Sjölund, 11 years ago

Milestone: 1.9.01.9.1

Postponed until 1.9.1

comment:4 by Martin Sjölund, 10 years ago

Milestone: 1.9.11.9.2

This ticket was not closed for 1.9.1, which has now been released. It was batch modified for milestone 1.9.2 (but maybe an empty milestone was more appropriate; feel free to change it).

comment:5 by Martin Sjölund, 10 years ago

Milestone: 1.9.21.9.3

Milestone changed to 1.9.3 since 1.9.2 was released.

comment:6 by Martin Sjölund, 9 years ago

Milestone: 1.9.31.9.4

Moved to new milestone 1.9.4

comment:7 by Martin Sjölund, 9 years ago

Resolution: fixed
Status: acceptedclosed

This has been fixed by using try-blocks with a special annotation __OpenModelica_stackOverflowCheckpoint=true.

comment:8 by Martin Sjölund, 9 years ago

Milestone: 1.9.41.9.4-1.9.x

Milestone renamed

comment:9 by Martin Sjölund, 9 years ago

Milestone: 1.9.4-1.9.x1.9.4

Milestone renamed

Note: See TracTickets for help on using tickets.