Skip to content

Commit

Permalink
Added optional Susan debugging help
Browse files Browse the repository at this point in the history
There is a new flag -d=susanDebug which can generate a different
MetaModelica from the Susan code. It will give a stack-trace of the
point where a failure happens.

Use the debug-flag when compiling the Susan code to add extra try/catch
blocks everywhere (this slows down the code considerably and is not
intended for use in the production executable; only for debugging).

Belonging to [master]:
  - OpenModelica/OMCompiler#1955
  • Loading branch information
sjoelund authored and OpenModelica-Hudson committed Oct 30, 2017
1 parent fe021bd commit 80e3d34
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 58 deletions.
100 changes: 50 additions & 50 deletions Compiler/Template/Tpl.mo
Expand Up @@ -8,16 +8,18 @@ encapsulated package Tpl
$Id$
"

protected import Config;
protected import ClockIndexes;
protected import Debug;
protected import Error;
protected import File;
protected import Flags;
protected import List;
protected import Print;
protected import StringUtil;
protected import System;
protected
import Config;
import ClockIndexes;
import Debug;
import Error;
import File;
import Flags;
import List;
import Print;
import StackOverflow;
import StringUtil;
import System;

// indentation will be implemented through spaces
// where tabs will be converted where 1 tab = 4 spaces ??
Expand Down Expand Up @@ -1999,27 +2001,45 @@ algorithm
end match;
end failIfTrue;

public function tplCallWithFailErrorNoArg
protected function tplCallHandleErrors
input Tpl_Fun inFun;
input output Text txt = emptyTxt;
input Integer nArg;

partial function Tpl_Fun
input Text in_txt;
output Text out_txt;
end Tpl_Fun;
algorithm
try
try
txt := inFun(txt);
else
addTemplateErrorFunc(0, inFun);
addTemplateErrorFunc(nArg, inFun);
fail();
end try;
else
addTemplateErrorFunc(nArg, inFun);
fail();
end try annotation(__OpenModelica_stackOverflowCheckpoint=true);
end tplCallHandleErrors;

public function tplCallWithFailErrorNoArg
input Tpl_Fun inFun;
input output Text txt = emptyTxt;

partial function Tpl_Fun
input Text in_txt;
output Text out_txt;
end Tpl_Fun;
algorithm
txt := tplCallHandleErrors(inFun, txt, 0);
end tplCallWithFailErrorNoArg;

public function tplCallWithFailError
input Tpl_Fun inFun;
input ArgType1 inArg;
output Text outTxt;
input output Text txt = emptyTxt;

partial function Tpl_Fun
input Text in_txt;
Expand All @@ -2028,25 +2048,15 @@ public function tplCallWithFailError
end Tpl_Fun;
protected
ArgType1 arg;
Text txt;
algorithm
outTxt := matchcontinue(inFun, inArg)
case(_, arg)
equation
txt = inFun(emptyTxt, arg);
then txt;
else
equation
addTemplateErrorFunc(1, inFun);
then fail();
end matchcontinue;
txt := tplCallHandleErrors(function inFun(inArgA=inArg), txt, 1);
end tplCallWithFailError;

public function tplCallWithFailError2
input Tpl_Fun inFun;
input ArgType1 inArgA;
input ArgType2 inArgB;
output Text outTxt;
input output Text txt = emptyTxt;

partial function Tpl_Fun
input Text in_txt;
Expand All @@ -2057,20 +2067,8 @@ public function tplCallWithFailError2
protected
ArgType1 argA;
ArgType2 argB;
Text txt;
algorithm
outTxt := matchcontinue(inFun, inArgA, inArgB)
local
String file,symbol;
case(_, argA, argB)
equation
txt = inFun(emptyTxt, argA, argB);
then txt;
else
equation
addTemplateErrorFunc(2, inFun);
then fail();
end matchcontinue;
txt := tplCallHandleErrors(function inFun(inArgA=inArgA, inArgB=inArgB), txt, 2);
end tplCallWithFailError2;

function tplCallWithFailError3
Expand All @@ -2088,12 +2086,7 @@ function tplCallWithFailError3
output Text out_txt;
end Tpl_Fun;
algorithm
try
txt := inFun(txt, inArgA, inArgB, inArgC);
else
addTemplateErrorFunc(3, inFun);
fail();
end try;
txt := tplCallHandleErrors(function inFun(inArgA=inArgA, inArgB=inArgB, inArgC=inArgC), txt, 3);
end tplCallWithFailError3;

function tplCallWithFailError4
Expand All @@ -2113,12 +2106,7 @@ function tplCallWithFailError4
output Text out_txt;
end Tpl_Fun;
algorithm
try
txt := func(txt, argA, argB, argC, argD);
else
addTemplateErrorFunc(4, func);
fail();
end try;
txt := tplCallHandleErrors(function func(inArgA=argA, inArgB=argB, inArgC=argC, inArgD=argD), txt, 4);
end tplCallWithFailError4;

public function tplString
Expand Down Expand Up @@ -2592,5 +2580,17 @@ algorithm
end match;
end handleTok;

public function debugSusan
output Boolean b;
algorithm
b := Flags.isSet(Flags.SUSAN_MATCHCONTINUE_DEBUG);
end debugSusan;

public function fakeStackOverflow
algorithm
Error.addInternalError("Stack overflow:\n" + StackOverflow.generateReadableMessage(), sourceInfo());
StackOverflow.triggerStackOverflow();
end fakeStackOverflow;

