@@ -44,16 +44,23 @@ TEST_CASE("can use std::vector", "[cxx]")
44
44
TEST_ASSERT_EQUAL (51 , std::accumulate (std::begin (v), std::end (v), 0 ));
45
45
}
46
46
47
- /* Note: When first exception (in system) is thrown this test produces memory leaks report (~500 bytes):
48
- - 392 bytes (can vary) as libunwind allocates memory to keep stack frames info to handle exceptions.
49
- This info is kept until global destructors are called by __do_global_dtors_aux()
47
+ /* Note: When first exception (in system) is thrown this test produces memory leaks report (~300 bytes):
50
48
- 8 bytes are allocated by __cxa_get_globals() to keep __cxa_eh_globals
51
49
- 16 bytes are allocated by pthread_setspecific() which is called by __cxa_get_globals() to init TLS var for __cxa_eh_globals
52
50
- 88 bytes are allocated by pthread_setspecific() to init internal lock
51
+ - some more memory...
53
52
*/
54
53
#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
55
54
56
- TEST_CASE (" c++ exceptions work" , " [cxx] [exceptions] [leaks=816]" )
55
+ #if CONFIG_IDF_TARGET_ESP32
56
+ #define LEAKS " 300"
57
+ #elif CONFIG_IDF_TARGET_ESP32S2
58
+ #define LEAKS " 800"
59
+ #else
60
+ #error "unknown target in CXX tests, can't set leaks threshold"
61
+ #endif
62
+
63
+ TEST_CASE (" c++ exceptions work" , " [cxx] [exceptions] [leaks=" LEAKS " ]" )
57
64
{
58
65
int thrown_value;
59
66
try {
@@ -65,7 +72,7 @@ TEST_CASE("c++ exceptions work", "[cxx] [exceptions] [leaks=816]")
65
72
printf (" OK?\n " );
66
73
}
67
74
68
- TEST_CASE (" c++ bool exception" , " [cxx] [exceptions] [leaks=816 ]" )
75
+ TEST_CASE (" c++ bool exception" , " [cxx] [exceptions] [leaks=" LEAKS " ]" )
69
76
{
70
77
bool thrown_value = false ;
71
78
try {
@@ -77,7 +84,7 @@ TEST_CASE("c++ bool exception", "[cxx] [exceptions] [leaks=816]")
77
84
printf (" OK?\n " );
78
85
}
79
86
80
- TEST_CASE (" c++ void exception" , " [cxx] [exceptions] [leaks=816 ]" )
87
+ TEST_CASE (" c++ void exception" , " [cxx] [exceptions] [leaks=" LEAKS " ]" )
81
88
{
82
89
void * thrown_value = 0 ;
83
90
try {
@@ -89,7 +96,7 @@ TEST_CASE("c++ void exception", "[cxx] [exceptions] [leaks=816]")
89
96
printf (" OK?\n " );
90
97
}
91
98
92
- TEST_CASE (" c++ uint64_t exception" , " [cxx] [exceptions] [leaks=816 ]" )
99
+ TEST_CASE (" c++ uint64_t exception" , " [cxx] [exceptions] [leaks=" LEAKS " ]" )
93
100
{
94
101
uint64_t thrown_value = 0 ;
95
102
try {
@@ -101,7 +108,7 @@ TEST_CASE("c++ uint64_t exception", "[cxx] [exceptions] [leaks=816]")
101
108
printf (" OK?\n " );
102
109
}
103
110
104
- TEST_CASE (" c++ char exception" , " [cxx] [exceptions] [leaks=816 ]" )
111
+ TEST_CASE (" c++ char exception" , " [cxx] [exceptions] [leaks=" LEAKS " ]" )
105
112
{
106
113
char thrown_value = ' 0' ;
107
114
try {
@@ -113,7 +120,7 @@ TEST_CASE("c++ char exception", "[cxx] [exceptions] [leaks=816]")
113
120
printf (" OK?\n " );
114
121
}
115
122
116
- TEST_CASE (" c++ wchar exception" , " [cxx] [exceptions] [leaks=816 ]" )
123
+ TEST_CASE (" c++ wchar exception" , " [cxx] [exceptions] [leaks=" LEAKS " ]" )
117
124
{
118
125
wchar_t thrown_value = 0 ;
119
126
try {
@@ -125,7 +132,7 @@ TEST_CASE("c++ wchar exception", "[cxx] [exceptions] [leaks=816]")
125
132
printf (" OK?\n " );
126
133
}
127
134
128
- TEST_CASE (" c++ float exception" , " [cxx] [exceptions] [leaks=816 ]" )
135
+ TEST_CASE (" c++ float exception" , " [cxx] [exceptions] [leaks=" LEAKS " ]" )
129
136
{
130
137
float thrown_value = 0 ;
131
138
try {
@@ -137,7 +144,7 @@ TEST_CASE("c++ float exception", "[cxx] [exceptions] [leaks=816]")
137
144
printf (" OK?\n " );
138
145
}
139
146
140
- TEST_CASE (" c++ double exception" , " [cxx] [exceptions] [leaks=816 ]" )
147
+ TEST_CASE (" c++ double exception" , " [cxx] [exceptions] [leaks=" LEAKS " ]" )
141
148
{
142
149
double thrown_value = 0 ;
143
150
try {
@@ -149,7 +156,7 @@ TEST_CASE("c++ double exception", "[cxx] [exceptions] [leaks=816]")
149
156
printf (" OK?\n " );
150
157
}
151
158
152
- TEST_CASE (" c++ const char* exception" , " [cxx] [exceptions] [leaks=816 ]" )
159
+ TEST_CASE (" c++ const char* exception" , " [cxx] [exceptions] [leaks=" LEAKS " ]" )
153
160
{
154
161
const char *thrown_value = 0 ;
155
162
try {
@@ -167,7 +174,7 @@ struct NonExcTypeThrowee {
167
174
NonExcTypeThrowee (int value) : value(value) { }
168
175
};
169
176
170
- TEST_CASE (" c++ any class exception" , " [cxx] [exceptions] [leaks=816 ]" )
177
+ TEST_CASE (" c++ any class exception" , " [cxx] [exceptions] [leaks=" LEAKS " ]" )
171
178
{
172
179
int thrown_value = 0 ;
173
180
try {
@@ -185,7 +192,7 @@ struct ExcTypeThrowee : public std::exception {
185
192
ExcTypeThrowee (int value) : value(value) { }
186
193
};
187
194
188
- TEST_CASE (" c++ std::exception child" , " [cxx] [exceptions] [leaks=816 ]" )
195
+ TEST_CASE (" c++ std::exception child" , " [cxx] [exceptions] [leaks=" LEAKS " ]" )
189
196
{
190
197
int thrown_value = 0 ;
191
198
try {
@@ -197,7 +204,7 @@ TEST_CASE("c++ std::exception child", "[cxx] [exceptions] [leaks=816]")
197
204
printf (" OK?\n " );
198
205
}
199
206
200
- TEST_CASE (" c++ exceptions emergency pool" , " [cxx] [exceptions] [ignore]" )
207
+ TEST_CASE (" c++ exceptions emergency pool" , " [cxx] [exceptions] [ignore] [leaks= " LEAKS " ] " )
201
208
{
202
209
void **p, **pprev = NULL ;
203
210
int thrown_value = 0 ;
@@ -244,6 +251,60 @@ TEST_CASE("c++ exceptions emergency pool", "[cxx] [exceptions] [ignore]")
244
251
#endif
245
252
}
246
253
254
+
255
+ #define TIMEOUT 19
256
+
257
+ #define RECURSION 19
258
+
259
+ static esp_timer_handle_t crash_timer;
260
+
261
+ static uint32_t result = 0 ;
262
+
263
+ uint32_t calc_fac (uint32_t n) {
264
+ if (n == 1 || n == 0 ) {
265
+ return 1 ;
266
+ } else {
267
+ return n * calc_fac (n - 1 );
268
+ }
269
+ }
270
+
271
+ static void timer_cb (void *arg) {
272
+ result = calc_fac (RECURSION);
273
+ }
274
+
275
+ // TODO: Not a unit test, refactor to integration test/system test, etc.
276
+ TEST_CASE (" frequent interrupts don't interfere with c++ exceptions" , " [cxx] [exceptions] [leaks=" LEAKS " ]" )
277
+ {// if exception workaround is disabled, this is almost guaranteed to fail
278
+ const esp_timer_create_args_t timer_args {
279
+ timer_cb,
280
+ NULL ,
281
+ ESP_TIMER_TASK,
282
+ " crash_timer"
283
+ };
284
+
285
+ TEST_ESP_OK (esp_timer_create (&timer_args, &crash_timer));
286
+ TEST_ESP_OK (esp_timer_start_periodic (crash_timer, TIMEOUT));
287
+
288
+ for (int i = 0 ; i < 500 ; i++) {
289
+ bool thrown_value = false ;
290
+ try {
291
+ throw true ;
292
+ } catch (bool e) {
293
+ thrown_value = e;
294
+ }
295
+
296
+ if (thrown_value) {
297
+ printf (" ex thrown %d\n " , i);
298
+ } else {
299
+ printf (" ex not thrown\n " );
300
+ TEST_ASSERT (false );
301
+ }
302
+ }
303
+
304
+ TEST_ESP_OK (esp_timer_stop (crash_timer));
305
+ TEST_ESP_OK (esp_timer_delete (crash_timer));
306
+ }
307
+
247
308
#else // !CONFIG_COMPILER_CXX_EXCEPTIONS
248
309
249
310
TEST_CASE (" std::out_of_range exception when -fno-exceptions" , " [cxx][reset=abort,SW_CPU_RESET]" )
0 commit comments