31#define MIN(a, b) (a) < (b) ? (a) : (b)
41void winpr_win_backtrace_free(
void* buffer)
43 t_win_stack* data = (t_win_stack*)buffer;
51void* 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);
73char** 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);
131char* winpr_win_strerror(DWORD dw,
char* dmsg,
size_t size)
137 dwFlags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
138#ifdef FORMAT_MESSAGE_ALLOCATE_BUFFER
140 dwFlags |= FORMAT_MESSAGE_ALLOCATE_BUFFER;
142 nSize = (DWORD)(size *
sizeof(WCHAR));
143 msg = (LPTSTR)calloc(nSize,
sizeof(WCHAR));
145 const DWORD rc = FormatMessage(dwFlags, NULL, dw, 0, alloc ? (LPTSTR)&msg : msg, nSize, NULL);
150 (void)WideCharToMultiByte(CP_ACP, 0, msg, (
int)rc, dmsg, (int)(MIN(size - 1, INT_MAX)),
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());