annotation(__OpenModelica_Interface="susan");
end Tpl;
6 changes: 4 additions & 2 deletions Compiler/Util/Flags.mo
Expand Up @@ -520,7 +520,8 @@ constant DebugFlag IGNORE_CYCLES = DEBUG_FLAG(172, "ignoreCycles", false,
Util.gettext("Ignores cycles between constant/parameter components."));
constant DebugFlag ALIAS_CONFLICTS = DEBUG_FLAG(173, "aliasConflicts", false,
Util.gettext("Dumps alias sets with different start or nominal values."));

constant DebugFlag SUSAN_MATCHCONTINUE_DEBUG = DEBUG_FLAG(174, "susanDebug", false,
Util.gettext("Makes Susan generate code using try/else to better debug which function broke the expected match semantics."));

// This is a list of all debug flags, to keep track of which flags are used. A
// flag can not be used unless it's in this list, and the list is checked at
Expand Down Expand Up @@ -700,7 +701,8 @@ constant list<DebugFlag> allDebugFlags = {
MERGE_ALGORITHM_SECTIONS,
WARN_NO_NOMINAL,
IGNORE_CYCLES,
ALIAS_CONFLICTS
ALIAS_CONFLICTS,
SUSAN_MATCHCONTINUE_DEBUG
};

public
Expand Down
8 changes: 8 additions & 0 deletions Compiler/Util/StackOverflow.mo
Expand Up @@ -78,6 +78,14 @@ end stripAddresses;

public

function triggerStackOverflow
external "C" mmc_do_stackoverflow(OpenModelica.threadData()) annotation(Documentation(info="<html>
<p>Fakes a stack overflow (useful for debugging; forces earlier exit
since most functions do not catch stack overflow, and gives you a
stacktrace of the position you triggered this from).</p>
</html>"));
end triggerStackOverflow;

function generateReadableMessage
input Integer numFrames=1000;
input Integer numSkip=4;
Expand Down
30 changes: 27 additions & 3 deletions Compiler/susan_codegen/TplCodegen.tpl
Expand Up @@ -57,8 +57,20 @@ template mmDeclaration(MMDeclaration it) ::=
protected
<%typedIdents(mf.locals)%>
>>%>
algorithm
algorithm<%if debugSusan() then
<<

try
>>
%>
<%sts |> it => '<%mmExp(it, ":=")%>;' ;separator="\n"%>
<%if debugSusan() then
<<
else
Tpl.fakeStackOverflow();
end try;
>>
%>
>>
%>
end <%name%>;
Expand All @@ -70,7 +82,12 @@ template mmMatchFunBody(TypedIdents inArgs, TypedIdents outArgs, TypedIdents loc
<%typedIdentsEx(inArgs, "input", "in_")%>

<%typedIdentsEx(outArgs, "output", "out_")%>
algorithm
algorithm<% if debugSusan() then
<<

try
>>
%>
<%match outArgs
case {(nm,_)} then 'out_<%nm%>'
case outArgs then <<(<%outArgs |> (nm,_)=> 'out_<%nm%>' ;separator=", "%>)>>
Expand All @@ -91,7 +108,14 @@ algorithm
case oas then '(<%oas |> (nm,_)=> nm ;separator=", "%>)'
%>;
>>;separator="\n"%>
end match;
end match;<% if debugSusan() then
<<

else
Tpl.fakeStackOverflow();
end try;
>>
%>
>>
end mmMatchFunBody;

Expand Down
4 changes: 4 additions & 0 deletions Compiler/susan_codegen/TplCodegenTV.mo
Expand Up @@ -24,6 +24,10 @@ package Tpl
Boolean lastHasNewLine "True when the last string in the list has new-line at the end.";
end ST_STRING_LIST;
end StringToken;

function debugSusan
output Boolean b;
end debugSusan;
end Tpl;

package TplAbsyn
Expand Down
7 changes: 7 additions & 0 deletions SimulationRuntime/c/meta/meta_modelica_segv.c
Expand Up @@ -232,3 +232,10 @@ void mmc_init_stackoverflow(threadData_t *threadData)
threadData->stackBottom = 0x1; /* Dummy until Windows detects the stack bottom */
}
#endif

void mmc_do_stackoverflow(threadData_t *threadData)
{
/* Do the jump */
mmc_setStacktraceMessages_threadData(threadData, 1, MMC_SEGV_TRACE_NFRAMES);
longjmp(*threadData->mmc_stack_overflow_jumper, 1);
}
6 changes: 3 additions & 3 deletions SimulationRuntime/c/meta/meta_modelica_segv.h
Expand Up @@ -64,6 +64,8 @@ void mmc_init_stackoverflow(threadData_t *threadData);
/* Does not work very well with many stack frames because we are close to the stack end when we need this data... */
#define MMC_SEGV_TRACE_NFRAMES 1024

void mmc_do_stackoverflow(threadData_t *threadData);

static inline void mmc_check_stackoverflow(threadData_t *threadData)
{
#if __has_builtin(__builtin_frame_address) || defined(__GNUC__)
Expand All @@ -74,9 +76,7 @@ static inline void mmc_check_stackoverflow(threadData_t *threadData)
if ((void*) &addr < threadData->stackBottom)
#endif
{
/* Do the jump */
mmc_setStacktraceMessages_threadData(threadData, 1, MMC_SEGV_TRACE_NFRAMES);
longjmp(*threadData->mmc_stack_overflow_jumper, 1);
mmc_do_stackoverflow(threadData);
}
}

Expand Down

0 comments on commit 80e3d34

Please sign in to comment.