Skip to content

Commit 80e3d34

Browse files
sjoelundOpenModelica-Hudson
authored andcommitted
Added optional Susan debugging help
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
1 parent fe021bd commit 80e3d34

File tree

7 files changed

+103
-58
lines changed

7 files changed

+103
-58
lines changed

Compiler/Template/Tpl.mo

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,18 @@ encapsulated package Tpl
88
$Id$
99
"
1010

11-
protected import Config;
12-
protected import ClockIndexes;
13-
protected import Debug;
14-
protected import Error;
15-
protected import File;
16-
protected import Flags;
17-
protected import List;
18-
protected import Print;
19-
protected import StringUtil;
20-
protected import System;
11+
protected
12+
import Config;
13+
import ClockIndexes;
14+
import Debug;
15+
import Error;
16+
import File;
17+
import Flags;
18+
import List;
19+
import Print;
20+
import StackOverflow;
21+
import StringUtil;
22+
import System;
2123

2224
// indentation will be implemented through spaces
2325
// where tabs will be converted where 1 tab = 4 spaces ??
@@ -1999,27 +2001,45 @@ algorithm
19992001
end match;
20002002
end failIfTrue;
20012003

2002-
public function tplCallWithFailErrorNoArg
2004+
protected function tplCallHandleErrors
20032005
input Tpl_Fun inFun;
20042006
input output Text txt = emptyTxt;
2007+
input Integer nArg;
20052008

20062009
partial function Tpl_Fun
20072010
input Text in_txt;
20082011
output Text out_txt;
20092012
end Tpl_Fun;
20102013
algorithm
2014+
try
20112015
try
20122016
txt := inFun(txt);
20132017
else
2014-
addTemplateErrorFunc(0, inFun);
2018+
addTemplateErrorFunc(nArg, inFun);
20152019
fail();
20162020
end try;
2021+
else
2022+
addTemplateErrorFunc(nArg, inFun);
2023+
fail();
2024+
end try annotation(__OpenModelica_stackOverflowCheckpoint=true);
2025+
end tplCallHandleErrors;
2026+
2027+
public function tplCallWithFailErrorNoArg
2028+
input Tpl_Fun inFun;
2029+
input output Text txt = emptyTxt;
2030+
2031+
partial function Tpl_Fun
2032+
input Text in_txt;
2033+
output Text out_txt;
2034+
end Tpl_Fun;
2035+
algorithm
2036+
txt := tplCallHandleErrors(inFun, txt, 0);
20172037
end tplCallWithFailErrorNoArg;
20182038

20192039
public function tplCallWithFailError
20202040
input Tpl_Fun inFun;
20212041
input ArgType1 inArg;
2022-
output Text outTxt;
2042+
input output Text txt = emptyTxt;
20232043

20242044
partial function Tpl_Fun
20252045
input Text in_txt;
@@ -2028,25 +2048,15 @@ public function tplCallWithFailError
20282048
end Tpl_Fun;
20292049
protected
20302050
ArgType1 arg;
2031-
Text txt;
20322051
algorithm
2033-
outTxt := matchcontinue(inFun, inArg)
2034-
case(_, arg)
2035-
equation
2036-
txt = inFun(emptyTxt, arg);
2037-
then txt;
2038-
else
2039-
equation
2040-
addTemplateErrorFunc(1, inFun);
2041-
then fail();
2042-
end matchcontinue;
2052+
txt := tplCallHandleErrors(function inFun(inArgA=inArg), txt, 1);
20432053
end tplCallWithFailError;
20442054

20452055
public function tplCallWithFailError2
20462056
input Tpl_Fun inFun;
20472057
input ArgType1 inArgA;
20482058
input ArgType2 inArgB;
2049-
output Text outTxt;
2059+
input output Text txt = emptyTxt;
20502060

