Removing the new Minidump plugin

Tests are failing and build is failing on windows and darwin.
Will fix and commit it later
-------------------------------------------------------------

Revert "xfailing minidump tests again ... :("
This reverts commit 97eade002c9e43c1e0d11475a4888083a8965044.

Revert "Fixing new Minidump plugin tests"
This reverts commit 0dd93b3ab39c8288696001dd50b9a093b813b09c.

Revert "Add the new minidump files to the Xcode project."
This reverts commit 2f638a1d046b8a88e61e212220edc40aecd2ce44.

Revert "xfailing tests for Minidump plugin"
This reverts commit 99311c0b22338a83e6a00c4fbddfd3577914c003.

Revert "Adding a new Minidump post-mortem debugging plugin"
This reverts commit b09a7e4dae231663095a84dac4be3da00b03a021.

llvm-svn: 283352
This commit is contained in:
Dimitar Vlahovski 2016-10-05 18:11:45 +00:00
parent 0debabb3d0
commit 36e21a3d56
20 changed files with 25 additions and 820 deletions

View File

@ -735,8 +735,6 @@
4C56543519D2297A002E9C44 /* SBThreadPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C56543419D2297A002E9C44 /* SBThreadPlan.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4C56543519D2297A002E9C44 /* SBThreadPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C56543419D2297A002E9C44 /* SBThreadPlan.h */; settings = {ATTRIBUTES = (Public, ); }; };
4C56543719D22B32002E9C44 /* SBThreadPlan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C56543619D22B32002E9C44 /* SBThreadPlan.cpp */; }; 4C56543719D22B32002E9C44 /* SBThreadPlan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C56543619D22B32002E9C44 /* SBThreadPlan.cpp */; };
4C6649A314EEE81000B0316F /* StreamCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C6649A214EEE81000B0316F /* StreamCallback.cpp */; }; 4C6649A314EEE81000B0316F /* StreamCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C6649A214EEE81000B0316F /* StreamCallback.cpp */; };
4C6966101DA47BCE004FAE72 /* ThreadMinidump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C6966081DA47BB4004FAE72 /* ThreadMinidump.cpp */; };
4C6966111DA47BDB004FAE72 /* ProcessMinidump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C69660A1DA47BB4004FAE72 /* ProcessMinidump.cpp */; };
4C88BC2A1BA3722B00AA0964 /* Expression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C88BC291BA3722B00AA0964 /* Expression.cpp */; }; 4C88BC2A1BA3722B00AA0964 /* Expression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C88BC291BA3722B00AA0964 /* Expression.cpp */; };
4C88BC2D1BA391B000AA0964 /* UserExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0083331B9A5DE200D5CF24 /* UserExpression.cpp */; }; 4C88BC2D1BA391B000AA0964 /* UserExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0083331B9A5DE200D5CF24 /* UserExpression.cpp */; };
4CABA9E0134A8BCD00539BDD /* ValueObjectMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CABA9DF134A8BCD00539BDD /* ValueObjectMemory.cpp */; }; 4CABA9E0134A8BCD00539BDD /* ValueObjectMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CABA9DF134A8BCD00539BDD /* ValueObjectMemory.cpp */; };
@ -958,6 +956,7 @@
AFCB2BBD1BF577F40018B553 /* PythonExceptionState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFCB2BBB1BF577F40018B553 /* PythonExceptionState.cpp */; }; AFCB2BBD1BF577F40018B553 /* PythonExceptionState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFCB2BBB1BF577F40018B553 /* PythonExceptionState.cpp */; };
AFCB2BBE1BF577F40018B553 /* PythonExceptionState.h in Headers */ = {isa = PBXBuildFile; fileRef = AFCB2BBC1BF577F40018B553 /* PythonExceptionState.h */; }; AFCB2BBE1BF577F40018B553 /* PythonExceptionState.h in Headers */ = {isa = PBXBuildFile; fileRef = AFCB2BBC1BF577F40018B553 /* PythonExceptionState.h */; };
AFD65C811D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFD65C7F1D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp */; }; AFD65C811D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFD65C7F1D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp */; };
AFD65C821D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = AFD65C801D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.h */; };
AFDCDBCB19DD0F42005EA55E /* SBExecutionContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 940B02F419DC96CB00AD0F52 /* SBExecutionContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; AFDCDBCB19DD0F42005EA55E /* SBExecutionContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 940B02F419DC96CB00AD0F52 /* SBExecutionContext.h */; settings = {ATTRIBUTES = (Public, ); }; };
AFDFDFD119E34D3400EAE509 /* ConnectionFileDescriptorPosix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFDFDFD019E34D3400EAE509 /* ConnectionFileDescriptorPosix.cpp */; }; AFDFDFD119E34D3400EAE509 /* ConnectionFileDescriptorPosix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFDFDFD019E34D3400EAE509 /* ConnectionFileDescriptorPosix.cpp */; };
AFEC3362194A8ABA00FF05C6 /* StructuredData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFEC3361194A8ABA00FF05C6 /* StructuredData.cpp */; }; AFEC3362194A8ABA00FF05C6 /* StructuredData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFEC3361194A8ABA00FF05C6 /* StructuredData.cpp */; };
@ -1336,6 +1335,7 @@
23E2E5201D903726006F38BB /* linux-x86_64.dmp */ = {isa = PBXFileReference; lastKnownFileType = file; path = "linux-x86_64.dmp"; sourceTree = "<group>"; }; 23E2E5201D903726006F38BB /* linux-x86_64.dmp */ = {isa = PBXFileReference; lastKnownFileType = file; path = "linux-x86_64.dmp"; sourceTree = "<group>"; };
23E2E52D1D90382B006F38BB /* BreakpointIDTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BreakpointIDTest.cpp; sourceTree = "<group>"; }; 23E2E52D1D90382B006F38BB /* BreakpointIDTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BreakpointIDTest.cpp; sourceTree = "<group>"; };
23E2E52E1D90382B006F38BB /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; }; 23E2E52E1D90382B006F38BB /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
23E2E5361D9048FB006F38BB /* CMakeLists.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
23E2E5371D9048FB006F38BB /* MinidumpParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MinidumpParser.cpp; sourceTree = "<group>"; }; 23E2E5371D9048FB006F38BB /* MinidumpParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MinidumpParser.cpp; sourceTree = "<group>"; };
23E2E5381D9048FB006F38BB /* MinidumpParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MinidumpParser.h; sourceTree = "<group>"; }; 23E2E5381D9048FB006F38BB /* MinidumpParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MinidumpParser.h; sourceTree = "<group>"; };
23E2E5391D9048FB006F38BB /* MinidumpTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MinidumpTypes.cpp; sourceTree = "<group>"; }; 23E2E5391D9048FB006F38BB /* MinidumpTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MinidumpTypes.cpp; sourceTree = "<group>"; };
@ -2531,10 +2531,6 @@
4C626533130F1B0A00C889F6 /* StreamTee.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StreamTee.h; path = include/lldb/Core/StreamTee.h; sourceTree = "<group>"; }; 4C626533130F1B0A00C889F6 /* StreamTee.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StreamTee.h; path = include/lldb/Core/StreamTee.h; sourceTree = "<group>"; };
4C66499F14EEE7F100B0316F /* StreamCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StreamCallback.h; path = include/lldb/Core/StreamCallback.h; sourceTree = "<group>"; }; 4C66499F14EEE7F100B0316F /* StreamCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StreamCallback.h; path = include/lldb/Core/StreamCallback.h; sourceTree = "<group>"; };
4C6649A214EEE81000B0316F /* StreamCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StreamCallback.cpp; path = source/Core/StreamCallback.cpp; sourceTree = "<group>"; }; 4C6649A214EEE81000B0316F /* StreamCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StreamCallback.cpp; path = source/Core/StreamCallback.cpp; sourceTree = "<group>"; };
4C6966071DA47BB4004FAE72 /* ThreadMinidump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadMinidump.h; sourceTree = "<group>"; };
4C6966081DA47BB4004FAE72 /* ThreadMinidump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadMinidump.cpp; sourceTree = "<group>"; };
4C6966091DA47BB4004FAE72 /* ProcessMinidump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProcessMinidump.h; sourceTree = "<group>"; };
4C69660A1DA47BB4004FAE72 /* ProcessMinidump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessMinidump.cpp; sourceTree = "<group>"; };
4C73152119B7D71700F865A4 /* Iterable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Iterable.h; path = include/lldb/Utility/Iterable.h; sourceTree = "<group>"; }; 4C73152119B7D71700F865A4 /* Iterable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Iterable.h; path = include/lldb/Utility/Iterable.h; sourceTree = "<group>"; };
4C7CF7E31295E10E00B4FBB5 /* ThreadPlanCallUserExpression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanCallUserExpression.h; path = include/lldb/Target/ThreadPlanCallUserExpression.h; sourceTree = "<group>"; }; 4C7CF7E31295E10E00B4FBB5 /* ThreadPlanCallUserExpression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanCallUserExpression.h; path = include/lldb/Target/ThreadPlanCallUserExpression.h; sourceTree = "<group>"; };
4C7CF7E51295E12B00B4FBB5 /* ThreadPlanCallUserExpression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanCallUserExpression.cpp; path = source/Target/ThreadPlanCallUserExpression.cpp; sourceTree = "<group>"; }; 4C7CF7E51295E12B00B4FBB5 /* ThreadPlanCallUserExpression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanCallUserExpression.cpp; path = source/Target/ThreadPlanCallUserExpression.cpp; sourceTree = "<group>"; };
@ -3542,12 +3538,9 @@
23E2E5351D9048E7006F38BB /* minidump */ = { 23E2E5351D9048E7006F38BB /* minidump */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4C6966071DA47BB4004FAE72 /* ThreadMinidump.h */,
4C6966081DA47BB4004FAE72 /* ThreadMinidump.cpp */,
4C6966091DA47BB4004FAE72 /* ProcessMinidump.h */,
4C69660A1DA47BB4004FAE72 /* ProcessMinidump.cpp */,
AFD65C7F1D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp */, AFD65C7F1D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp */,
AFD65C801D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.h */, AFD65C801D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.h */,
23E2E5361D9048FB006F38BB /* CMakeLists.txt */,
23E2E5371D9048FB006F38BB /* MinidumpParser.cpp */, 23E2E5371D9048FB006F38BB /* MinidumpParser.cpp */,
23E2E5381D9048FB006F38BB /* MinidumpParser.h */, 23E2E5381D9048FB006F38BB /* MinidumpParser.h */,
23E2E5391D9048FB006F38BB /* MinidumpTypes.cpp */, 23E2E5391D9048FB006F38BB /* MinidumpTypes.cpp */,
@ -6438,6 +6431,7 @@
4984BA181B979C08008658D4 /* ExpressionVariable.h in Headers */, 4984BA181B979C08008658D4 /* ExpressionVariable.h in Headers */,
26C7C4841BFFEA7E009BD01F /* WindowsMiniDump.h in Headers */, 26C7C4841BFFEA7E009BD01F /* WindowsMiniDump.h in Headers */,
30B38A001CAAA6D7009524E3 /* ClangUtil.h in Headers */, 30B38A001CAAA6D7009524E3 /* ClangUtil.h in Headers */,
AFD65C821D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.h in Headers */,
238F2BA11D2C835A001FF92A /* StructuredDataPlugin.h in Headers */, 238F2BA11D2C835A001FF92A /* StructuredDataPlugin.h in Headers */,
AF415AE81D949E4400FCE0D4 /* x86AssemblyInspectionEngine.h in Headers */, AF415AE81D949E4400FCE0D4 /* x86AssemblyInspectionEngine.h in Headers */,
AF8AD62F1BEC28A400150209 /* PlatformAppleTVSimulator.h in Headers */, AF8AD62F1BEC28A400150209 /* PlatformAppleTVSimulator.h in Headers */,
@ -7329,7 +7323,6 @@
268900CB13353E5F00698AC0 /* LogChannelDWARF.cpp in Sources */, 268900CB13353E5F00698AC0 /* LogChannelDWARF.cpp in Sources */,
268900CC13353E5F00698AC0 /* SymbolFileDWARFDebugMap.cpp in Sources */, 268900CC13353E5F00698AC0 /* SymbolFileDWARFDebugMap.cpp in Sources */,
268900CD13353E5F00698AC0 /* UniqueDWARFASTType.cpp in Sources */, 268900CD13353E5F00698AC0 /* UniqueDWARFASTType.cpp in Sources */,
4C6966101DA47BCE004FAE72 /* ThreadMinidump.cpp in Sources */,
944372DC171F6B4300E57C32 /* RegisterContextDummy.cpp in Sources */, 944372DC171F6B4300E57C32 /* RegisterContextDummy.cpp in Sources */,
4C88BC2D1BA391B000AA0964 /* UserExpression.cpp in Sources */, 4C88BC2D1BA391B000AA0964 /* UserExpression.cpp in Sources */,
49E4F66B1C9CAD16008487EA /* DiagnosticManager.cpp in Sources */, 49E4F66B1C9CAD16008487EA /* DiagnosticManager.cpp in Sources */,
@ -7589,7 +7582,6 @@
23D0658F1D4A7BEE0008EDE6 /* RenderScriptExpressionOpts.cpp in Sources */, 23D0658F1D4A7BEE0008EDE6 /* RenderScriptExpressionOpts.cpp in Sources */,
945215DF17F639EE00521C0B /* ValueObjectPrinter.cpp in Sources */, 945215DF17F639EE00521C0B /* ValueObjectPrinter.cpp in Sources */,
26EFB61B1BFE8D3E00544801 /* PlatformNetBSD.cpp in Sources */, 26EFB61B1BFE8D3E00544801 /* PlatformNetBSD.cpp in Sources */,
4C6966111DA47BDB004FAE72 /* ProcessMinidump.cpp in Sources */,
AFD65C811D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp in Sources */, AFD65C811D9B5B2E00D93120 /* RegisterContextMinidump_x86_64.cpp in Sources */,
260CC64815D0440D002BF2E0 /* OptionValueArgs.cpp in Sources */, 260CC64815D0440D002BF2E0 /* OptionValueArgs.cpp in Sources */,
260CC64915D0440D002BF2E0 /* OptionValueArray.cpp in Sources */, 260CC64915D0440D002BF2E0 /* OptionValueArray.cpp in Sources */,

View File

@ -1,6 +0,0 @@
LEVEL = ../../../make
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules

View File

@ -1,108 +0,0 @@
"""
Test basics of Minidump debugging.
"""
from __future__ import print_function
from six import iteritems
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class MiniDumpNewTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
NO_DEBUG_INFO_TESTCASE = True
@expectedFailureAll
def test_process_info_in_minidump(self):
"""Test that lldb can read the process information from the Minidump."""
# target create -c linux-x86_64.dmp
self.dbg.CreateTarget(None)
self.target = self.dbg.GetSelectedTarget()
self.process = self.target.LoadCore("linux-x86_64.dmp")
self.assertTrue(self.process, PROCESS_IS_VALID)
self.assertEqual(self.process.GetNumThreads(), 1)
self.assertEqual(self.process.GetProcessID(), 16001)
@expectedFailureAll
def test_thread_info_in_minidump(self):
"""Test that lldb can read the thread information from the Minidump."""
# target create -c linux-x86_64.dmp
self.dbg.CreateTarget(None)
self.target = self.dbg.GetSelectedTarget()
self.process = self.target.LoadCore("linux-x86_64.dmp")
# This process crashed due to a segmentation fault in its
# one and only thread.
self.assertEqual(self.process.GetNumThreads(), 1)
thread = self.process.GetThreadAtIndex(0)
self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal)
stop_description = thread.GetStopDescription(256)
self.assertTrue("SIGSEGV" in stop_description)
@expectedFailureAll
def test_stack_info_in_minidump(self):
"""Test that we can see a trivial stack in a breakpad-generated Minidump."""
# target create linux-x86_64 -c linux-x86_64.dmp
self.dbg.CreateTarget("linux-x86_64")
self.target = self.dbg.GetSelectedTarget()
self.process = self.target.LoadCore("linux-x86_64.dmp")
self.assertEqual(self.process.GetNumThreads(), 1)
thread = self.process.GetThreadAtIndex(0)
# frame #0: a.out`crash()
# frame #1: a.out`main()
# frame #2: libc-2.19.so`__libc_start_main()
# frame #3: a.out`_start
self.assertEqual(thread.GetNumFrames(), 4)
frame = thread.GetFrameAtIndex(0)
self.assertTrue(frame.IsValid())
pc = frame.GetPC()
eip = frame.FindRegister("pc")
self.assertTrue(eip.IsValid())
self.assertEqual(pc, eip.GetValueAsUnsigned())
@expectedFailureAll
def test_snapshot_minidump(self):
"""Test that if we load a snapshot minidump file (meaning the process did not crash) there is no stop reason."""
# target create -c linux-x86_64_not_crashed.dmp
self.dbg.CreateTarget(None)
self.target = self.dbg.GetSelectedTarget()
self.process = self.target.LoadCore("linux-x86_64_not_crashed.dmp")
self.assertEqual(self.process.GetNumThreads(), 1)
thread = self.process.GetThreadAtIndex(0)
self.assertEqual(thread.GetStopReason(), lldb.eStopReasonNone)
stop_description = thread.GetStopDescription(256)
self.assertEqual(stop_description, None)
@expectedFailureAll
def test_deeper_stack_in_minidump(self):
"""Test that we can examine a more interesting stack in a Minidump."""
# Launch with the Minidump, and inspect the stack.
# target create linux-x86_64_not_crashed -c linux-x86_64_not_crashed.dmp
target = self.dbg.CreateTarget("linux-x86_64_not_crashed")
process = target.LoadCore("linux-x86_64_not_crashed.dmp")
thread = process.GetThreadAtIndex(0)
expected_stack = {1: 'bar', 2: 'foo', 3: 'main'}
self.assertGreaterEqual(thread.GetNumFrames(), len(expected_stack))
for index, name in iteritems(expected_stack):
frame = thread.GetFrameAtIndex(index)
self.assertTrue(frame.IsValid())
function_name = frame.GetFunctionName()
self.assertTrue(name in function_name)
@expectedFailureAll
def test_local_variables_in_minidump(self):
"""Test that we can examine local variables in a Minidump."""
# Launch with the Minidump, and inspect a local variable.
# target create linux-x86_64_not_crashed -c linux-x86_64_not_crashed.dmp
target = self.dbg.CreateTarget("linux-x86_64_not_crashed")
process = target.LoadCore("linux-x86_64_not_crashed.dmp")
thread = process.GetThreadAtIndex(0)
frame = thread.GetFrameAtIndex(1)
value = frame.EvaluateExpression('x')
self.assertEqual(value.GetValueAsSigned(), 3)

