Théophile Bastian
df2d6179a8
Preserves stack_walker's interface (one can link against stack_walker or stack_walker_unwind indifferently).
47 lines
1.5 KiB
C++
47 lines
1.5 KiB
C++
/** Provides stack walking facilities exploiting the eh_elf objects, that can
|
|
* be loaded at runtime. */
|
|
|
|
|
|
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <functional>
|
|
|
|
#include "../shared/context_struct.h"
|
|
|
|
/** Handled registers list */
|
|
enum StackWalkerRegisters {
|
|
SW_REG_RIP,
|
|
SW_REG_RSP,
|
|
SW_REG_RBP
|
|
};
|
|
|
|
/** Initialize the stack walker. This must be called only once.
|
|
*
|
|
* \return true iff everything was correctly initialized.
|
|
*/
|
|
bool stack_walker_init();
|
|
|
|
/** Deallocate everything that was allocated by the stack walker */
|
|
void stack_walker_close();
|
|
|
|
/** Get the unwind context of the point from which this function was called.
|
|
*
|
|
* This context must then be exploited straight away: it is unsafe to alter the
|
|
* call stack before using it, in particular by returning from the calling
|
|
* function. */
|
|
unwind_context_t get_context();
|
|
|
|
/** Unwind the passed context once, in place.
|
|
*
|
|
* Returns `true` if the context was actually unwinded, or `false` if the end
|
|
* of the call stack was reached. */
|
|
bool unwind_context(unwind_context_t& ctx);
|
|
|
|
/** Call the passed function once per frame in the call stack, most recent
|
|
* frame first, with the current context as its sole argument. */
|
|
void walk_stack(const std::function<void(const unwind_context_t&)>& mapped);
|
|
|
|
/** Get a register's value on an unwind_context_t. This is useful for other
|
|
* implementations of stack_walker that use different unwind_context_t */
|
|
uintptr_t get_register(const unwind_context_t& ctx, StackWalkerRegisters reg);
|