Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 2.9% 1 / 0 / 34
Functions: 14.3% 1 / 1 / 8
Branches: 0.0% 0 / 0 / 44

OMCompiler/Compiler/Util/StackOverflow.mo
Line Branch Exec Source
1 /*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC),
5 * c/o Linköpings universitet, Department of Computer and Information Science,
6 * SE-58183 Linköping, Sweden.
7 *
8 * All rights reserved.
9 *
10 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR
11 * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8.
12 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
13 * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL
14 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
15 *
16 * The OpenModelica software and the OSMC (Open Source Modelica Consortium)
17 * Public License (OSMC-PL) are obtained from OSMC, either from the above
18 * address, from the URLs:
19 * http://www.openmodelica.org or
20 * https://github.com/OpenModelica/ or
21 * http://www.ida.liu.se/projects/OpenModelica,
22 * and in the OpenModelica distribution.
23 *
24 * GNU AGPL version 3 is obtained from:
25 * https://www.gnu.org/licenses/licenses.html#GPL
26 *
27 * This program is distributed WITHOUT ANY WARRANTY; without
28 * even the implied warranty of MERCHANTABILITY or FITNESS
29 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
30 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
31 *
32 * See the full OSMC Public License conditions for more details.
33 *
34 */
35
36 encapsulated package StackOverflow
37
38 protected
39
40 import StringUtil;
41 import System;
42 import Testsuite;
43
44 function unmangle
45 input String inSymbol;
46 output String outSymbol;
47 algorithm
48 outSymbol := inSymbol;
49 ✗ if StringUtil.startsWith(inSymbol, "omc_") then
50 ✗ outSymbol := substring(outSymbol, 5, stringLength(outSymbol));
51 ✗ outSymbol := System.stringReplace(outSymbol, "__", "#");
52 ✗ outSymbol := System.stringReplace(outSymbol, "_", ".");
53 ✗ outSymbol := System.stringReplace(outSymbol, "#", "_");
54 end if;
55 end unmangle;
56
57 function stripAddresses
58 input String inSymbol;
59 output String outSymbol;
60 protected
61 Integer n;
62 list<String> strs;
63 String so,fun;
64 algorithm
65 // regex for Linux messages
66 ✗ (n,strs) := System.regex(inSymbol, "^([^(]*)[(]([^+]*[^+]*)[+][^)]*[)] *[[]0x[0-9a-fA-F]*[]]$", 3, extended=true);
67 ✗ if n == 3 then
68 ✗ {_,so,fun} := strs;
69 ✗ outSymbol := so + "(" + unmangle(fun) + ")";
70 else
71 // regex for OSX messages
72 ✗ (n,strs) := System.regex(inSymbol, "^[0-9 ]*([A-Za-z0-9.]*) *0x[0-9a-fA-F]* ([A-Za-z0-9_]*) *[+] *[0-9]*$", 3, extended=true);
73 ✗ if n == 3 then
74 ✗ {_,so,fun} := strs;
75 ✗ outSymbol := so + "(" + unmangle(fun) + ")";
76 else
77 outSymbol := inSymbol;
78 end if;
79 end if;
80 end stripAddresses;
81
82 public
83
84 ✗ function triggerStackOverflow
85 external "C" mmc_do_stackoverflow(OpenModelica.threadData()) annotation(Documentation(info="<html>
86 <p>Fakes a stack overflow (useful for debugging; forces earlier exit
87 since most functions do not catch stack overflow, and gives you a
88 stacktrace of the position you triggered this from).</p>
89 </html>"));
90 end triggerStackOverflow;
91
92 function generateReadableMessage
93 input Integer numFrames=1000;
94 input Integer numSkip=4;
95 input String delimiter="\n";
96 output String str;
97 algorithm
98 ✗ StackOverflow.setStacktraceMessages(numSkip, numFrames);
99 ✗ str := getReadableMessage(delimiter=delimiter);
100 end generateReadableMessage;
101
102 function getReadableMessage
103 input String delimiter="\n";
104 output String str;
105 algorithm
106 ✗ str := stringDelimitList(StackOverflow.readableStacktraceMessages(),delimiter);
107 end getReadableMessage;
108
109 function readableStacktraceMessages
110 output list<String> symbols = {};
111 protected
112 String prev = "";
113 Integer n = 1, prevN = 1;
114 algorithm
115 ✗ if Testsuite.isRunning() then
116 symbols := {"[bt] [Symbols are not generated when running the test suite]"};
117 ✗ return;
118 end if;
119 ✗ for symbol in list(stripAddresses(s) for s in getStacktraceMessages()) loop
120 ✗ if prev == "" then
121
122 elseif symbol <> prev then
123 ✗ symbols := ("[bt] #" + String(prevN) + (if n <> prevN then ("..."+String(n)) else "") + " " + prev)::symbols;
124 ✗ n := n + 1;
125 ✗ prevN := n;
126 else
127 ✗ n := n + 1;
128 end if;
129 prev := symbol;
130 end for;
131 ✗ symbols := ("[bt] #" + String(prevN) + (if n <> prevN then ("..."+String(n)) else "") + " " + prev)::symbols;
132 ✗ symbols := listReverse(symbols);
133 end readableStacktraceMessages;
134
135 ✗ function getStacktraceMessages
136 output list<String> symbols;
137 external "C" symbols=mmc_getStacktraceMessages_threadData(OpenModelica.threadData())annotation(Documentation(info="<html>
138 <p>Returns a list of symbol names to print in error messages.</p>
139 </html>"));
140 end getStacktraceMessages;
141
142 ✗ function setStacktraceMessages
143 input Integer numSkip;
144 input Integer numFrames;
145 external "C" mmc_setStacktraceMessages_threadData(OpenModelica.threadData(), numSkip, numFrames)annotation(Documentation(info="<html>
146 <p>Generate a stacktrace at the current position of code.</p>
147 </html>"));
148 end setStacktraceMessages;
149
150 ✗ function hasStacktraceMessages
151 output Boolean b;
152 external "C" b=mmc_hasStacktraceMessages(OpenModelica.threadData())annotation(Documentation(info="<html>
153 <p>Returns true if a stack overflow has occurred.</p>
154 </html>"));
155 end hasStacktraceMessages;
156
157 10558 function clearStacktraceMessages
158 external "C" mmc_clearStacktraceMessages(OpenModelica.threadData())annotation(Documentation(info="<html>
159 <p>Clears the stacktrace from a stack overflow.</p>
160 </html>"));
161 end clearStacktraceMessages;
162
163 function outOfMemoryMessage
164 "What ran out and its limit when the last checkpoint was reached because
165 memory ran out, else empty. Only the Rust runtime tells the two apart."
166 output String msg = "";
167 end outOfMemoryMessage;
168
169 function errorPrefix
170 "\"Stack overflow\", or what ran out of memory."
171 output String str;
172 protected
173 String oom = outOfMemoryMessage();
174 algorithm
175 ✗ str := if stringEmpty(oom) then "Stack overflow" else "Out of memory (" + oom + ")";
176 end errorPrefix;
177
178 annotation(__OpenModelica_Interface="util");
179 end StackOverflow;
180