View File

@ -1,28 +0,0 @@
// Example source from breakpad's linux tutorial
// https://chromium.googlesource.com/breakpad/breakpad/+/master/docs/linux_starter_guide.md
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include "client/linux/handler/exception_handler.h"
static bool dumpCallback(const google_breakpad::MinidumpDescriptor &descriptor,
void *context, bool succeeded) {
printf("Dump path: %s\n", descriptor.path());
return succeeded;
}
void crash() {
volatile int *a = (int *)(NULL);
*a = 1;
}
int main(int argc, char *argv[]) {
google_breakpad::MinidumpDescriptor descriptor("/tmp");
google_breakpad::ExceptionHandler eh(descriptor, NULL, dumpCallback, NULL,
true, -1);
printf("pid: %d\n", getpid());
crash();
return 0;
}

View File

@ -1,36 +0,0 @@
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include "client/linux/handler/exception_handler.h"
static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,
void* context, bool succeeded) {
printf("Dump path: %s\n", descriptor.path());
return succeeded;
}
int global = 42;
int
bar(int x, google_breakpad::ExceptionHandler &eh)
{
eh.WriteMinidump();
int y = 4*x + global;
return y;
}
int
foo(int x, google_breakpad::ExceptionHandler &eh)
{
int y = 2*bar(3*x, eh);
return y;
}
int main(int argc, char* argv[]) {
google_breakpad::MinidumpDescriptor descriptor("/tmp");
google_breakpad::ExceptionHandler eh(descriptor, NULL, dumpCallback, NULL, true, -1);
foo(1, eh);
return 0;
}