20512061
partial function Tpl_Fun
20522062
input Text in_txt;
@@ -2057,20 +2067,8 @@ public function tplCallWithFailError2
20572067
protected
20582068
ArgType1 argA;
20592069
ArgType2 argB;
2060-
Text txt;
20612070
algorithm
2062-
outTxt := matchcontinue(inFun, inArgA, inArgB)
2063-
local
2064-
String file,symbol;
2065-
case(_, argA, argB)
2066-
equation
2067-
txt = inFun(emptyTxt, argA, argB);
2068-
then txt;
2069-
else
2070-
equation
2071-
addTemplateErrorFunc(2, inFun);
2072-
then fail();
2073-
end matchcontinue;
2071+
txt := tplCallHandleErrors(function inFun(inArgA=inArgA, inArgB=inArgB), txt, 2);
20742072
end tplCallWithFailError2;
20752073

20762074
function tplCallWithFailError3
@@ -2088,12 +2086,7 @@ function tplCallWithFailError3
20882086
output Text out_txt;
20892087
end Tpl_Fun;
20902088
algorithm
2091-
try
2092-
txt := inFun(txt, inArgA, inArgB, inArgC);
2093-
else
2094-
addTemplateErrorFunc(3, inFun);
2095-
fail();
2096-
end try;
2089+
txt := tplCallHandleErrors(function inFun(inArgA=inArgA, inArgB=inArgB, inArgC=inArgC), txt, 3);
20972090
end tplCallWithFailError3;
20982091

20992092
function tplCallWithFailError4
@@ -2113,12 +2106,7 @@ function tplCallWithFailError4
21132106
output Text out_txt;
21142107
end Tpl_Fun;
21152108
algorithm
2116-
try
2117-
txt := func(txt, argA, argB, argC, argD);
2118-
else
2119-
addTemplateErrorFunc(4, func);
2120-
fail();
2121-
end try;
2109+
txt := tplCallHandleErrors(function func(inArgA=argA, inArgB=argB, inArgC=argC, inArgD=argD), txt, 4);
21222110
end tplCallWithFailError4;
21232111

21242112
public function tplString
@@ -2592,5 +2580,17 @@ algorithm
25922580
end match;
25932581
end handleTok;
25942582

2583+
public function debugSusan
2584+
output Boolean b;
2585+
algorithm
2586+
b := Flags.isSet(Flags.SUSAN_MATCHCONTINUE_DEBUG);
2587+
end debugSusan;
2588+
2589+
public function fakeStackOverflow
2590+
algorithm
2591+
Error.addInternalError("Stack overflow:\n" + StackOverflow.generateReadableMessage(), sourceInfo());
2592+
StackOverflow.triggerStackOverflow();
2593+
end fakeStackOverflow;
2594+
25952595
annotation(__OpenModelica_Interface="susan");
25962596
end Tpl;

Compiler/Util/Flags.mo

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,8 @@ constant DebugFlag IGNORE_CYCLES = DEBUG_FLAG(172, "ignoreCycles", false,
520520
Util.gettext("Ignores cycles between constant/parameter components."));
521521
constant DebugFlag ALIAS_CONFLICTS = DEBUG_FLAG(173, "aliasConflicts", false,
522522
Util.gettext("Dumps alias sets with different start or nominal values."));
523-
523+
constant DebugFlag SUSAN_MATCHCONTINUE_DEBUG = DEBUG_FLAG(174, "susanDebug", false,
524+
Util.gettext("Makes Susan generate code using try/else to better debug which function broke the expected match semantics."));
524525

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

706708
public

Compiler/Util/StackOverflow.mo

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@ end stripAddresses;
7878

7979
public
8080

