| 41 | typedef pair<Array<DWORD64, StackLimit>, size_t> StackCapture; |
| 42 | |
| 43 | inline StackCapture captureStack() { |
| 44 | HANDLE process = GetCurrentProcess(); |
| 45 | HANDLE thread = GetCurrentThread(); |
| 46 | |
| 47 | CONTEXT context; |
| 48 | DWORD image; |
| 49 | STACKFRAME64 stackFrame; |
| 50 | |
| 51 | memset(&context, 0, sizeof(CONTEXT)); |
| 52 | context.ContextFlags = CONTEXT_FULL; |
| 53 | |
| 54 | ZeroMemory(&stackFrame, sizeof(STACKFRAME64)); |
| 55 | stackFrame.AddrPC.Mode = AddrModeFlat; |
| 56 | stackFrame.AddrReturn.Mode = AddrModeFlat; |
| 57 | stackFrame.AddrFrame.Mode = AddrModeFlat; |
| 58 | stackFrame.AddrStack.Mode = AddrModeFlat; |
| 59 | |
| 60 | #ifdef STAR_ARCHITECTURE_I386 |
| 61 | |
| 62 | #ifdef STAR_COMPILER_MSVC |
| 63 | __asm { |
| 64 | mov [context.Ebp], ebp; |
| 65 | mov [context.Esp], esp; |
| 66 | call next; |
| 67 | next: |
| 68 | pop [context.Eip]; |
| 69 | } |
| 70 | #else |
| 71 | DWORD eip_val = 0; |
| 72 | DWORD esp_val = 0; |
| 73 | DWORD ebp_val = 0; |
| 74 | |
| 75 | __asm__ __volatile__("call 1f\n1: pop %0" : "=g"(eip_val)); |
| 76 | __asm__ __volatile__("movl %%esp, %0" : "=g"(esp_val)); |
| 77 | __asm__ __volatile__("movl %%ebp, %0" : "=g"(ebp_val)); |
| 78 | |
| 79 | context.Eip = eip_val; |
| 80 | context.Esp = esp_val; |
| 81 | context.Ebp = ebp_val; |
| 82 | #endif |
| 83 | |
| 84 | image = IMAGE_FILE_MACHINE_I386; |
| 85 | |
| 86 | stackFrame.AddrPC.Offset = context.Eip; |
| 87 | stackFrame.AddrReturn.Offset = context.Eip; |
| 88 | stackFrame.AddrFrame.Offset = context.Ebp; |
| 89 | stackFrame.AddrStack.Offset = context.Esp; |
| 90 | |
| 91 | #elif defined STAR_ARCHITECTURE_X86_64 |
| 92 | |
| 93 | RtlCaptureContext(&context); |
| 94 | |
| 95 | image = IMAGE_FILE_MACHINE_AMD64; |
| 96 | |
| 97 | stackFrame.AddrPC.Offset = context.Rip; |
| 98 | stackFrame.AddrReturn.Offset = context.Rip; |
| 99 | stackFrame.AddrFrame.Offset = context.Rbp; |
| 100 | stackFrame.AddrStack.Offset = context.Rsp; |
no test coverage detected