View File

@ -78,7 +78,6 @@
#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h" #include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h"
#include "Plugins/Process/elf-core/ProcessElfCore.h" #include "Plugins/Process/elf-core/ProcessElfCore.h"
#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h" #include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
#include "Plugins/Process/minidump/ProcessMinidump.h"
#include "Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h" #include "Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h"
@ -308,7 +307,6 @@ void SystemInitializerFull::Initialize() {
#if defined(_MSC_VER) #if defined(_MSC_VER)
ProcessWinMiniDump::Initialize(); ProcessWinMiniDump::Initialize();
#endif #endif
minidump::ProcessMinidump::Initialize();
MemoryHistoryASan::Initialize(); MemoryHistoryASan::Initialize();
AddressSanitizerRuntime::Initialize(); AddressSanitizerRuntime::Initialize();
ThreadSanitizerRuntime::Initialize(); ThreadSanitizerRuntime::Initialize();
@ -431,11 +429,9 @@ void SystemInitializerFull::Terminate() {
JITLoaderGDB::Terminate(); JITLoaderGDB::Terminate();
ProcessElfCore::Terminate(); ProcessElfCore::Terminate();
#if defined(_MSC_VER) #if defined(_MSC_VER)
ProcessWinMiniDump::Terminate(); ProcessWinMiniDump::Terminate();
#endif #endif
minidump::ProcessMinidump::Terminate();
MemoryHistoryASan::Terminate(); MemoryHistoryASan::Terminate();
AddressSanitizerRuntime::Terminate(); AddressSanitizerRuntime::Terminate();
ThreadSanitizerRuntime::Terminate(); ThreadSanitizerRuntime::Terminate();

View File

@ -4,6 +4,4 @@ add_lldb_library(lldbPluginProcessMinidump
MinidumpTypes.cpp MinidumpTypes.cpp
MinidumpParser.cpp MinidumpParser.cpp
RegisterContextMinidump_x86_64.cpp RegisterContextMinidump_x86_64.cpp
ThreadMinidump.cpp
ProcessMinidump.cpp
) )

View File

@ -1,11 +1,11 @@
//===-- MinidumpParser.cpp -------------------------------------*- C++ -*-===// //===-- MinidumpParser.cpp ---------------------------------------*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
// This file is distributed under the University of Illinois Open Source // This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===--------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Project includes // Project includes
#include "MinidumpParser.h" #include "MinidumpParser.h"
@ -65,7 +65,8 @@ MinidumpParser::MinidumpParser(
} }
llvm::ArrayRef<uint8_t> MinidumpParser::GetData() { llvm::ArrayRef<uint8_t> MinidumpParser::GetData() {
return m_data_sp->GetData(); return llvm::ArrayRef<uint8_t>(m_data_sp->GetBytes(),
m_data_sp->GetByteSize());
} }
llvm::ArrayRef<uint8_t> llvm::ArrayRef<uint8_t>
@ -75,14 +76,15 @@ MinidumpParser::GetStream(MinidumpStreamType stream_type) {
return {}; return {};
// check if there is enough data // check if there is enough data
if (iter->second.rva + iter->second.data_size > GetData().size()) if (iter->second.rva + iter->second.data_size > m_data_sp->GetByteSize())
return {}; return {};
return GetData().slice(iter->second.rva, iter->second.data_size); return llvm::ArrayRef<uint8_t>(m_data_sp->GetBytes() + iter->second.rva,
iter->second.data_size);
} }
llvm::Optional<std::string> MinidumpParser::GetMinidumpString(uint32_t rva) { llvm::Optional<std::string> MinidumpParser::GetMinidumpString(uint32_t rva) {
auto arr_ref = GetData(); auto arr_ref = m_data_sp->GetData();
if (rva > arr_ref.size()) if (rva > arr_ref.size())
return llvm::None; return llvm::None;
arr_ref = arr_ref.drop_front(rva); arr_ref = arr_ref.drop_front(rva);
@ -98,14 +100,6 @@ llvm::ArrayRef<MinidumpThread> MinidumpParser::GetThreads() {
return MinidumpThread::ParseThreadList(data); return MinidumpThread::ParseThreadList(data);
} }
llvm::ArrayRef<uint8_t>
MinidumpParser::GetThreadContext(const MinidumpThread &td) {
if (td.thread_context.rva + td.thread_context.data_size > GetData().size())
return llvm::None;
return GetData().slice(td.thread_context.rva, td.thread_context.data_size);
}
const MinidumpSystemInfo *MinidumpParser::GetSystemInfo() { const MinidumpSystemInfo *MinidumpParser::GetSystemInfo() {
llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::SystemInfo); llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::SystemInfo);
@ -230,33 +224,3 @@ const MinidumpExceptionStream *MinidumpParser::GetExceptionStream() {
return MinidumpExceptionStream::Parse(data); return MinidumpExceptionStream::Parse(data);
} }
llvm::Optional<Range> MinidumpParser::FindMemoryRange(lldb::addr_t addr) {
llvm::ArrayRef<uint8_t> data = GetStream(MinidumpStreamType::MemoryList);
if (data.size() == 0)
return llvm::None;
llvm::ArrayRef<MinidumpMemoryDescriptor> memory_list =
MinidumpMemoryDescriptor::ParseMemoryList(data);
if (memory_list.size() == 0)
return llvm::None;
for (auto memory_desc : memory_list) {
const MinidumpLocationDescriptor &loc_desc = memory_desc.memory;
const lldb::addr_t range_start = memory_desc.start_of_memory_range;
const size_t range_size = loc_desc.data_size;
if (loc_desc.rva + loc_desc.data_size > GetData().size())
return llvm::None;
if (range_start <= addr && addr < range_start + range_size) {
return Range(range_start, GetData().slice(loc_desc.rva, range_size));
}
}
// TODO parse Memory64List which is present in full-memory Minidumps
return llvm::None;
}

