| 170 | #ifdef _WIN32 |
| 171 | |
| 172 | void WriteMetaFile(const char* stamp, EXCEPTION_POINTERS* ep, |
| 173 | const std::string& guest_tail) { |
| 174 | std::string path = JoinPath(g_config.crash_dir, |
| 175 | std::string("crash_") + stamp + ".meta"); |
| 176 | std::FILE* f = std::fopen(path.c_str(), "wb"); |
| 177 | if (!f) return; |
| 178 | |
| 179 | DWORD code = ep && ep->ExceptionRecord ? ep->ExceptionRecord->ExceptionCode : 0; |
| 180 | void* addr = ep && ep->ExceptionRecord ? ep->ExceptionRecord->ExceptionAddress : nullptr; |
| 181 | |
| 182 | std::fprintf(f, "TenBox runtime crash\n"); |
| 183 | std::fprintf(f, "version : %s\n", g_config.version.c_str()); |
| 184 | std::fprintf(f, "vm_id : %s\n", g_config.vm_id.c_str()); |
| 185 | std::fprintf(f, "pid : %lu\n", GetCurrentProcessId()); |
| 186 | std::fprintf(f, "tid : %lu\n", GetCurrentThreadId()); |
| 187 | std::fprintf(f, "code : 0x%08lx\n", code); |
| 188 | std::fprintf(f, "address : 0x%p\n", addr); |
| 189 | if (code == EXCEPTION_ACCESS_VIOLATION && ep && ep->ExceptionRecord |
| 190 | && ep->ExceptionRecord->NumberParameters >= 2) { |
| 191 | const ULONG_PTR* p = ep->ExceptionRecord->ExceptionInformation; |
| 192 | const char* kind = p[0] == 0 ? "read" : (p[0] == 1 ? "write" : "exec"); |
| 193 | std::fprintf(f, "av_kind : %s\n", kind); |
| 194 | std::fprintf(f, "av_addr : 0x%p\n", reinterpret_cast<void*>(p[1])); |
| 195 | } |
| 196 | std::fprintf(f, "\n-- last guest console (%zu bytes) --\n", guest_tail.size()); |
| 197 | std::fwrite(guest_tail.data(), 1, guest_tail.size(), f); |
| 198 | std::fclose(f); |
| 199 | } |
| 200 | |
| 201 | LONG WINAPI TopLevelFilter(EXCEPTION_POINTERS* ep) { |
| 202 | bool expected = false; |
no test coverage detected