-typedef BOOL(WINAPI * xbt_pfn_stack_walk_t) (DWORD, HANDLE, HANDLE,
- LPSTACKFRAME, PVOID,
- PREAD_PROCESS_MEMORY_ROUTINE,
- PFUNCTION_TABLE_ACCESS_ROUTINE,
- PGET_MODULE_BASE_ROUTINE,
- PTRANSLATE_ADDRESS_ROUTINE);
-
-/* This structure represents the debug_help library used interface */
-typedef struct s_xbt_debug_help {
- HINSTANCE instance;
- HANDLE process_handle;
- xbt_pfn_sym_initialize_t sym_initialize;
- xbt_pfn_sym_cleanup_t sym_cleanup;
- xbt_pfn_sym_function_table_access_t sym_function_table_access;
- xbt_pfn_sym_get_line_from_addr_t sym_get_line_from_addr;
- xbt_pfn_sym_get_module_base_t sym_get_module_base;
- xbt_pfn_sym_get_options_t sym_get_options;
- xbt_pfn_sym_get_sym_from_addr_t sym_get_sym_from_addr;
- xbt_pfn_sym_set_options_t sym_set_options;
- xbt_pfn_stack_walk_t stack_walk;
-} s_xbt_debug_hlp_t, *xbt_debug_hlp_t;
-
-
-/* the address to the unique reference to the debug help library interface */
-static xbt_debug_hlp_t dbg_hlp = NULL;
-
-/* initialize the debug help library */
-static int dbg_hlp_init(HANDLE process_handle);
-
-/* finalize the debug help library */
-static int dbg_hlp_finalize(void);
+typedef BOOL(WINAPI * fun_stack_walk_t) (DWORD, HANDLE, HANDLE,
+ LPSTACKFRAME, PVOID,
+ PREAD_PROCESS_MEMORY_ROUTINE,
+ PFUNCTION_TABLE_ACCESS_ROUTINE,
+ PGET_MODULE_BASE_ROUTINE,
+ PTRANSLATE_ADDRESS_ROUTINE);
+static fun_stack_walk_t fun_stack_walk;
+
+static HINSTANCE hlp_dbg_instance = NULL;
+static HANDLE process_handle = NULL;
+
+
+/* Module creation/destruction: nothing to do on linux */
+void xbt_backtrace_init(void)
+{
+ process_handle = GetCurrentProcess();
+
+ if (hlp_dbg_instance) {
+ /* debug help is already loaded */
+ return;
+ }
+
+ /* load the library */
+ hlp_dbg_instance = LoadLibraryA("Dbghelp.dll");
+
+ if (!hlp_dbg_instance)
+ return;
+
+ /* get the pointers to debug help library exported functions */
+ fun_initialize =
+ (fun_initialize_t) GetProcAddress(hlp_dbg_instance, "SymInitialize");
+ fun_cleanup =
+ (fun_cleanup_t) GetProcAddress(hlp_dbg_instance, "SymCleanup");
+ fun_function_table_access =
+ (fun_function_table_access_t) GetProcAddress(hlp_dbg_instance,
+ "SymFunctionTableAccess");
+ fun_get_line_from_addr =
+ (fun_get_line_from_addr_t) GetProcAddress(hlp_dbg_instance,
+ "SymGetLineFromAddr");
+ fun_get_module_base =
+ (fun_get_module_base_t) GetProcAddress(hlp_dbg_instance,
+ "SymGetModuleBase");
+ fun_get_options =
+ (fun_get_options_t) GetProcAddress(hlp_dbg_instance, "SymGetOptions");
+ fun_get_sym_from_addr =
+ (fun_get_sym_from_addr_t) GetProcAddress(hlp_dbg_instance,
+ "SymGetSymFromAddr");
+ fun_set_options =
+ (fun_set_options_t) GetProcAddress(hlp_dbg_instance, "SymSetOptions");
+ fun_stack_walk =
+ (fun_stack_walk_t) GetProcAddress(hlp_dbg_instance, "StackWalk");
+
+ /* Check that everything worked well */
+ if (!fun_initialize ||
+ !fun_cleanup ||
+ !fun_function_table_access ||
+ !fun_get_line_from_addr ||
+ !fun_get_module_base ||
+ !fun_get_options ||
+ !fun_get_sym_from_addr || !fun_set_options || !fun_stack_walk) {
+ FreeLibrary(hlp_dbg_instance);
+ hlp_dbg_instance = NULL;
+ return;
+ }
+
+ (*fun_set_options) ((*fun_get_options) () |
+ SYMOPT_LOAD_LINES | SYMOPT_DEFERRED_LOADS);
+
+ if (!(*fun_initialize) (process_handle, 0, 1)) {
+ FreeLibrary(hlp_dbg_instance);
+ hlp_dbg_instance = NULL;
+ }
+}
+
+void xbt_backtrace_exit(void)
+{
+ if (!hlp_dbg_instance)
+ return;
+
+ if ((*fun_cleanup) (process_handle))
+ FreeLibrary(hlp_dbg_instance);
+
+ hlp_dbg_instance = NULL;
+}