View File

@ -1,11 +1,12 @@
//===-- MinidumpParser.h ---------------------------------------*- C++ -*-===// //===-- MinidumpParser.h -----------------------------------------*- C++
//-*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
// This file is distributed under the University of Illinois Open Source // This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===--------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef liblldb_MinidumpParser_h_ #ifndef liblldb_MinidumpParser_h_
#define liblldb_MinidumpParser_h_ #define liblldb_MinidumpParser_h_
@ -24,22 +25,15 @@
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
// C includes // C includes
// C++ includes // C++ includes
#include <cstring>
#include <unordered_map>
namespace lldb_private { namespace lldb_private {
namespace minidump { namespace minidump {
// Describes a range of memory captured in the Minidump
struct Range {
lldb::addr_t start; // virtual address of the beginning of the range
// range_ref - absolute pointer to the first byte of the range and size
llvm::ArrayRef<uint8_t> range_ref;
Range(lldb::addr_t start, llvm::ArrayRef<uint8_t> range_ref)
: start(start), range_ref(range_ref) {}
};
class MinidumpParser { class MinidumpParser {
public: public:
static llvm::Optional<MinidumpParser> static llvm::Optional<MinidumpParser>
@ -53,8 +47,6 @@ public:
llvm::ArrayRef<MinidumpThread> GetThreads(); llvm::ArrayRef<MinidumpThread> GetThreads();
llvm::ArrayRef<uint8_t> GetThreadContext(const MinidumpThread &td);
const MinidumpSystemInfo *GetSystemInfo(); const MinidumpSystemInfo *GetSystemInfo();
ArchSpec GetArchitecture(); ArchSpec GetArchitecture();
@ -69,8 +61,6 @@ public:
const MinidumpExceptionStream *GetExceptionStream(); const MinidumpExceptionStream *GetExceptionStream();
llvm::Optional<Range> FindMemoryRange(lldb::addr_t addr);
private: private:
lldb::DataBufferSP m_data_sp; lldb::DataBufferSP m_data_sp;
const MinidumpHeader *m_header; const MinidumpHeader *m_header;

View File

@ -85,7 +85,7 @@ MinidumpThread::ParseThreadList(llvm::ArrayRef<uint8_t> &data) {
if (error.Fail() || *thread_count * sizeof(MinidumpThread) > data.size()) if (error.Fail() || *thread_count * sizeof(MinidumpThread) > data.size())
return {}; return {};
return llvm::makeArrayRef( return llvm::ArrayRef<MinidumpThread>(
reinterpret_cast<const MinidumpThread *>(data.data()), *thread_count); reinterpret_cast<const MinidumpThread *>(data.data()), *thread_count);
} }
@ -162,7 +162,7 @@ MinidumpModule::ParseModuleList(llvm::ArrayRef<uint8_t> &data) {
if (error.Fail() || *modules_count * sizeof(MinidumpModule) > data.size()) if (error.Fail() || *modules_count * sizeof(MinidumpModule) > data.size())
return {}; return {};
return llvm::makeArrayRef( return llvm::ArrayRef<MinidumpModule>(
reinterpret_cast<const MinidumpModule *>(data.data()), *modules_count); reinterpret_cast<const MinidumpModule *>(data.data()), *modules_count);
} }
@ -176,16 +176,3 @@ MinidumpExceptionStream::Parse(llvm::ArrayRef<uint8_t> &data) {
return exception_stream; return exception_stream;
} }
llvm::ArrayRef<MinidumpMemoryDescriptor>
MinidumpMemoryDescriptor::ParseMemoryList(llvm::ArrayRef<uint8_t> &data) {
const llvm::support::ulittle32_t *mem_ranges_count;
Error error = consumeObject(data, mem_ranges_count);
if (error.Fail() ||
*mem_ranges_count * sizeof(MinidumpMemoryDescriptor) > data.size())
return {};
return llvm::makeArrayRef(
reinterpret_cast<const MinidumpMemoryDescriptor *>(data.data()),
*mem_ranges_count);
}

View File

@ -207,9 +207,6 @@ static_assert(sizeof(MinidumpLocationDescriptor) == 8,
struct MinidumpMemoryDescriptor { struct MinidumpMemoryDescriptor {
llvm::support::ulittle64_t start_of_memory_range; llvm::support::ulittle64_t start_of_memory_range;
MinidumpLocationDescriptor memory; MinidumpLocationDescriptor memory;
static llvm::ArrayRef<MinidumpMemoryDescriptor>
ParseMemoryList(llvm::ArrayRef<uint8_t> &data);
}; };
static_assert(sizeof(MinidumpMemoryDescriptor) == 16, static_assert(sizeof(MinidumpMemoryDescriptor) == 16,
"sizeof MinidumpMemoryDescriptor is not correct!"); "sizeof MinidumpMemoryDescriptor is not correct!");
@ -365,8 +362,7 @@ static_assert(sizeof(MinidumpModule) == 108,
// Exception stuff // Exception stuff
struct MinidumpException { struct MinidumpException {
enum { enum {
ExceptonInfoMaxParams = 15, MaxParams = 15,
DumpRequested = 0xFFFFFFFF,
}; };
llvm::support::ulittle32_t exception_code; llvm::support::ulittle32_t exception_code;
@ -375,7 +371,7 @@ struct MinidumpException {
llvm::support::ulittle64_t exception_address; llvm::support::ulittle64_t exception_address;
llvm::support::ulittle32_t number_parameters; llvm::support::ulittle32_t number_parameters;
llvm::support::ulittle32_t unused_alignment; llvm::support::ulittle32_t unused_alignment;
llvm::support::ulittle64_t exception_information[ExceptonInfoMaxParams]; llvm::support::ulittle64_t exception_information[MaxParams];
}; };
static_assert(sizeof(MinidumpException) == 152, static_assert(sizeof(MinidumpException) == 152,
"sizeof MinidumpException is not correct!"); "sizeof MinidumpException is not correct!");

View File

@ -1,263 +0,0 @@
//===-- ProcessMinidump.cpp -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Project includes
#include "ProcessMinidump.h"
#include "ThreadMinidump.h"
// Other libraries and framework includes
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/State.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/LLDBAssert.h"
// C includes
// C++ includes
using namespace lldb_private;
using namespace minidump;
ConstString ProcessMinidump::GetPluginNameStatic() {
static ConstString g_name("minidump");
return g_name;
}
const char *ProcessMinidump::GetPluginDescriptionStatic() {
return "Minidump plug-in.";
}
lldb::ProcessSP ProcessMinidump::CreateInstance(lldb::TargetSP target_sp,
lldb::ListenerSP listener_sp,
const FileSpec *crash_file) {
if (!crash_file)
return nullptr;
lldb::ProcessSP process_sp;
// Read enough data for the Minidump header
const size_t header_size = sizeof(MinidumpHeader);
lldb::DataBufferSP data_sp(crash_file->MemoryMapFileContents(0, header_size));
// The memory map can fail
if (!data_sp)
return nullptr;
// first, only try to parse the header, beacuse we need to be fast
llvm::ArrayRef<uint8_t> header_data(data_sp->GetBytes(), header_size);
const MinidumpHeader *header = MinidumpHeader::Parse(header_data);
if (data_sp->GetByteSize() != header_size || header == nullptr)
return nullptr;
lldb::DataBufferSP all_data_sp(crash_file->MemoryMapFileContents());
auto minidump_parser = MinidumpParser::Create(all_data_sp);
// check if the parser object is valid
// skip if the Minidump file is Windows generated, because we are still
// work-in-progress
if (!minidump_parser ||
minidump_parser->GetArchitecture().GetTriple().getOS() ==
llvm::Triple::OSType::Win32)
return nullptr;
return lldb::ProcessSP(new ProcessMinidump(
target_sp, listener_sp, *crash_file, minidump_parser.getValue()));
}
// TODO leave it to be only "return true" ?
bool ProcessMinidump::CanDebug(lldb::TargetSP target_sp,
bool plugin_specified_by_name) {
return true;
}
ProcessMinidump::ProcessMinidump(lldb::TargetSP target_sp,
lldb::ListenerSP listener_sp,
const FileSpec &core_file,
MinidumpParser minidump_parser)
: Process(target_sp, listener_sp), m_minidump_parser(minidump_parser),
m_core_file(core_file) {}
ProcessMinidump::~ProcessMinidump() {
Clear();
// We need to call finalize on the process before destroying ourselves
// to make sure all of the broadcaster cleanup goes as planned. If we
// destruct this class, then Process::~Process() might have problems
// trying to fully destroy the broadcaster.
Finalize();
}
void ProcessMinidump::Initialize() {
static std::once_flag g_once_flag;
std::call_once(g_once_flag, []() {
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(),
ProcessMinidump::CreateInstance);
});
}
void ProcessMinidump::Terminate() {
PluginManager::UnregisterPlugin(ProcessMinidump::CreateInstance);
}
Error ProcessMinidump::DoLoadCore() {
Error error;
m_thread_list = m_minidump_parser.GetThreads();
m_active_exception = m_minidump_parser.GetExceptionStream();
GetTarget().SetArchitecture(GetArchitecture());
ReadModuleList();
llvm::Optional<lldb::pid_t> pid = m_minidump_parser.GetPid();
if (!pid) {
error.SetErrorString("failed to parse PID");
return error;
}
SetID(pid.getValue());
return error;
}
DynamicLoader *ProcessMinidump::GetDynamicLoader() {
if (m_dyld_ap.get() == nullptr)
m_dyld_ap.reset(DynamicLoader::FindPlugin(this, nullptr));
return m_dyld_ap.get();
}
ConstString ProcessMinidump::GetPluginName() { return GetPluginNameStatic(); }
uint32_t ProcessMinidump::GetPluginVersion() { return 1; }
Error ProcessMinidump::DoDestroy() { return Error(); }
void ProcessMinidump::RefreshStateAfterStop() {
if (!m_active_exception)
return;
if (m_active_exception->exception_record.exception_code ==
MinidumpException::DumpRequested) {
return;
}
lldb::StopInfoSP stop_info;
lldb::ThreadSP stop_thread;
Process::m_thread_list.SetSelectedThreadByID(m_active_exception->thread_id);
stop_thread = Process::m_thread_list.GetSelectedThread();
ArchSpec arch = GetArchitecture();
if (arch.GetTriple().getOS() == llvm::Triple::Linux) {
stop_info = StopInfo::CreateStopReasonWithSignal(
*stop_thread, m_active_exception->exception_record.exception_code);
} else {
std::string desc;
llvm::raw_string_ostream desc_stream(desc);
desc_stream << "Exception "
<< llvm::format_hex(
m_active_exception->exception_record.exception_code, 8)
<< " encountered at address "
<< llvm::format_hex(
m_active_exception->exception_record.exception_address,
8);
stop_info = StopInfo::CreateStopReasonWithException(
*stop_thread, desc_stream.str().c_str());
}
stop_thread->SetStopInfo(stop_info);
}
bool ProcessMinidump::IsAlive() { return true; }
bool ProcessMinidump::WarnBeforeDetach() const { return false; }
size_t ProcessMinidump::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
lldb_private::Error &error) {
// Don't allow the caching that lldb_private::Process::ReadMemory does
// since we have it all cached in our dump file anyway.
return DoReadMemory(addr, buf, size, error);
}
size_t ProcessMinidump::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
lldb_private::Error &error) {
// I don't have a sense of how frequently this is called or how many memory
// ranges a Minidump typically has, so I'm not sure if searching for the
// appropriate range linearly each time is stupid. Perhaps we should build
// an index for faster lookups.
llvm::Optional<Range> range = m_minidump_parser.FindMemoryRange(addr);
if (!range)
return 0;
// There's at least some overlap between the beginning of the desired range
// (addr) and the current range. Figure out where the overlap begins and
// how much overlap there is, then copy it to the destination buffer.
lldbassert(range->start <= addr);
const size_t offset = addr - range->start;
lldbassert(offset < range->range_ref.size());
const size_t overlap = std::min(size, range->range_ref.size() - offset);
std::memcpy(buf, range->range_ref.data() + offset, overlap);
return overlap;
}
ArchSpec ProcessMinidump::GetArchitecture() {
return m_minidump_parser.GetArchitecture();
}
// TODO - parse the MemoryInfoListStream and implement this method
Error ProcessMinidump::GetMemoryRegionInfo(
lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &range_info) {
return {};
}
void ProcessMinidump::Clear() { Process::m_thread_list.Clear(); }
bool ProcessMinidump::UpdateThreadList(
lldb_private::ThreadList &old_thread_list,
lldb_private::ThreadList &new_thread_list) {
uint32_t num_threads = 0;
if (m_thread_list.size() > 0)
num_threads = m_thread_list.size();
for (lldb::tid_t tid = 0; tid < num_threads; ++tid) {
lldb::ThreadSP thread_sp(new ThreadMinidump(
*this, m_thread_list[tid],
m_minidump_parser.GetThreadContext(m_thread_list[tid])));
new_thread_list.AddThread(thread_sp);
}
return new_thread_list.GetSize(false) > 0;
}
void ProcessMinidump::ReadModuleList() {
llvm::ArrayRef<MinidumpModule> modules = m_minidump_parser.GetModuleList();
for (auto module : modules) {
llvm::Optional<std::string> name =
m_minidump_parser.GetMinidumpString(module.module_name_rva);
if (!name)
continue;
const auto file_spec = FileSpec(name.getValue(), true);
ModuleSpec module_spec = file_spec;
Error error;
lldb::ModuleSP module_sp =
this->GetTarget().GetSharedModule(module_spec, &error);
if (!module_sp || error.Fail()) {
continue;
}
bool load_addr_changed = false;
module_sp->SetLoadAddress(this->GetTarget(), module.base_of_image, false,
load_addr_changed);
}
}

View File

@ -1,103 +0,0 @@
//===-- ProcessMinidump.h ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef liblldb_ProcessMinidump_h_
#define liblldb_ProcessMinidump_h_
// Project includes
#include "MinidumpParser.h"
#include "MinidumpTypes.h"
// Other libraries and framework includes
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
// C Includes
// C++ Includes
namespace lldb_private {
namespace minidump {
class ProcessMinidump : public Process {
public:
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
lldb::ListenerSP listener_sp,
const FileSpec *crash_file_path);
static void Initialize();
static void Terminate();
static ConstString GetPluginNameStatic();
static const char *GetPluginDescriptionStatic();
ProcessMinidump(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
const lldb_private::FileSpec &core_file,
MinidumpParser minidump_parser);
~ProcessMinidump() override;
bool CanDebug(lldb::TargetSP target_sp,
bool plugin_specified_by_name) override;
Error DoLoadCore() override;
DynamicLoader *GetDynamicLoader() override;
ConstString GetPluginName() override;
uint32_t GetPluginVersion() override;
Error DoDestroy() override;
void RefreshStateAfterStop() override;
bool IsAlive() override;
bool WarnBeforeDetach() const override;
size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size,
Error &error) override;
size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
Error &error) override;
ArchSpec GetArchitecture();
Error GetMemoryRegionInfo(lldb::addr_t load_addr,
MemoryRegionInfo &range_info) override;
MinidumpParser m_minidump_parser;
protected:
void Clear();
bool UpdateThreadList(ThreadList &old_thread_list,
ThreadList &new_thread_list) override;
void ReadModuleList();
private:
FileSpec m_core_file;
llvm::ArrayRef<MinidumpThread> m_thread_list;
const MinidumpExceptionStream *m_active_exception;
};
} // namespace minidump
} // namespace lldb_private
#endif // liblldb_ProcessMinidump_h_

