diff --git a/src/agent/debugger/src/dbghelp.rs b/src/agent/debugger/src/dbghelp.rs index ff5ad14c09..3d925fcfd2 100644 --- a/src/agent/debugger/src/dbghelp.rs +++ b/src/agent/debugger/src/dbghelp.rs @@ -8,6 +8,7 @@ #![allow(clippy::collapsible_if)] #![allow(clippy::needless_return)] #![allow(clippy::upper_case_acronyms)] + /// This module defines a wrapper around dbghelp apis so they can be used in a thread safe manner /// as well as providing a more Rust like api. use std::{ @@ -34,8 +35,9 @@ use winapi::{ dbghelp::{ AddrModeFlat, StackWalkEx, SymCleanup, SymFindFileInPathW, SymFromNameW, SymFunctionTableAccess64, SymGetModuleBase64, SymInitializeW, SymLoadModuleExW, - IMAGEHLP_LINEW64, PIMAGEHLP_LINEW64, PSYMBOL_INFOW, STACKFRAME_EX, SYMBOL_INFOW, - SYMOPT_DEBUG, SYMOPT_DEFERRED_LOADS, SYMOPT_FAIL_CRITICAL_ERRORS, SYMOPT_NO_PROMPTS, + IMAGEHLP_LINEW64, INLINE_FRAME_CONTEXT_IGNORE, INLINE_FRAME_CONTEXT_INIT, + PIMAGEHLP_LINEW64, PSYMBOL_INFOW, STACKFRAME_EX, SYMBOL_INFOW, SYMOPT_DEBUG, + SYMOPT_DEFERRED_LOADS, SYMOPT_FAIL_CRITICAL_ERRORS, SYMOPT_NO_PROMPTS, SYM_STKWALK_DEFAULT, }, errhandlingapi::GetLastError, @@ -537,6 +539,7 @@ impl DebugHelpGuard { &self, process_handle: HANDLE, thread_handle: HANDLE, + walk_inline_frames: bool, mut f: F, ) -> Result<()> { let mut frame_context = get_thread_frame(process_handle, thread_handle)?; @@ -548,6 +551,11 @@ impl DebugHelpGuard { frame.AddrStack.Mode = AddrModeFlat; frame.AddrFrame.Offset = frame_context.frame_pointer(); frame.AddrFrame.Mode = AddrModeFlat; + frame.InlineFrameContext = if walk_inline_frames { + INLINE_FRAME_CONTEXT_INIT + } else { + INLINE_FRAME_CONTEXT_IGNORE + }; loop { let success = unsafe { diff --git a/src/agent/debugger/src/debugger.rs b/src/agent/debugger/src/debugger.rs index 4df5a40af6..8074c7abcc 100644 --- a/src/agent/debugger/src/debugger.rs +++ b/src/agent/debugger/src/debugger.rs @@ -498,6 +498,7 @@ impl Debugger { dbghlp.stackwalk_ex( self.target.process_handle(), self.target.current_thread_handle(), + false, /* ignore inline frames */ |frame| { return_address = frame.AddrReturn; stack_pointer = frame.AddrStack; diff --git a/src/agent/debugger/src/stack.rs b/src/agent/debugger/src/stack.rs index 81495f4d0b..c37ea2b0af 100644 --- a/src/agent/debugger/src/stack.rs +++ b/src/agent/debugger/src/stack.rs @@ -228,39 +228,45 @@ pub fn get_stack( let mut stack = vec![]; - dbghlp.stackwalk_ex(process_handle, thread_handle, |frame| { - let program_counter = frame.AddrPC.Offset; - - let debug_stack_frame = if resolve_symbols { - if let Ok(module_info) = dbghlp.sym_get_module_info(process_handle, program_counter) { - get_function_location_in_module( - &dbghlp, - &module_info, - process_handle, - program_counter, - frame.InlineFrameContext, - ) + dbghlp.stackwalk_ex( + process_handle, + thread_handle, + true, /* visit inline frames */ + |frame| { + let program_counter = frame.AddrPC.Offset; + + let debug_stack_frame = if resolve_symbols { + if let Ok(module_info) = dbghlp.sym_get_module_info(process_handle, program_counter) + { + get_function_location_in_module( + &dbghlp, + &module_info, + process_handle, + program_counter, + frame.InlineFrameContext, + ) + } else { + // We ignore the error from sym_get_module_info because corrupt stacks in the + // target are a common cause of not finding the module - a condition we expect. + get_frame_with_unknown_module(process_handle, program_counter) + } } else { - // We ignore the error from sym_get_module_info because corrupt stacks in the - // target are a common cause of not finding the module - a condition we expect. get_frame_with_unknown_module(process_handle, program_counter) - } - } else { - get_frame_with_unknown_module(process_handle, program_counter) - }; + }; - // Avoid pushing consecutive corrupt frames. - if !debug_stack_frame.is_corrupt_frame() - || stack - .last() - .map_or(true, |f: &DebugStackFrame| !f.is_corrupt_frame()) - { - stack.push(debug_stack_frame); - }; + // Avoid pushing consecutive corrupt frames. + if !debug_stack_frame.is_corrupt_frame() + || stack + .last() + .map_or(true, |f: &DebugStackFrame| !f.is_corrupt_frame()) + { + stack.push(debug_stack_frame); + }; - // We want all frames, so continue walking. - true - })?; + // We want all frames, so continue walking. + true + }, + )?; Ok(DebugStack::new(stack)) }