@@ -126,7 +126,7 @@ static MonoFtnPtrEHCallback ftnptr_eh_callback;
126
126
*/
127
127
int mono_llvmonly_do_unwind_flag ;
128
128
129
- static void mono_walk_stack_full (MonoJitStackWalk func , MonoContext * start_ctx , MonoJitTlsData * jit_tls , MonoLMF * lmf , MonoUnwindOptions unwind_options , gpointer user_data , gboolean crash_context );
129
+ static void mono_walk_stack_full (MonoJitStackWalk func , MonoContext * start_ctx , MonoJitTlsData * jit_tls , MonoLMF * lmf , MonoUnwindOptions unwind_options , gpointer user_data );
130
130
static void mono_raise_exception_with_ctx (MonoException * exc , MonoContext * ctx );
131
131
static void mono_runtime_walk_stack_with_ctx (MonoJitStackWalk func , MonoContext * start_ctx , MonoUnwindOptions unwind_options , void * user_data );
132
132
static gboolean mono_current_thread_has_handle_block_guard (void );
@@ -160,7 +160,7 @@ static gpointer
160
160
mono_thread_get_managed_sp (void )
161
161
{
162
162
gpointer addr = NULL ;
163
- mono_walk_stack (first_managed , MONO_UNWIND_SIGNAL_SAFE , & addr );
163
+ mono_walk_stack (first_managed , MONO_UNWIND_NONE , & addr );
164
164
return addr ;
165
165
}
166
166
@@ -1224,7 +1224,7 @@ mono_walk_stack_with_ctx (MonoJitStackWalk func, MonoContext *start_ctx, MonoUnw
1224
1224
start_ctx = & extra_ctx ;
1225
1225
}
1226
1226
1227
- mono_walk_stack_full (func , start_ctx , thread -> jit_data , mono_get_lmf (), unwind_options , user_data , FALSE );
1227
+ mono_walk_stack_full (func , start_ctx , thread -> jit_data , mono_get_lmf (), unwind_options , user_data );
1228
1228
}
1229
1229
1230
1230
/**
@@ -1241,8 +1241,9 @@ void
1241
1241
mono_walk_stack_with_state (MonoJitStackWalk func , MonoThreadUnwindState * state , MonoUnwindOptions unwind_options , void * user_data )
1242
1242
{
1243
1243
MonoThreadUnwindState extra_state ;
1244
+
1244
1245
if (!state ) {
1245
- g_assert (!mono_thread_info_is_async_context ());
1246
+ g_assert (!( unwind_options & MONO_UNWIND_SIGNAL_SAFE ) && ! mono_thread_info_is_async_context ());
1246
1247
if (!mono_thread_state_init_from_current (& extra_state ))
1247
1248
return ;
1248
1249
state = & extra_state ;
@@ -1258,7 +1259,7 @@ mono_walk_stack_with_state (MonoJitStackWalk func, MonoThreadUnwindState *state,
1258
1259
& state -> ctx ,
1259
1260
(MonoJitTlsData * )state -> unwind_data [MONO_UNWIND_DATA_JIT_TLS ],
1260
1261
(MonoLMF * )state -> unwind_data [MONO_UNWIND_DATA_LMF ],
1261
- unwind_options , user_data , FALSE );
1262
+ unwind_options , user_data );
1262
1263
}
1263
1264
1264
1265
void
@@ -1270,22 +1271,49 @@ mono_walk_stack (MonoJitStackWalk func, MonoUnwindOptions options, void *user_da
1270
1271
mono_walk_stack_with_state (func , & state , options , user_data );
1271
1272
}
1272
1273
1273
- /**
1274
- * mono_walk_stack_full:
1275
- * \param func callback to call for each stack frame
1276
- * \param unwind_options what extra information the unwinder should gather
1277
- * \param start_ctx starting state of the stack walk, can be NULL.
1278
- * \param thread the thread whose stack to walk, can be NULL to use the current thread
1279
- * \param lmf the LMF of \p thread, can be NULL to use the LMF of the current thread
1280
- * \param user_data data passed to the callback
1281
- * \param crash_context tells us that we're in a context where it's not safe to lock or allocate
1282
- * This function walks the stack of a thread, starting from the state
1283
- * represented by \p start_ctx. For each frame the callback
1284
- * function is called with the relevant info. The walk ends when no more
1285
- * managed stack frames are found or when the callback returns a TRUE value.
1286
- */
1274
+ #ifndef TARGET_WASM
1287
1275
static void
1288
- mono_walk_stack_full (MonoJitStackWalk func , MonoContext * start_ctx , MonoJitTlsData * jit_tls , MonoLMF * lmf , MonoUnwindOptions unwind_options , gpointer user_data , gboolean crash_context )
1276
+ walk_stack_full_llvm_only (MonoJitStackWalk func , MonoContext * start_ctx , MonoJitTlsData * jit_tls , MonoLMF * lmf , MonoUnwindOptions unwind_options , gpointer user_data )
1277
+ {
1278
+ GSList * l , * ips ;
1279
+ StackFrameInfo frame ;
1280
+
1281
+ g_assert (mono_llvm_only );
1282
+
1283
+ memset (& frame , 0 , sizeof (StackFrameInfo ));
1284
+
1285
+ // TODO: Fix async support.
1286
+ if (mono_thread_info_is_async_context ())
1287
+ return ;
1288
+
1289
+ ips = get_unwind_backtrace ();
1290
+ for (l = ips ; l ; l = l -> next ) {
1291
+ guint8 * ip = (guint8 * )l -> data ;
1292
+ memset (& frame , 0 , sizeof (StackFrameInfo ));
1293
+ frame .ji = mini_jit_info_table_find (ip );
1294
+ if (!frame .ji || frame .ji -> is_trampoline )
1295
+ continue ;
1296
+ frame .type = FRAME_TYPE_MANAGED ;
1297
+ frame .method = jinfo_get_method (frame .ji );
1298
+ // FIXME: Cannot lookup the actual method
1299
+ frame .actual_method = frame .method ;
1300
+ if (frame .type == FRAME_TYPE_MANAGED ) {
1301
+ if (!frame .method -> wrapper_type || frame .method -> wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD )
1302
+ frame .managed = TRUE;
1303
+ }
1304
+ frame .native_offset = GPTRDIFF_TO_INT (ip - (guint8 * )frame .ji -> code_start );
1305
+ frame .il_offset = -1 ;
1306
+
1307
+ if (func (& frame , NULL , user_data ))
1308
+ break ;
1309
+ }
1310
+ g_slist_free (ips );
1311
+ return ;
1312
+ }
1313
+ #endif
1314
+
1315
+ static void
1316
+ walk_stack_full (MonoJitStackWalk func , MonoContext * start_ctx , MonoJitTlsData * jit_tls , MonoLMF * lmf , MonoUnwindOptions unwind_options , gpointer user_data )
1289
1317
{
1290
1318
gint il_offset ;
1291
1319
MonoContext ctx , new_ctx ;
@@ -1299,39 +1327,6 @@ mono_walk_stack_full (MonoJitStackWalk func, MonoContext *start_ctx, MonoJitTlsD
1299
1327
1300
1328
memset (& frame , 0 , sizeof (StackFrameInfo ));
1301
1329
1302
- #ifndef TARGET_WASM
1303
- if (mono_llvm_only ) {
1304
- GSList * l , * ips ;
1305
-
1306
- if (async )
1307
- return ;
1308
-
1309
- ips = get_unwind_backtrace ();
1310
- for (l = ips ; l ; l = l -> next ) {
1311
- guint8 * ip = (guint8 * )l -> data ;
1312
- memset (& frame , 0 , sizeof (StackFrameInfo ));
1313
- frame .ji = mini_jit_info_table_find (ip );
1314
- if (!frame .ji || frame .ji -> is_trampoline )
1315
- continue ;
1316
- frame .type = FRAME_TYPE_MANAGED ;
1317
- frame .method = jinfo_get_method (frame .ji );
1318
- // FIXME: Cannot lookup the actual method
1319
- frame .actual_method = frame .method ;
1320
- if (frame .type == FRAME_TYPE_MANAGED ) {
1321
- if (!frame .method -> wrapper_type || frame .method -> wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD )
1322
- frame .managed = TRUE;
1323
- }
1324
- frame .native_offset = GPTRDIFF_TO_INT (ip - (guint8 * )frame .ji -> code_start );
1325
- frame .il_offset = -1 ;
1326
-
1327
- if (func (& frame , NULL , user_data ))
1328
- break ;
1329
- }
1330
- g_slist_free (ips );
1331
- return ;
1332
- }
1333
- #endif
1334
-
1335
1330
if (!start_ctx ) {
1336
1331
g_warning ("start_ctx required for stack walk" );
1337
1332
return ;
@@ -1372,15 +1367,15 @@ mono_walk_stack_full (MonoJitStackWalk func, MonoContext *start_ctx, MonoJitTlsD
1372
1367
MonoDebugSourceLocation * source = NULL ;
1373
1368
1374
1369
// Don't do this when we can be in a signal handler
1375
- if (!crash_context )
1370
+ if (!async )
1376
1371
source = mono_debug_lookup_source_location (jinfo_get_method (frame .ji ), frame .native_offset , NULL );
1377
1372
if (source ) {
1378
1373
il_offset = source -> il_offset ;
1379
1374
} else {
1380
1375
MonoSeqPointInfo * seq_points = NULL ;
1381
1376
1382
1377
// It's more reliable to look into the global cache if possible
1383
- if (crash_context )
1378
+ if (async )
1384
1379
seq_points = (MonoSeqPointInfo * ) frame .ji -> seq_points ;
1385
1380
else
1386
1381
seq_points = mono_get_seq_points (jinfo_get_method (frame .ji ));
@@ -1422,6 +1417,41 @@ mono_walk_stack_full (MonoJitStackWalk func, MonoContext *start_ctx, MonoJitTlsD
1422
1417
}
1423
1418
}
1424
1419
1420
+ /**
1421
+ * mono_walk_stack_full:
1422
+ * \param func callback to call for each stack frame
1423
+ * \param unwind_options what extra information the unwinder should gather
1424
+ * \param start_ctx starting state of the stack walk, can be NULL.
1425
+ * \param thread the thread whose stack to walk, can be NULL to use the current thread
1426
+ * \param lmf the LMF of \p thread, can be NULL to use the LMF of the current thread
1427
+ * \param user_data data passed to the callback
1428
+ * This function walks the stack of a thread, starting from the state
1429
+ * represented by \p start_ctx. For each frame the callback
1430
+ * function is called with the relevant info. The walk ends when no more
1431
+ * managed stack frames are found or when the callback returns a TRUE value.
1432
+ */
1433
+ static void
1434
+ mono_walk_stack_full (MonoJitStackWalk func , MonoContext * start_ctx , MonoJitTlsData * jit_tls , MonoLMF * lmf , MonoUnwindOptions unwind_options , gpointer user_data )
1435
+ {
1436
+ gboolean restore_async_context = FALSE;
1437
+ if ((unwind_options & MONO_UNWIND_SIGNAL_SAFE ) && !mono_thread_info_is_async_context ()) {
1438
+ mono_thread_info_set_is_async_context (TRUE);
1439
+ restore_async_context = TRUE;
1440
+ }
1441
+
1442
+ #ifndef TARGET_WASM
1443
+ if (mono_llvm_only )
1444
+ walk_stack_full_llvm_only (func , start_ctx , jit_tls , lmf , unwind_options , user_data );
1445
+ else
1446
+ walk_stack_full (func , start_ctx , jit_tls , lmf , unwind_options , user_data );
1447
+ #else
1448
+ walk_stack_full (func , start_ctx , jit_tls , lmf , unwind_options , user_data );
1449
+ #endif
1450
+
1451
+ if (restore_async_context )
1452
+ mono_thread_info_set_is_async_context (FALSE);
1453
+ }
1454
+
1425
1455
MonoBoolean
1426
1456
mono_get_frame_info (gint32 skip ,
1427
1457
MonoMethod * * out_method ,
@@ -2976,7 +3006,8 @@ mono_handle_native_crash (const char *signal, MonoContext *mctx, MONO_SIG_HANDLE
2976
3006
g_async_safe_printf ("\tManaged Stacktrace:\n" );
2977
3007
g_async_safe_printf ("=================================================================\n" );
2978
3008
2979
- mono_walk_stack_full (print_stack_frame_signal_safe , mctx , jit_tls , mono_get_lmf (), MONO_UNWIND_LOOKUP_IL_OFFSET , NULL , TRUE);
3009
+ mono_walk_stack_full (print_stack_frame_signal_safe , mctx , jit_tls , mono_get_lmf (), MONO_UNWIND_LOOKUP_IL_OFFSET | MONO_UNWIND_SIGNAL_SAFE , NULL );
3010
+
2980
3011
g_async_safe_printf ("=================================================================\n" );
2981
3012
}
2982
3013
@@ -3146,15 +3177,13 @@ mono_install_handler_block_guard (MonoThreadUnwindState *ctx)
3146
3177
MonoJitTlsData * jit_tls = (MonoJitTlsData * )ctx -> unwind_data [MONO_UNWIND_DATA_JIT_TLS ];
3147
3178
3148
3179
/* Guard against a null MonoJitTlsData. This can happens if the thread receives the
3149
- * interrupt signal before the JIT has time to initialize its TLS data for the given thread.
3180
+ * interrupt signal before the JIT has time to initialize its TLS data for the given thread.
3150
3181
*/
3151
3182
if (!jit_tls || jit_tls -> handler_block )
3152
3183
return FALSE;
3153
3184
3154
3185
/* Do an async safe stack walk */
3155
- mono_thread_info_set_is_async_context (TRUE);
3156
- mono_walk_stack_with_state (find_last_handler_block , ctx , MONO_UNWIND_NONE , & data );
3157
- mono_thread_info_set_is_async_context (FALSE);
3186
+ mono_walk_stack_with_state (find_last_handler_block , ctx , MONO_UNWIND_SIGNAL_SAFE , & data );
3158
3187
3159
3188
if (!data .ji )
3160
3189
return FALSE;
0 commit comments