Wooo, RAII

This commit is contained in:
Asher Baker 2018-07-20 20:57:12 +01:00
parent 3dc66eec46
commit c88ae7d972

View File

@ -5,8 +5,6 @@
#include "common/linux/dump_symbols.h" #include "common/linux/dump_symbols.h"
#include "common/path_helper.h" #include "common/path_helper.h"
#include <sstream>
#include <signal.h> #include <signal.h>
#include <dirent.h> #include <dirent.h>
#include <unistd.h> #include <unistd.h>
@ -19,6 +17,26 @@
using google_breakpad::MinidumpDescriptor; using google_breakpad::MinidumpDescriptor;
using google_breakpad::WriteSymbolFile; using google_breakpad::WriteSymbolFile;
class StderrInhibitor
{
FILE *saved_stderr = nullptr;
public:
StderrInhibitor() {
saved_stderr = fdopen(dup(fileno(stderr)), "w");
if (freopen(_PATH_DEVNULL, "w", stderr)) {
// If it fails, not a lot we can (or should) do.
// Add this brace section to silence gcc warnings.
}
}
~StderrInhibitor() {
fflush(stderr);
dup2(fileno(saved_stderr), fileno(stderr));
fclose(saved_stderr);
}
};
#elif defined _WINDOWS #elif defined _WINDOWS
#define _STDINT // ~.~ #define _STDINT // ~.~
#include "client/windows/handler/exception_handler.h" #include "client/windows/handler/exception_handler.h"
@ -38,6 +56,7 @@ using google_breakpad::WriteSymbolFile;
#include <google_breakpad/processor/stack_frame.h> #include <google_breakpad/processor/stack_frame.h>
#include <processor/pathname_stripper.h> #include <processor/pathname_stripper.h>
#include <sstream>
#include <streambuf> #include <streambuf>
#include <setjmp.h> #include <setjmp.h>
@ -53,6 +72,21 @@ using google_breakpad::StackFrame;
using google_breakpad::PathnameStripper; using google_breakpad::PathnameStripper;
using google_breakpad::CodeModule; using google_breakpad::CodeModule;
class ClogInhibitor
{
std::streambuf *saved_clog = nullptr;
public:
ClogInhibitor() {
saved_clog = std::clog.rdbuf();
std::clog.rdbuf(nullptr);
}
~ClogInhibitor() {
std::clog.rdbuf(saved_clog);
}
};
my_jmp_buf envbuf; my_jmp_buf envbuf;
char path[1024]; char path[1024];
@ -123,15 +157,14 @@ int main(int argc, char *argv[])
strncpy(path, argv[i], sizeof(path)); strncpy(path, argv[i], sizeof(path));
} }
ProcessState processState;
ProcessResult processResult;
MinidumpProcessor minidumpProcessor(nullptr, nullptr); MinidumpProcessor minidumpProcessor(nullptr, nullptr);
std::streambuf *old = std::clog.rdbuf(); {
std::clog.rdbuf(nullptr); ClogInhibitor clogInhibitor;
processResult = minidumpProcessor.Process(path, &processState);
ProcessState processState; }
ProcessResult processResult = minidumpProcessor.Process(path, &processState);
std::clog.rdbuf(old);
if (processResult != google_breakpad::PROCESS_OK) { if (processResult != google_breakpad::PROCESS_OK) {
continue; continue;
@ -144,7 +177,6 @@ int main(int argc, char *argv[])
const CallStack *stack = processState.threads()->at(requestingThread); const CallStack *stack = processState.threads()->at(requestingThread);
if (!stack) { if (!stack) {
fprintf(stderr, "Minidump missing stack!\n");
continue; continue;
} }
@ -153,7 +185,8 @@ int main(int argc, char *argv[])
frameCount = 10; frameCount = 10;
} }
printf("1|%d|%s|%x|%d", processState.crashed(), processState.crash_reason().c_str(), (intptr_t)processState.crash_address(), requestingThread); std::ostringstream summaryStream;
summaryStream << 1 << "|" << processState.crashed() << "|" << processState.crash_reason() << "|" << std::hex << processState.crash_address() << std::dec << "|" << requestingThread;
std::map<const CodeModule *, unsigned int> moduleMap; std::map<const CodeModule *, unsigned int> moduleMap;
@ -164,22 +197,25 @@ int main(int argc, char *argv[])
auto debugFile = PathnameStripper::File(module->debug_file()); auto debugFile = PathnameStripper::File(module->debug_file());
auto debugIdentifier = module->debug_identifier(); auto debugIdentifier = module->debug_identifier();
printf("|M|%s|%s", debugFile.c_str(), debugIdentifier.c_str());
summaryStream << "|M|" << debugFile << "|" << debugIdentifier;
} }
for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) { for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
const StackFrame *frame = stack->frames()->at(frameIndex); const StackFrame *frame = stack->frames()->at(frameIndex);
if (frame->module) {
auto moduleIndex = moduleMap[frame->module];
auto moduleOffset = frame->ReturnAddress() - frame->module->base_address();
printf("|F|%d|%x", moduleIndex, (intptr_t)moduleOffset); int moduleIndex = -1;
} else { auto moduleOffset = frame->ReturnAddress();
printf("|F|%d|%x", -1, (intptr_t)frame->ReturnAddress()); if (frame->module) {
moduleIndex = moduleMap[frame->module];
moduleOffset -= frame->module->base_address();
} }
summaryStream << "|F|" << moduleIndex << "|" << std::hex << moduleOffset << std::dec;
} }
printf("\n"); auto summaryLine = summaryStream.str();
printf("%s\n", summaryLine.c_str());
#if defined _LINUX #if defined _LINUX
for (unsigned int moduleIndex = 0; moduleIndex < moduleCount; ++moduleIndex) { for (unsigned int moduleIndex = 0; moduleIndex < moduleCount; ++moduleIndex) {
@ -197,35 +233,28 @@ int main(int argc, char *argv[])
debugFileDir, debugFileDir,
}; };
FILE *saved_stderr = fdopen(dup(fileno(stderr)), "w");
if (freopen(_PATH_DEVNULL, "w", stderr)) {
// If it fails, not a lot we can (or should) do.
// Add this brace section to silence gcc warnings.
}
std::ostringstream outputStream; std::ostringstream outputStream;
google_breakpad::DumpOptions options(ALL_SYMBOL_DATA, true); google_breakpad::DumpOptions options(ALL_SYMBOL_DATA, true);
if (!WriteSymbolFile(debugFile, debug_dirs, options, outputStream)) {
outputStream.str("");
outputStream.clear();
// Try again without debug dirs. {
if (!WriteSymbolFile(debugFile, {}, options, outputStream)) { StderrInhibitor stdrrInhibitor;
// TODO: Something.
if (!WriteSymbolFile(debugFile, debug_dirs, options, outputStream)) {
outputStream.str("");
outputStream.clear();
// Try again without debug dirs.
if (!WriteSymbolFile(debugFile, {}, options, outputStream)) {
// TODO: Something.
continue;
}
} }
} }
fflush(stderr);
dup2(fileno(saved_stderr), fileno(stderr));
fclose(saved_stderr);
// WriteSymbolFileHeaderOnly would do this for us, but this is just for testing. // WriteSymbolFileHeaderOnly would do this for us, but this is just for testing.
auto output = outputStream.str(); auto output = outputStream.str();
output = output.substr(0, output.find("\n")); output = output.substr(0, output.find("\n"));
fprintf(stdout, "%s\n", output.c_str()); printf("%s\n", output.c_str());
// break;
} }
#endif #endif
} }