File tree Expand file tree Collapse file tree 1 file changed +23
-5
lines changed Expand file tree Collapse file tree 1 file changed +23
-5
lines changed Original file line number Diff line number Diff line change @@ -227,11 +227,29 @@ def cpp_get_uncaught_exceptions() -> int:
227227 """
228228 Return the current number of uncaught exceptions on the current thread.
229229 """
230- try :
231- return int (gdb .parse_and_eval ("__cxa_get_globals()->uncaught_exceptions" ))
232- except gdb .error :
233- # Fall back to alternate spelling which has also been observed.
234- return int (gdb .parse_and_eval ("__cxa_get_globals()->uncaughtExceptions" ))
230+ # Get a pointer to the base of the C++ runtime's per-thread globals.
231+ cxa_globals = gdb .parse_and_eval ("(char *)__cxa_get_globals()" )
232+
233+ # The globals structure contains a pointer, followed by an unsigned int that stores the current
234+ # count of uncaught exceptions.
235+ #
236+ # See https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html#cxx-data for more details.
237+ #
238+ # Mark saw the naming for the "uncaughtExceptions" field appear to vary but has not been able to
239+ # reproduce this. However, the names are not always available at all if debug symbols are not
240+ # present.
241+ #
242+ # Since this is part of the ABI we can calculate the address to look up the current uncaught
243+ # exception count, rather than rely on symbols.
244+
245+ void_ptr_type = gdb .lookup_type ("void" ).pointer ()
246+ unsigned_int_type = gdb .lookup_type ("unsigned int" )
247+
248+ # The globals structure contains pointer followed by the unsigned int we are looking for. We can
249+ # calculate a pointer to that unsigned int member.
250+ uncaught_ptr = (cxa_globals + void_ptr_type .sizeof ).cast (unsigned_int_type .pointer ())
251+
252+ return int (uncaught_ptr .dereference ())
235253
236254
237255def cpp_exception_state_present () -> bool :
You can’t perform that action at this time.
0 commit comments