PStack  2.0
Stack trace printer for MSVC and GCC binaries
pstack::pstack_event_handler Class Referencefinal

Handle debugger events with the goal of generating stack traces. More...

#include <pstack_event_handler.hpp>

Inheritance diagram for pstack::pstack_event_handler:
Collaboration diagram for pstack::pstack_event_handler:

Construction / Destruction

 pstack_event_handler () noexcept
 Construct the pstack_event_handler instance.
 
virtual ~pstack_event_handler () noexcept
 Destroy the pstack_event_handler instance.
 

base_debug_event_listener Interface

virtual bool create_process_event (psystem::process_id_t pid, psystem::thread_id_t tid, psystem::shared_handle<> const &file_handle, CREATE_PROCESS_DEBUG_INFO const &info) noexcept override
 Invoked when the debugger sends an event to indicate process creation. More...
 
virtual bool create_thread_event (psystem::process_id_t pid, psystem::thread_id_t tid, CREATE_THREAD_DEBUG_INFO const &info) noexcept override
 Invoked when the debugger sends an event to indicate thread creation. More...
 
virtual bool exception_event (psystem::process_id_t pid, psystem::thread_id_t tid, EXCEPTION_DEBUG_INFO const &info) noexcept override
 Invoked when the debugger sends an event to indicate some exception in normal process execution. More...
 
virtual bool exit_process_event (psystem::process_id_t pid, psystem::thread_id_t tid, EXIT_PROCESS_DEBUG_INFO const &info) noexcept override
 Invoked when the debugger sends an event to indicate that the process has exited. More...
 
virtual bool exit_thread_event (psystem::process_id_t pid, psystem::thread_id_t tid, EXIT_THREAD_DEBUG_INFO const &info) noexcept override
 Invoked when the debugger sends an event to indicate that a thread has exited. More...
 
virtual bool load_dll_event (psystem::process_id_t pid, psystem::thread_id_t tid, psystem::shared_handle<> const &file_handle, LOAD_DLL_DEBUG_INFO const &info) noexcept override
 Invoked when the debugger sends an event to indicate that a DLL hase been loaded. More...
 
virtual bool unload_dll_event (psystem::process_id_t pid, psystem::thread_id_t tid, UNLOAD_DLL_DEBUG_INFO const &info) noexcept override
 Invoked when the debugger encounters a DLL unload. More...
 

Public Accessors

psystem::thread_id_t get_active_thread_id () const noexcept
 Access the ID for the thread that was executing when the debugger attached. More...
 
psystem::process_infoget_process_info () const noexcept
 Access information about the process that generated the events for this handler. More...
 
bool is_debugger_ready () const noexcept
 Determines if the debugger is ready to give a valid stack trace for all threads. More...
 

Member Data

std::unique_ptr< psystem::process_infom_process_info
 The process for which events will be dispatched to this handler.
 
bool m_is_debugger_ready
 The debugger is ready to make stack traces for all threads. More...
 
psystem::thread_id_t m_active_thread
 The thread that was executing code when the debugger attached.
 

Additional Inherited Members

- Public Member Functions inherited from proclib::base_debug_event_listener
virtual ~base_debug_event_listener () noexcept
 Clean up base_debug_event_listener resources.
 
virtual bool output_debug_string_event (psystem::process_id_t pid, psystem::thread_id_t tid, OUTPUT_DEBUG_STRING_INFO const &info) noexcept
 Invoked when the debugger encounters a trace message from the debuggee. More...
 
virtual bool rip_event (psystem::process_id_t pid, psystem::thread_id_t tid, RIP_INFO const &info) noexcept
 Invoked when the debugger encounters a fatal application exit or debugger error. More...
 
- Protected Member Functions inherited from proclib::base_debug_event_listener
 base_debug_event_listener () noexcept
 Construct the base_debug_event_listener instance. More...
 

Detailed Description

Handle debugger events with the goal of generating stack traces.

This class handles events sent by the debugger — building structures as it goes — so that it can generate stack traces for one or more threads in a single process.

Author
Matt Bisson
Date
5 August, 2014
Since
PStack 2.0
Version
PStack 2.0

Member Function Documentation

bool pstack::pstack_event_handler::create_process_event ( psystem::process_id_t  pid,
psystem::thread_id_t  tid,
psystem::shared_handle<> const &  file_handle,
CREATE_PROCESS_DEBUG_INFO const &  info 
)
overridevirtualnoexcept

Invoked when the debugger sends an event to indicate process creation.

This events is sent upon attachment to a running process, or when the debugger itself creates a process for debugging. This event is important also because it signifies that the executable module has been loaded, and that the main process thread has been created.

Parameters
[in]pidThe ID of the process that signaled this event.
[in]tidThe ID of the thread that is currently in the active state.
[in]file_handleThe "shared" handle to the open file that represents this process's module. The handle will be closed if no listeners copy the shared_handle.
[in]infoInformation that pertains specifically to this event. Note that any handles in the structure may be nullptr, and that the hFile member is only valid until exit_process_event().
Returns
This method should return true to indicate that it has taken action based on receiving the event, or false to indicate that it has not.
Postcondition
get_process_info() returns a valid psystem::process_info instance.
Todo:
Should we not "share" HANDLE?
Todo:
Manual module file symbol loading

Reimplemented from proclib::base_debug_event_listener.

bool pstack::pstack_event_handler::create_thread_event ( psystem::process_id_t  pid,
psystem::thread_id_t  tid,
CREATE_THREAD_DEBUG_INFO const &  info 
)
overridevirtualnoexcept

Invoked when the debugger sends an event to indicate thread creation.

