void DumpHeap(const char* basename, int idx, JSContext* cx) { char filename[64]; sprintf_s(filename, ARRAY_SIZE(filename), "%s.%03d.txt", basename, idx); OsPath pathname = psLogDir() / filename; FILE* f = sys_OpenFile(pathname, "w"); ENSURE(f); JS_DumpHeap(cx, f, NULL, 0, NULL, (size_t)-1, NULL); fclose(f); }
Status debug_WriteCrashlog(const wchar_t* text) { // (avoid infinite recursion and/or reentering this function if it // fails/reports an error) enum State { IDLE, BUSY, FAILED }; // note: the initial state is IDLE. we rely on zero-init because // initializing local static objects from constants may happen when // this is first called, which isn't thread-safe. (see C++ 6.7.4) cassert(IDLE == 0); static volatile intptr_t state; if(!cpu_CAS(&state, IDLE, BUSY)) return ERR::REENTERED; // NOWARN OsPath pathname = ah_get_log_dir()/"crashlog.txt"; FILE* f = sys_OpenFile(pathname, "w"); if(!f) { state = FAILED; // must come before DEBUG_DISPLAY_ERROR DEBUG_DISPLAY_ERROR(L"Unable to open crashlog.txt for writing (please ensure the log directory is writable)"); return ERR::FAIL; // NOWARN (the above text is more helpful than a generic error code) } fputwc(0xFEFF, f); // BOM fwprintf(f, L"%ls\n", text); fwprintf(f, L"\n\n====================================\n\n"); // allow user to bundle whatever information they want ah_bundle_logs(f); fclose(f); state = IDLE; return INFO::OK; }
// convert contents of file <in_filename> from char to wchar_t and // append to <out> file. static void AppendAsciiFile(FILE* out, const OsPath& pathname) { FILE* in = sys_OpenFile(pathname, "rb"); if (!in) { fwprintf(out, L"(unavailable)"); return; } const size_t buf_size = 1024; char buf[buf_size+1]; // include space for trailing '\0' while (!feof(in)) { size_t bytes_read = fread(buf, 1, buf_size, in); if (!bytes_read) break; buf[bytes_read] = 0; // 0-terminate fwprintf(out, L"%hs", buf); } fclose(in); }
void WriteSystemInfo() { TIMER(L"write_sys_info"); // get_cpu_info and gfx_detect already called during init - see call site snd_detect(); struct utsname un; uname(&un); OsPath pathname = psLogDir()/"system_info.txt"; FILE* f = sys_OpenFile(pathname, "w"); if(!f) return; // current timestamp (redundant WRT OS timestamp, but that is not // visible when people are posting this file's contents online) { wchar_t timestampBuf[100] = {'\0'}; time_t seconds; time(&seconds); struct tm* t = gmtime(&seconds); const size_t charsWritten = wcsftime(timestampBuf, ARRAY_SIZE(timestampBuf), L"(generated %Y-%m-%d %H:%M:%S UTC)", t); ENSURE(charsWritten != 0); fprintf(f, "%ls\n\n", timestampBuf); } // OS fprintf(f, "OS : %s %s (%s)\n", un.sysname, un.release, un.version); // CPU fprintf(f, "CPU : %s, %s", un.machine, cpu_IdentifierString()); #if ARCH_X86_X64 fprintf(f, " (%dx%dx%d)", (int)topology::NumPackages(), (int)topology::CoresPerPackage(), (int)topology::LogicalPerCore()); #endif double cpuClock = os_cpu_ClockFrequency(); // query OS (may fail) #if ARCH_X86_X64 if(cpuClock <= 0.0) cpuClock = x86_x64::ClockFrequency(); // measure (takes a few ms) #endif if(cpuClock > 0.0) { if(cpuClock < 1e9) fprintf(f, ", %.2f MHz\n", cpuClock*1e-6); else fprintf(f, ", %.2f GHz\n", cpuClock*1e-9); } else fprintf(f, "\n"); // memory fprintf(f, "Memory : %u MiB; %u MiB free\n", (unsigned)os_cpu_MemorySize(), (unsigned)os_cpu_MemoryAvailable()); // graphics const std::wstring cardName = gfx::CardName(); const std::wstring driverInfo = gfx::DriverInfo(); fprintf(f, "Graphics Card : %ls\n", cardName.c_str()); fprintf(f, "OpenGL Drivers : %s; %ls\n", glGetString(GL_VERSION), driverInfo.c_str()); fprintf(f, "Video Mode : %dx%d:%d\n", g_VideoMode.GetXRes(), g_VideoMode.GetYRes(), g_VideoMode.GetBPP()); // sound fprintf(f, "Sound Card : %ls\n", snd_card); fprintf(f, "Sound Drivers : %ls\n", snd_drv_ver); // OpenGL extensions (write them last, since it's a lot of text) const char* exts = ogl_ExtensionString(); if (!exts) exts = "{unknown}"; fprintf(f, "\nOpenGL Extensions: \n%s\n", SplitExts(exts).c_str()); // System Management BIOS (even more text than OpenGL extensions) std::string smbios = SMBIOS::StringizeStructures(SMBIOS::GetStructures()); fprintf(f, "\nSMBIOS: \n%s\n", smbios.c_str()); fclose(f); f = 0; }