- if(dbg_hlp)
- {
- /* debug help is already loaded */
- return 0;
- }
-
- /* allocation */
- dbg_hlp = xbt_new0(s_xbt_debug_hlp_t,1);
-
- if(!dbg_hlp)
- return ENOMEM;
-
- /* load the library */
- dbg_hlp->instance = LoadLibraryA("Dbghelp.dll");
-
- if(!(dbg_hlp->instance))
- {
- free(dbg_hlp);
- dbg_hlp = NULL;
- return (int)GetLastError();
- }
-
- /* get the pointers to debug help library exported functions */
-
- if(!((dbg_hlp->sym_initialize) = (xbt_pfn_sym_initialize_t)GetProcAddress(dbg_hlp->instance,"SymInitialize")))
- {
- FreeLibrary(dbg_hlp->instance);
- free(dbg_hlp);
- dbg_hlp = NULL;
- return (int)GetLastError();
- }
-
- if(!((dbg_hlp->sym_cleanup) = (xbt_pfn_sym_cleanup_t)GetProcAddress(dbg_hlp->instance,"SymCleanup")))
- {
- FreeLibrary(dbg_hlp->instance);
- free(dbg_hlp);
- dbg_hlp = NULL;
- return (int)GetLastError();
- }
-
- if(!((dbg_hlp->sym_function_table_access) = (xbt_pfn_sym_function_table_access_t)GetProcAddress(dbg_hlp->instance,"SymFunctionTableAccess")))
- {
- FreeLibrary(dbg_hlp->instance);
- free(dbg_hlp);
- dbg_hlp = NULL;
- return (int)GetLastError();
- }
-
- if(!((dbg_hlp->sym_get_line_from_addr) = (xbt_pfn_sym_get_line_from_addr_t)GetProcAddress(dbg_hlp->instance,"SymGetLineFromAddr")))
- {
- FreeLibrary(dbg_hlp->instance);
- free(dbg_hlp);
- dbg_hlp = NULL;
- return (int)GetLastError();
- }
-
- if(!((dbg_hlp->sym_get_module_base) = (xbt_pfn_sym_get_module_base_t)GetProcAddress(dbg_hlp->instance,"SymGetModuleBase")))
- {
- FreeLibrary(dbg_hlp->instance);
- free(dbg_hlp);
- dbg_hlp = NULL;
- return (int)GetLastError();
- }
-
- if(!((dbg_hlp->sym_get_options) = (xbt_pfn_sym_get_options_t)GetProcAddress(dbg_hlp->instance,"SymGetOptions")))
- {
- FreeLibrary(dbg_hlp->instance);
- free(dbg_hlp);
- dbg_hlp = NULL;
- return (int)GetLastError();
- }
-
- if(!((dbg_hlp->sym_get_sym_from_addr) = (xbt_pfn_sym_get_sym_from_addr_t)GetProcAddress(dbg_hlp->instance,"SymGetSymFromAddr")))
- {
- FreeLibrary(dbg_hlp->instance);
- free(dbg_hlp);
- dbg_hlp = NULL;
- return (int)GetLastError();
- }
-
- if(!((dbg_hlp->sym_set_options) = (xbt_pfn_sym_set_options_t)GetProcAddress(dbg_hlp->instance,"SymSetOptions")))
- {
- FreeLibrary(dbg_hlp->instance);
- free(dbg_hlp);
- dbg_hlp = NULL;
- return (int)GetLastError();
- }
-
- if(!((dbg_hlp->stack_walk) = (xbt_pfn_stack_walk_t)GetProcAddress(dbg_hlp->instance,"StackWalk")))
- {
- FreeLibrary(dbg_hlp->instance);
- free(dbg_hlp);
- dbg_hlp = NULL;
- return (int)GetLastError();
- }
-
- dbg_hlp->process_handle = process_handle;
-
- (*(dbg_hlp->sym_set_options))((*(dbg_hlp->sym_get_options))() | SYMOPT_LOAD_LINES | SYMOPT_DEFERRED_LOADS);
-
- if(!(*(dbg_hlp->sym_initialize))(dbg_hlp->process_handle,0,1))
- {
- FreeLibrary(dbg_hlp->instance);
- free(dbg_hlp);
- dbg_hlp = NULL;
- return (int)GetLastError();
- }
-
-
- return 0;
+ int pos = 0;
+ STACKFRAME *stack_frame;
+ int first = 1;
+
+ IMAGEHLP_SYMBOL *pSym;
+ unsigned long offset = 0;
+ IMAGEHLP_LINE line_info = { 0 };
+ byte
+ __buffer[(sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR) +
+ sizeof(ULONG64) - 1) / sizeof(ULONG64)];
+
+ CONTEXT context = { CONTEXT_FULL };
+ GetThreadContext(GetCurrentThread(), &context);
+
+ /* ebp points on stack base */
+ /* esp points on stack pointer, ie on last stacked element (current element) */
+ _asm call $ + 5
+ _asm pop eax
+ _asm mov context.Eip, eax
+ _asm mov eax, esp
+ _asm mov context.Esp, eax
+ _asm mov context.Ebp, ebp
+
+ if ((NULL == hlp_dbg_instance) || (size <= 0) || (NULL == buffer)) {
+ errno = EINVAL;
+ return 0;
+ }
+
+ for (pos = 0; pos < size; pos++)
+ buffer[pos] = NULL;
+
+ pos = 0;
+
+ pSym = (IMAGEHLP_SYMBOL *) __buffer;
+
+ pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
+ pSym->MaxNameLength = MAX_SYM_NAME;
+
+
+ line_info.SizeOfStruct = sizeof(IMAGEHLP_LINE);
+
+
+ while (pos < size) {
+ stack_frame = (void *) xbt_new0(STACKFRAME, 1);
+
+ stack_frame->AddrPC.Offset = context.Eip;
+ stack_frame->AddrPC.Mode = AddrModeFlat;
+
+ stack_frame->AddrFrame.Offset = context.Ebp;
+ stack_frame->AddrFrame.Mode = AddrModeFlat;
+
+ stack_frame->AddrStack.Offset = context.Esp;
+ stack_frame->AddrStack.Mode = AddrModeFlat;
+
+ if ((*fun_stack_walk) (IMAGE_FILE_MACHINE_I386,
+ process_handle,
+ GetCurrentThread(),
+ stack_frame,
+ &context,
+ NULL,
+ fun_function_table_access,
+ fun_get_module_base, NULL)
+ && !first) {
+ if (stack_frame->AddrReturn.Offset) {
+
+ if ((*fun_get_sym_from_addr) (process_handle, stack_frame->AddrPC.Offset, &offset, pSym)) {
+ if ((*fun_get_line_from_addr) (process_handle, stack_frame->AddrPC.Offset, &offset, &line_info))
+ buffer[pos++] = (void *) stack_frame;
+ }
+ } else {
+ free(stack_frame); /* no symbol or no line info */
+ break;
+ }
+ } else {
+ free(stack_frame);
+
+ if (first)
+ first = 0;
+ else
+ break;
+ }
+ }
+
+ return pos;