This event is sent when a new thread is created during normal execution in a process being debugged, or when the debugger attaches to a process and encounters a preexisting thread of execution.

Parameters
[in]pidThe ID of the process that signaled this event.
[in]tidThe ID of the thread that was created or discovered.
[in]infoInformation that applies specifically to this event.
Returns
This method should return true to indicate that it has taken action based on receiving the event, or false to indicate that it has not.
Todo:
Should we not "share" HANDLE?

Reimplemented from proclib::base_debug_event_listener.

bool pstack::pstack_event_handler::exception_event ( psystem::process_id_t  pid,
psystem::thread_id_t  tid,
EXCEPTION_DEBUG_INFO const &  info 
)
overridevirtualnoexcept

Invoked when the debugger sends an event to indicate some exception in normal process execution.

An exception may be an unhandled C++ exception, it may be a system-level exception (i.e., sigsegv on UNIX or GPF on Windows plaforms), or it may simply indicate that the debugger has reached a breakpoint (which may be requested either by the debugger itself, or by a user-specified break).

Parameters
[in]pidThe ID of the process that signaled this event.
[in]tidThe ID of the thread that is currently in the active state.
[in]infoInformation that applies specifically to this event. This will contain the exception record, which in turn contains the cause of the exception.
Returns
This method should return true to indicate that it has taken action based on receiving the event, or false to indicate that it has not.

Reimplemented from proclib::base_debug_event_listener.

bool pstack::pstack_event_handler::exit_process_event ( psystem::process_id_t  pid,
psystem::thread_id_t  tid,
EXIT_PROCESS_DEBUG_INFO const &  info 
)
overridevirtualnoexcept

Invoked when the debugger sends an event to indicate that the process has exited.

Parameters
[in]pidThe ID of the process that signaled this event.
[in]tidThe ID of the thread that was in the active state on exit.
[in]infoInformation that applies specifically to this event.
Returns
This method should return true to indicate that it has taken action based on receiving the event, or false to indicate that it has not.
Postcondition
All handles pertaining to this process are invalid.
get_process_info() returns nullptr. Any previous values returned from the method are invalidated.

Reimplemented from proclib::base_debug_event_listener.

bool pstack::pstack_event_handler::exit_thread_event ( psystem::process_id_t  pid,
psystem::thread_id_t  tid,
EXIT_THREAD_DEBUG_INFO const &  info 
)
overridevirtualnoexcept

Invoked when the debugger sends an event to indicate that a thread has exited.

Parameters
[in]pidThe ID of the process that signaled this event.
[in]tidThe ID of the thread that just exited.
[in]infoInformation that applies specifically to this event.
Returns
This method should return true to indicate that it has taken action based on receiving the event, or false to indicate that it has not.
Postcondition
The thread handle retrieved from create_thread_event() is no longer valid.

Reimplemented from proclib::base_debug_event_listener.

psystem::thread_id_t pstack::pstack_event_handler::get_active_thread_id ( ) const
noexcept

Access the ID for the thread that was executing when the debugger attached.

Returns
A system thread ID (TID). If no events have been seen, this value is undefined.
psystem::process_info * pstack::pstack_event_handler::get_process_info ( ) const
noexcept

Access information about the process that generated the events for this handler.

Returns
This returns nullptr if it is called before this handler receives create_process_event(), and after exit_process_event() (without a subsequent create_process_event). A pointer returned by this function is only valid until the next exit_process_event, or until the instance is destroyed.
bool pstack::pstack_event_handler::is_debugger_ready ( ) const
noexcept

Determines if the debugger is ready to give a valid stack trace for all threads.

Returns
This is false until the pstack_event_handler decides that it has seen all of the debugger events that come from the debugger attaching to a process.
bool pstack::pstack_event_handler::load_dll_event ( psystem::process_id_t  pid,
psystem::thread_id_t  tid,
psystem::shared_handle<> const &  file_handle,
LOAD_DLL_DEBUG_INFO const &  info 
)
overridevirtualnoexcept

Invoked when the debugger sends an event to indicate that a DLL hase been loaded.

This callback may be triggered if a DLL has been loaded into a running process, or if the debugger discovers an already loaded DLL when attaching to a process.

Parameters
[in]pidThe ID of the process that signaled this event.
[in]tidThe ID of the thread that is currently in the active state.
[in]file_handleThe "shared" handle to the open file that represents this process's module. The handle will be closed if no listeners copy the shared_handle.
[in]infoInformation that applies specifically to this event. Note that any handles in the structure may be nullptr, and that the hFile member is only valid until unload_dll_event().
Returns
This method should return true to indicate that it has taken action based on receiving the event, or false to indicate that it has not.

Reimplemented from proclib::base_debug_event_listener.

bool pstack::pstack_event_handler::unload_dll_event ( psystem::process_id_t  pid,
psystem::thread_id_t  tid,
UNLOAD_DLL_DEBUG_INFO const &  info 
)
overridevirtualnoexcept

Invoked when the debugger encounters a DLL unload.

Parameters
[in]pidThe ID of the process that signaled this event.
[in]tidThe ID of the currently active thread.
[in]infoInformation that applies specifically to this event.
Returns
This method should return true to indicate that it has taken action based on receiving the event, or false to indicate that it has not.
Postcondition
The handle retrieved from the corresponding load_dll_event() is no longer valid.
Todo:
Need to figure out index for some kind of set

Reimplemented from proclib::base_debug_event_listener.

Member Data Documentation

bool pstack::pstack_event_handler::m_is_debugger_ready
private

The debugger is ready to make stack traces for all threads.

Todo:
Should this be a state machine to allow us to determine "saw process" -> "saw threads" -> "saw modules" -> etc?

The documentation for this class was generated from the following files: