Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Get register context for the 32-bit process in a WoW64 process minidump
32-bit processes on 64-bit Windows run in a layer called WoW64 (Windows-on-Windows64). If you capture a mini dump of such a process from a 32-bit debugger, you end up with a register context for the 64-bit WoW64 process rather than the 32-bit one you probably care about. This detects WoW64 by looking to see if there's a module named wow64.dll loaded. For such processes, it then looks in the 64-bit Thread Environment Block (TEB) to locate a copy of the 32-bit CONTEXT record that the plugin needs for the register context. Added some rudimentary tests. I'd like to improve these later once we figure out how to get the exception information from these mini dumps. Differential Revision: http://reviews.llvm.org/D17465 llvm-svn: 261808
- Loading branch information
1 parent
ce16649
commit 0a75082
Showing
5 changed files
with
200 additions
and
8 deletions.
There are no files selected for viewing
76 changes: 76 additions & 0 deletions
76
...ages/Python/lldbsuite/test/functionalities/postmortem/wow64_minidump/TestWow64MiniDump.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
""" | ||
Test basics of a mini dump taken of a 32-bit process running in WoW64 | ||
WoW64 is the subsystem that lets 32-bit processes run in 64-bit Windows. If you | ||
capture a mini dump of a process running under WoW64 with a 64-bit debugger, you | ||
end up with a dump of the WoW64 layer. In that case, LLDB must do extra work to | ||
get the 32-bit register contexts. | ||
""" | ||
|
||
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 Wow64MiniDumpTestCase(TestBase): | ||
|
||
mydir = TestBase.compute_mydir(__file__) | ||
|
||
@skipUnlessWindows # for now mini-dump debugging is limited to Windows hosts | ||
@no_debug_info_test | ||
def test_wow64_mini_dump(self): | ||
"""Test that lldb can read the process information from the minidump.""" | ||
# target create -c fizzbuzz_wow64.dmp | ||
target = self.dbg.CreateTarget("") | ||
process = target.LoadCore("fizzbuzz_wow64.dmp") | ||
self.assertTrue(process, PROCESS_IS_VALID) | ||
self.assertEqual(process.GetNumThreads(), 1) | ||
self.assertEqual(process.GetProcessID(), 0x1E9C) | ||
|
||
@skipUnlessWindows # for now mini-dump debugging is limited to Windows hosts | ||
@no_debug_info_test | ||
def test_thread_info_in_wow64_mini_dump(self): | ||
"""Test that lldb can read the thread information from the minidump.""" | ||
# target create -c fizzbuzz_wow64.dmp | ||
target = self.dbg.CreateTarget("") | ||
process = target.LoadCore("fizzbuzz_wow64.dmp") | ||
# This process crashed due to an access violation (0xc0000005), but the | ||
# minidump doesn't have an exception record--perhaps the crash handler | ||
# ate it. | ||
# TODO: See if we can recover the exception information from the TEB, | ||
# which, according to Windbg, has a pointer to an exception list. | ||
|
||
# In the dump, none of the threads are stopped, so we cannot use | ||
# lldbutil.get_stopped_thread. | ||
thread = process.GetThreadAtIndex(0) | ||
self.assertEqual(thread.GetStopReason(), lldb.eStopReasonNone) | ||
|
||
@skipUnlessWindows # for now mini-dump debugging is limited to Windows hosts | ||
@no_debug_info_test | ||
def test_stack_info_in_wow64_mini_dump(self): | ||
"""Test that we can see a trivial stack in a VS-generate mini dump.""" | ||
# target create -c fizzbuzz_no_heap.dmp | ||
target = self.dbg.CreateTarget("") | ||
process = target.LoadCore("fizzbuzz_wow64.dmp") | ||
self.assertGreaterEqual(process.GetNumThreads(), 1) | ||
# This process crashed due to an access violation (0xc0000005), but the | ||
# minidump doesn't have an exception record--perhaps the crash handler | ||
# ate it. | ||
# TODO: See if we can recover the exception information from the TEB, | ||
# which, according to Windbg, has a pointer to an exception list. | ||
|
||
# In the dump, none of the threads are stopped, so we cannot use | ||
# lldbutil.get_stopped_thread. | ||
thread = process.GetThreadAtIndex(0) | ||
# The crash is in main, so there should be at least one frame on the stack. | ||
self.assertGreaterEqual(thread.GetNumFrames(), 1) | ||
frame = thread.GetFrameAtIndex(0) | ||
self.assertTrue(frame.IsValid()) | ||
pc = frame.GetPC() | ||
eip = frame.FindRegister("pc") | ||
self.assertTrue(eip.IsValid()) | ||
self.assertEqual(pc, eip.GetValueAsUnsigned()) |
31 changes: 31 additions & 0 deletions
31
lldb/packages/Python/lldbsuite/test/functionalities/postmortem/wow64_minidump/fizzbuzz.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// A sample program for getting minidumps on Windows. | ||
|
||
#include <iostream> | ||
|
||
bool | ||
fizz(int x) | ||
{ | ||
return x % 3 == 0; | ||
} | ||
|
||
bool | ||
buzz(int x) | ||
{ | ||
return x % 5 == 0; | ||
} | ||
|
||
int | ||
main() | ||
{ | ||
int *buggy = 0; | ||
|
||
for (int i = 1; i <= 100; ++i) | ||
{ | ||
if (fizz(i)) std::cout << "fizz"; | ||
if (buzz(i)) std::cout << "buzz"; | ||
if (!fizz(i) && !buzz(i)) std::cout << i; | ||
std::cout << '\n'; | ||
} | ||
|
||
return *buggy; | ||
} |
Binary file added
BIN
+8.85 MB
...ckages/Python/lldbsuite/test/functionalities/postmortem/wow64_minidump/fizzbuzz_wow64.dmp
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
//===-- NtStructures.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_Plugins_Process_Windows_Common_NtStructures_h_ | ||
#define liblldb_Plugins_Process_Windows_Common_NtStructures_h_ | ||
|
||
#include "lldb/Host/windows/windows.h" | ||
|
||
// This describes the layout of a TEB (Thread Environment Block) for a 64-bit | ||
// process. It's adapted from the 32-bit TEB in winternl.h. Currently, we care | ||
// only about the position of the TlsSlots. | ||
struct TEB64 | ||
{ | ||
ULONG64 Reserved1[12]; | ||
ULONG64 ProcessEnvironmentBlock; | ||
ULONG64 Reserved2[399]; | ||
BYTE Reserved3[1952]; | ||
ULONG64 TlsSlots[64]; | ||
BYTE Reserved4[8]; | ||
ULONG64 Reserved5[26]; | ||
ULONG64 ReservedForOle; // Windows 2000 only | ||
ULONG64 Reserved6[4]; | ||
ULONG64 TlsExpansionSlots; | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters