31 #define MIN(a, b) (a) < (b) ? (a) : (b)
41 void winpr_win_backtrace_free(
void* buffer)
43 t_win_stack* data = (t_win_stack*)buffer;
51 void* winpr_win_backtrace(DWORD size)
53 HANDLE process = GetCurrentProcess();
54 t_win_stack* data = calloc(1,
sizeof(t_win_stack));
60 data->stack = calloc(data->max,
sizeof(PVOID));
68 SymInitialize(process, NULL, TRUE);
69 data->used = RtlCaptureStackBackTrace(2, size, data->stack, NULL);
73 char** winpr_win_backtrace_symbols(
void* buffer,
size_t* used)
82 size_t line_len = 1024;
83 HANDLE process = GetCurrentProcess();
84 t_win_stack* data = (t_win_stack*)buffer;
85 size_t array_size = data->used *
sizeof(
char*);
86 size_t lines_size = data->used * line_len;
87 char** vlines = calloc(1, array_size + lines_size);
88 SYMBOL_INFO* symbol = calloc(1,
sizeof(SYMBOL_INFO) + line_len *
sizeof(
char));
89 IMAGEHLP_LINE64* line = (IMAGEHLP_LINE64*)calloc(1,
sizeof(IMAGEHLP_LINE64));
91 if (!vlines || !symbol || !line)
99 line->SizeOfStruct =
sizeof(IMAGEHLP_LINE64);
100 symbol->MaxNameLen = (ULONG)line_len;
101 symbol->SizeOfStruct =
sizeof(SYMBOL_INFO);
104 for (
size_t i = 0; i < data->used; i++)
105 vlines[i] = (
char*)vlines + array_size + i * line_len;
107 for (
size_t i = 0; i < data->used; i++)
109 DWORD64 address = (DWORD64)(data->stack[i]);
111 SymFromAddr(process, address, 0, symbol);
113 if (SymGetLineFromAddr64(process, address, &displacement, line))
115 sprintf_s(vlines[i], line_len,
"%016" PRIx64
": %s in %s:%" PRIu32, symbol->Address,
116 symbol->Name, line->FileName, line->LineNumber);
119 sprintf_s(vlines[i], line_len,
"%016" PRIx64
": %s", symbol->Address, symbol->Name);
131 char* winpr_win_strerror(DWORD dw,
char* dmsg,
size_t size)
138 dwFlags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
139 #ifdef FORMAT_MESSAGE_ALLOCATE_BUFFER
141 dwFlags |= FORMAT_MESSAGE_ALLOCATE_BUFFER;
143 nSize = (DWORD)(size *
sizeof(WCHAR));
144 msg = (LPTSTR)calloc(nSize,
sizeof(WCHAR));
146 rc = FormatMessage(dwFlags, NULL, dw, 0, alloc ? (LPTSTR)&msg : msg, nSize, NULL);
151 WideCharToMultiByte(CP_ACP, 0, msg, rc, dmsg, (
int)MIN(size - 1, INT_MAX), NULL, NULL);
153 memcpy(dmsg, msg, MIN(rc, size - 1));
155 dmsg[MIN(rc, size - 1)] = 0;
156 #ifdef FORMAT_MESSAGE_ALLOCATE_BUFFER
164 _snprintf(dmsg, size,
"FAILURE: 0x%08" PRIX32
"", GetLastError());