View File

@ -1,102 +0,0 @@
//===-- ThreadMinidump.cpp --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Project includes
#include "ThreadMinidump.h"
#include "ProcessMinidump.h"
#include "RegisterContextMinidump_x86_64.h"
// Other libraries and framework includes
#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
#include "Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Log.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Unwind.h"
// C Includes
// C++ Includes
using namespace lldb;
using namespace lldb_private;
using namespace minidump;
ThreadMinidump::ThreadMinidump(Process &process, const MinidumpThread &td,
llvm::ArrayRef<uint8_t> gpregset_data)
: Thread(process, td.thread_id), m_thread_reg_ctx_sp(),
m_gpregset_data(gpregset_data) {}
ThreadMinidump::~ThreadMinidump() {}
void ThreadMinidump::RefreshStateAfterStop() {}
void ThreadMinidump::ClearStackFrames() {}
RegisterContextSP ThreadMinidump::GetRegisterContext() {
if (!m_reg_context_sp) {
m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
}
return m_reg_context_sp;
}
RegisterContextSP
ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) {
RegisterContextSP reg_ctx_sp;
uint32_t concrete_frame_idx = 0;
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
if (frame)
concrete_frame_idx = frame->GetConcreteFrameIndex();
if (concrete_frame_idx == 0) {
if (m_thread_reg_ctx_sp)
return m_thread_reg_ctx_sp;
ProcessMinidump *process =
static_cast<ProcessMinidump *>(GetProcess().get());
ArchSpec arch = process->GetArchitecture();
RegisterInfoInterface *reg_interface = nullptr;
// TODO write other register contexts and add them here
switch (arch.GetMachine()) {
case llvm::Triple::x86_64: {
reg_interface = new RegisterContextLinux_x86_64(arch);
lldb::DataBufferSP buf =
ConvertMinidumpContextToRegIface(m_gpregset_data, reg_interface);
DataExtractor gpregs(buf, lldb::eByteOrderLittle, 8);
DataExtractor fpregs;
m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
*this, reg_interface, gpregs, fpregs));
break;
}
default:
break;
}
if (!reg_interface) {
if (log)
log->Printf("elf-core::%s:: Architecture(%d) not supported",
__FUNCTION__, arch.GetMachine());
assert(false && "Architecture not supported");
}
reg_ctx_sp = m_thread_reg_ctx_sp;
} else if (m_unwinder_ap) {
reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame(frame);
}
return reg_ctx_sp;
}
bool ThreadMinidump::CalculateStopInfo() { return false; }

