michael@0: #include michael@0: michael@0: #include "google_breakpad/processor/minidump.h" michael@0: #include "nscore.h" michael@0: michael@0: using namespace google_breakpad; michael@0: michael@0: // Return true if the specified minidump contains a stream of |stream_type|. michael@0: extern "C" michael@0: NS_EXPORT bool michael@0: DumpHasStream(const char* dump_file, uint32_t stream_type) michael@0: { michael@0: Minidump dump(dump_file); michael@0: if (!dump.Read()) michael@0: return false; michael@0: michael@0: uint32_t length; michael@0: if (!dump.SeekToStreamType(stream_type, &length) || length == 0) michael@0: return false; michael@0: michael@0: return true; michael@0: } michael@0: michael@0: // Return true if the specified minidump contains a memory region michael@0: // that contains the instruction pointer from the exception record. michael@0: extern "C" michael@0: NS_EXPORT bool michael@0: DumpHasInstructionPointerMemory(const char* dump_file) michael@0: { michael@0: Minidump minidump(dump_file); michael@0: if (!minidump.Read()) michael@0: return false; michael@0: michael@0: MinidumpException* exception = minidump.GetException(); michael@0: MinidumpMemoryList* memory_list = minidump.GetMemoryList(); michael@0: if (!exception || !memory_list) { michael@0: return false; michael@0: } michael@0: michael@0: MinidumpContext* context = exception->GetContext(); michael@0: if (!context) michael@0: return false; michael@0: michael@0: uint64_t instruction_pointer; michael@0: if (!context->GetInstructionPointer(&instruction_pointer)) { michael@0: return false; michael@0: } michael@0: michael@0: MinidumpMemoryRegion* region = michael@0: memory_list->GetMemoryRegionForAddress(instruction_pointer); michael@0: return region != nullptr; michael@0: } michael@0: michael@0: // This function tests for a very specific condition. It finds michael@0: // an address in a file, "crash-addr", in the CWD. It checks michael@0: // that the minidump has a memory region starting at that michael@0: // address. The region must be 32 bytes long and contain the michael@0: // values 0 to 31 as bytes, in ascending order. michael@0: extern "C" michael@0: NS_EXPORT bool michael@0: DumpCheckMemory(const char* dump_file) michael@0: { michael@0: Minidump dump(dump_file); michael@0: if (!dump.Read()) michael@0: return false; michael@0: michael@0: MinidumpMemoryList* memory_list = dump.GetMemoryList(); michael@0: if (!memory_list) { michael@0: return false; michael@0: } michael@0: michael@0: void *addr; michael@0: FILE *fp = fopen("crash-addr", "r"); michael@0: if (!fp) michael@0: return false; michael@0: if (fscanf(fp, "%p", &addr) != 1) michael@0: return false; michael@0: fclose(fp); michael@0: michael@0: remove("crash-addr"); michael@0: michael@0: MinidumpMemoryRegion* region = michael@0: memory_list->GetMemoryRegionForAddress(uint64_t(addr)); michael@0: if(!region) michael@0: return false; michael@0: michael@0: const uint8_t* chars = region->GetMemory(); michael@0: if (region->GetSize() != 32) michael@0: return false; michael@0: michael@0: for (int i=0; i<32; i++) { michael@0: if (chars[i] != i) michael@0: return false; michael@0: } michael@0: michael@0: return true; michael@0: }