81+
function triggerStackOverflow
82+
external "C" mmc_do_stackoverflow(OpenModelica.threadData()) annotation(Documentation(info="<html>
83+
<p>Fakes a stack overflow (useful for debugging; forces earlier exit
84+
since most functions do not catch stack overflow, and gives you a
85+
stacktrace of the position you triggered this from).</p>
86+
</html>"));
87+
end triggerStackOverflow;
88+
8189
function generateReadableMessage
8290
input Integer numFrames=1000;
8391
input Integer numSkip=4;

Compiler/susan_codegen/TplCodegen.tpl

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,20 @@ template mmDeclaration(MMDeclaration it) ::=
5757
protected
5858
<%typedIdents(mf.locals)%>
5959
>>%>
60-
algorithm
60+
algorithm<%if debugSusan() then
61+
<<
62+
63+
try
64+
>>
65+
%>
6166
<%sts |> it => '<%mmExp(it, ":=")%>;' ;separator="\n"%>
67+
<%if debugSusan() then
68+
<<
69+
else
70+
Tpl.fakeStackOverflow();
71+
end try;
72+
>>
73+
%>
6274
>>
6375
%>
6476
end <%name%>;
@@ -70,7 +82,12 @@ template mmMatchFunBody(TypedIdents inArgs, TypedIdents outArgs, TypedIdents loc
7082
<%typedIdentsEx(inArgs, "input", "in_")%>
7183

7284
<%typedIdentsEx(outArgs, "output", "out_")%>
73-
algorithm
85+
algorithm<% if debugSusan() then
86+
<<
87+
88+
try
89+
>>
90+
%>
7491
<%match outArgs
7592
case {(nm,_)} then 'out_<%nm%>'
7693
case outArgs then <<(<%outArgs |> (nm,_)=> 'out_<%nm%>' ;separator=", "%>)>>
@@ -91,7 +108,14 @@ algorithm
91108
case oas then '(<%oas |> (nm,_)=> nm ;separator=", "%>)'
92109
%>;
93110
>>;separator="\n"%>
94-
end match;
111+
end match;<% if debugSusan() then
112+
<<
113+
114+
else
115+
Tpl.fakeStackOverflow();
116+
end try;
117+
>>
118+
%>
95119
>>
96120
end mmMatchFunBody;
97121

Compiler/susan_codegen/TplCodegenTV.mo

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ package Tpl
2424
Boolean lastHasNewLine "True when the last string in the list has new-line at the end.";
2525
end ST_STRING_LIST;
2626
end StringToken;
27+
28+
function debugSusan
29+
output Boolean b;
30+
end debugSusan;
2731
end Tpl;
2832

2933
package TplAbsyn

SimulationRuntime/c/meta/meta_modelica_segv.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,3 +232,10 @@ void mmc_init_stackoverflow(threadData_t *threadData)
232232
threadData->stackBottom = 0x1; /* Dummy until Windows detects the stack bottom */
233233
}
234234
#endif
235+
236+
void mmc_do_stackoverflow(threadData_t *threadData)
237+
{
238+
/* Do the jump */
239+
mmc_setStacktraceMessages_threadData(threadData, 1, MMC_SEGV_TRACE_NFRAMES);
240+
longjmp(*threadData->mmc_stack_overflow_jumper, 1);
241+
}

SimulationRuntime/c/meta/meta_modelica_segv.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ void mmc_init_stackoverflow(threadData_t *threadData);
6464
/* Does not work very well with many stack frames because we are close to the stack end when we need this data... */
6565
#define MMC_SEGV_TRACE_NFRAMES 1024
6666

67+
void mmc_do_stackoverflow(threadData_t *threadData);
68+
6769
static inline void mmc_check_stackoverflow(threadData_t *threadData)
6870
{
6971
#if __has_builtin(__builtin_frame_address) || defined(__GNUC__)
@@ -74,9 +76,7 @@ static inline void mmc_check_stackoverflow(threadData_t *threadData)
7476
if ((void*) &addr < threadData->stackBottom)
7577
#endif
7678
{
77-
/* Do the jump */
78-
mmc_setStacktraceMessages_threadData(threadData, 1, MMC_SEGV_TRACE_NFRAMES);
79-
longjmp(*threadData->mmc_stack_overflow_jumper, 1);
79+
mmc_do_stackoverflow(threadData);
8080
}
8181
}
8282

0 commit comments

Comments
 (0)