View File

@ -1,52 +0,0 @@
//===-- ThreadMinidump.h ---------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef liblldb_ThreadMinidump_h_
#define liblldb_ThreadMinidump_h_
// Project includes
#include "MinidumpTypes.h"
// Other libraries and framework includes
#include "lldb/Target/Thread.h"
// C Includes
// C++ Includes
namespace lldb_private {
namespace minidump {
class ThreadMinidump : public Thread {
public:
ThreadMinidump(Process &process, const MinidumpThread &td,
llvm::ArrayRef<uint8_t> gpregset_data);
~ThreadMinidump() override;
void RefreshStateAfterStop() override;
lldb::RegisterContextSP GetRegisterContext() override;
lldb::RegisterContextSP
CreateRegisterContextForFrame(StackFrame *frame) override;
void ClearStackFrames() override;
protected:
lldb::RegisterContextSP m_thread_reg_ctx_sp;
llvm::ArrayRef<uint8_t> m_gpregset_data;
bool CalculateStopInfo() override;
};
} // namespace minidump
} // namespace lldb_private
#endif // liblldb_ThreadMinidump_h_

View File

@ -60,7 +60,7 @@ public:
std::unique_ptr<MinidumpParser> parser; std::unique_ptr<MinidumpParser> parser;
}; };
TEST_F(MinidumpParserTest, GetThreadsAndGetThreadContext) { TEST_F(MinidumpParserTest, GetThreads) {
SetUpData("linux-x86_64.dmp"); SetUpData("linux-x86_64.dmp");
llvm::ArrayRef<MinidumpThread> thread_list; llvm::ArrayRef<MinidumpThread> thread_list;
@ -68,10 +68,7 @@ TEST_F(MinidumpParserTest, GetThreadsAndGetThreadContext) {
ASSERT_EQ(1UL, thread_list.size()); ASSERT_EQ(1UL, thread_list.size());
const MinidumpThread thread = thread_list[0]; const MinidumpThread thread = thread_list[0];
EXPECT_EQ(16001UL, thread.thread_id); ASSERT_EQ(16001UL, thread.thread_id);
llvm::ArrayRef<uint8_t> context = parser->GetThreadContext(thread);
EXPECT_EQ(1232, context.size());
} }
TEST_F(MinidumpParserTest, GetThreadsTruncatedFile) { TEST_F(MinidumpParserTest, GetThreadsTruncatedFile) {
@ -142,24 +139,6 @@ TEST_F(MinidumpParserTest, GetExceptionStream) {
ASSERT_EQ(11UL, exception_stream->exception_record.exception_code); ASSERT_EQ(11UL, exception_stream->exception_record.exception_code);
} }
TEST_F(MinidumpParserTest, GetMemoryRange) {
SetUpData("linux-x86_64.dmp");
// There are two memory ranges in the file (size is in bytes, decimal):
// 1) 0x7ffceb34a000 12288
// 2) 0x401d46 256
EXPECT_TRUE(parser->FindMemoryRange(0x7ffceb34a000).hasValue());
EXPECT_TRUE(parser->FindMemoryRange(0x7ffceb34a000 + 12288 / 2).hasValue());
EXPECT_TRUE(parser->FindMemoryRange(0x7ffceb34a000 + 12288 - 1).hasValue());
EXPECT_FALSE(parser->FindMemoryRange(0x7ffceb34a000 + 12288).hasValue());
EXPECT_TRUE(parser->FindMemoryRange(0x401d46).hasValue());
EXPECT_TRUE(parser->FindMemoryRange(0x401d46 + 256 / 2).hasValue());
EXPECT_TRUE(parser->FindMemoryRange(0x401d46 + 256 - 1).hasValue());
EXPECT_FALSE(parser->FindMemoryRange(0x401d46 + 256).hasValue());
EXPECT_FALSE(parser->FindMemoryRange(0x2a).hasValue());
}
// Windows Minidump tests // Windows Minidump tests
// fizzbuzz_no_heap.dmp is copied from the WinMiniDump tests // fizzbuzz_no_heap.dmp is copied from the WinMiniDump tests
TEST_F(MinidumpParserTest, GetArchitectureWindows) { TEST_F(MinidumpParserTest, GetArchitectureWindows) {
@ -193,6 +172,7 @@ TEST_F(MinidumpParserTest, GetPidWindows) {
} }
// Register stuff // Register stuff
// TODO probably split register stuff tests into different file?
#define REG_VAL(x) *(reinterpret_cast<uint64_t *>(x)) #define REG_VAL(x) *(reinterpret_cast<uint64_t *>(x))
TEST_F(MinidumpParserTest, ConvertRegisterContext) { TEST_F(MinidumpParserTest, ConvertRegisterContext) {