+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: initialize our tables */
+void xbt_backtrace_preinit(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;
+ }
+}