diff options
Diffstat (limited to 'lldb/packages/Python/lldbsuite')
11 files changed, 316 insertions, 0 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/1lwp_SIGSEGV.amd64 b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/1lwp_SIGSEGV.amd64 Binary files differnew file mode 100755 index 00000000000..56fa077bd6a --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/1lwp_SIGSEGV.amd64 diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/1lwp_SIGSEGV.amd64.core b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/1lwp_SIGSEGV.amd64.core Binary files differnew file mode 100644 index 00000000000..d2d40500455 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/1lwp_SIGSEGV.amd64.core diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/1lwp_SIGSEGV.c b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/1lwp_SIGSEGV.c new file mode 100644 index 00000000000..972e9678af5 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/1lwp_SIGSEGV.c @@ -0,0 +1,14 @@ +static void bar(char *boom) { + char F = 'b'; + *boom = 47; // Frame bar +} + +static void foo(char *boom, void (*boomer)(char *)) { + char F = 'f'; + boomer(boom); // Frame foo +} + +void main(void) { + char F = 'm'; + foo(0, bar); // Frame main +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_process_SIGSEGV.amd64 b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_process_SIGSEGV.amd64 Binary files differnew file mode 100755 index 00000000000..00f61dfce84 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_process_SIGSEGV.amd64 diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_process_SIGSEGV.amd64.core b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_process_SIGSEGV.amd64.core Binary files differnew file mode 100644 index 00000000000..f9c2b562fba --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_process_SIGSEGV.amd64.core diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_process_SIGSEGV.c b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_process_SIGSEGV.c new file mode 100644 index 00000000000..ce583aaada9 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_process_SIGSEGV.c @@ -0,0 +1,32 @@ +#include <lwp.h> +#include <stddef.h> +#include <stdlib.h> +#include <unistd.h> +#include <signal.h> + +static void bar() { + char F = 'b'; + kill(getpid(), SIGSEGV); // Frame bar +} + +static void foo(void (*boomer)()) { + char F = 'f'; + boomer(); // Frame foo +} + +static void lwp_main(void *unused) { + char F = 'l'; + foo(bar); // Frame lwp_main +} + +int main(int argc, char **argv) { + ucontext_t uc; + lwpid_t lid; + static const size_t ssize = 16 * 1024; + void *stack; + + stack = malloc(ssize); + _lwp_makecontext(&uc, lwp_main, NULL, NULL, stack, ssize); + _lwp_create(&uc, 0, &lid); + _lwp_wait(lid, NULL); +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_t2_SIGSEGV.amd64 b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_t2_SIGSEGV.amd64 Binary files differnew file mode 100755 index 00000000000..d304de160f0 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_t2_SIGSEGV.amd64 diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_t2_SIGSEGV.amd64.core b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_t2_SIGSEGV.amd64.core Binary files differnew file mode 100644 index 00000000000..5f68687c56e --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_t2_SIGSEGV.amd64.core diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_t2_SIGSEGV.c b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_t2_SIGSEGV.c new file mode 100644 index 00000000000..1cd86631edd --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_t2_SIGSEGV.c @@ -0,0 +1,30 @@ +#include <lwp.h> +#include <stddef.h> +#include <stdlib.h> + +static void bar(char *boom) { + char F = 'b'; + *boom = 47; // Frame bar +} + +static void foo(char *boom, void (*boomer)(char *)) { + char F = 'f'; + boomer(boom); // Frame foo +} + +void lwp_main(void *unused) { + char F = 'l'; + foo(0, bar); // Frame lwp_main +} + +int main(int argc, char **argv) { + ucontext_t uc; + lwpid_t lid; + static const size_t ssize = 16 * 1024; + void *stack; + + stack = malloc(ssize); + _lwp_makecontext(&uc, lwp_main, NULL, NULL, stack, ssize); + _lwp_create(&uc, 0, &lid); + _lwp_wait(lid, NULL); +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/GNUmakefile b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/GNUmakefile new file mode 100644 index 00000000000..62c719d3d2f --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/GNUmakefile @@ -0,0 +1,15 @@ +ARCH = $(shell uname -m) +PROGRAMS = 1lwp_SIGSEGV 2lwp_t2_SIGSEGV 2lwp_process_SIGSEGV +EXECS = $(patsubst %,%.$(ARCH),$(PROGRAMS)) +CORES = $(patsubst %,%.core,$(EXECS)) + +all: $(CORES) $(EXECS) +clean: + rm -f $(CORES) $(EXECS) + +%.core: % + sysctl -w proc.$$$$.corename=$@; ulimit -s 16; ! ./$< +%.$(ARCH): %.c + $(CC) -o $@ -g $< + +.PHONY: all clean diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/TestNetBSDCore.py b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/TestNetBSDCore.py new file mode 100644 index 00000000000..ca234ecc1f6 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/TestNetBSDCore.py @@ -0,0 +1,225 @@ +""" +Test NetBSD core file debugging. +""" + +from __future__ import division, print_function + +import shutil +import signal +import struct +import os + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class NetBSDCoreCommonTestCase(TestBase): + NO_DEBUG_INFO_TESTCASE = True + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + super(NetBSDCoreCommonTestCase, self).setUp() + self._initial_platform = lldb.DBG.GetSelectedPlatform() + + def tearDown(self): + lldb.DBG.SetSelectedPlatform(self._initial_platform) + super(NetBSDCoreCommonTestCase, self).tearDown() + + def check_memory_regions(self, process, region_count): + region_list = process.GetMemoryRegions() + self.assertEqual(region_list.GetSize(), region_count) + + region = lldb.SBMemoryRegionInfo() + + # Check we have the right number of regions. + self.assertEqual(region_list.GetSize(), region_count) + + # Check that getting a region beyond the last in the list fails. + self.assertFalse( + region_list.GetMemoryRegionAtIndex( + region_count, region)) + + # Check each region is valid. + for i in range(region_list.GetSize()): + # Check we can actually get this region. + self.assertTrue(region_list.GetMemoryRegionAtIndex(i, region)) + + # Every region in the list should be mapped. + self.assertTrue(region.IsMapped()) + + # Test the address at the start of a region returns it's enclosing + # region. + begin_address = region.GetRegionBase() + region_at_begin = lldb.SBMemoryRegionInfo() + error = process.GetMemoryRegionInfo(begin_address, region_at_begin) + self.assertEqual(region, region_at_begin) + + # Test an address in the middle of a region returns it's enclosing + # region. + middle_address = (region.GetRegionBase() + + region.GetRegionEnd()) // 2 + region_at_middle = lldb.SBMemoryRegionInfo() + error = process.GetMemoryRegionInfo( + middle_address, region_at_middle) + self.assertEqual(region, region_at_middle) + + # Test the address at the end of a region returns it's enclosing + # region. + end_address = region.GetRegionEnd() - 1 + region_at_end = lldb.SBMemoryRegionInfo() + error = process.GetMemoryRegionInfo(end_address, region_at_end) + self.assertEqual(region, region_at_end) + + # Check that quering the end address does not return this region but + # the next one. + next_region = lldb.SBMemoryRegionInfo() + error = process.GetMemoryRegionInfo( + region.GetRegionEnd(), next_region) + self.assertNotEqual(region, next_region) + self.assertEqual( + region.GetRegionEnd(), + next_region.GetRegionBase()) + + # Check that query beyond the last region returns an unmapped region + # that ends at LLDB_INVALID_ADDRESS + last_region = lldb.SBMemoryRegionInfo() + region_list.GetMemoryRegionAtIndex(region_count - 1, last_region) + end_region = lldb.SBMemoryRegionInfo() + error = process.GetMemoryRegionInfo( + last_region.GetRegionEnd(), end_region) + self.assertFalse(end_region.IsMapped()) + self.assertEqual( + last_region.GetRegionEnd(), + end_region.GetRegionBase()) + self.assertEqual(end_region.GetRegionEnd(), lldb.LLDB_INVALID_ADDRESS) + + def check_state(self, process): + with open(os.devnull) as devnul: + # sanitize test output + self.dbg.SetOutputFileHandle(devnul, False) + self.dbg.SetErrorFileHandle(devnul, False) + + self.assertTrue(process.is_stopped) + + # Process.Continue + error = process.Continue() + self.assertFalse(error.Success()) + self.assertTrue(process.is_stopped) + + # Thread.StepOut + thread = process.GetSelectedThread() + thread.StepOut() + self.assertTrue(process.is_stopped) + + # command line + self.dbg.HandleCommand('s') + self.assertTrue(process.is_stopped) + self.dbg.HandleCommand('c') + self.assertTrue(process.is_stopped) + + # restore file handles + self.dbg.SetOutputFileHandle(None, False) + self.dbg.SetErrorFileHandle(None, False) + + def check_backtrace(self, thread, filename, backtrace): + self.assertGreaterEqual(thread.GetNumFrames(), len(backtrace)) + src = filename.rpartition('.')[0] + '.c' + for i in range(len(backtrace)): + frame = thread.GetFrameAtIndex(i) + self.assertTrue(frame) + self.assertEqual(frame.GetFunctionName(), backtrace[i]) + if not backtrace[i].startswith('_'): + self.assertEqual(frame.GetLineEntry().GetLine(), + line_number(src, "Frame " + backtrace[i])) + self.assertEqual( + frame.FindVariable("F").GetValueAsUnsigned(), ord( + backtrace[i][0])) + + def do_test(self, filename, pid, region_count): + target = self.dbg.CreateTarget(filename) + process = target.LoadCore(filename + ".core") + + self.assertTrue(process, PROCESS_IS_VALID) + self.assertEqual(process.GetNumThreads(), self.THREAD_COUNT) + self.assertEqual(process.GetProcessID(), pid) + + self.check_state(process) + + self.check_stack(process, pid, filename) + + self.check_memory_regions(process, region_count) + + self.dbg.DeleteTarget(target) + + +class NetBSD1LWPCoreTestCase(NetBSDCoreCommonTestCase): + THREAD_COUNT = 1 + + def check_stack(self, process, pid, filename): + thread = process.GetSelectedThread() + self.assertTrue(thread) + self.assertEqual(thread.GetThreadID(), 1) + self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal) + self.assertEqual(thread.GetStopReasonDataCount(), 1) + self.assertEqual(thread.GetStopReasonDataAtIndex(0), signal.SIGSEGV) + backtrace = ["bar", "foo", "main"] + self.check_backtrace(thread, filename, backtrace) + + @skipIfLLVMTargetMissing("X86") + def test_amd64(self): + """Test single-threaded amd64 core dump.""" + self.do_test("1lwp_SIGSEGV.amd64", pid=693, region_count=21) + + +class NetBSD2LWPT2CoreTestCase(NetBSDCoreCommonTestCase): + THREAD_COUNT = 2 + + def check_stack(self, process, pid, filename): + thread = process.GetSelectedThread() + self.assertTrue(thread) + self.assertEqual(thread.GetThreadID(), 2) + self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal) + self.assertEqual(thread.GetStopReasonDataCount(), 1) + self.assertEqual(thread.GetStopReasonDataAtIndex(0), signal.SIGSEGV) + backtrace = ["bar", "foo", "lwp_main"] + self.check_backtrace(thread, filename, backtrace) + + # thread 1 should have no signal + thread = process.GetThreadByID(1) + self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal) + self.assertEqual(thread.GetStopReasonDataCount(), 1) + self.assertEqual(thread.GetStopReasonDataAtIndex(0), 0) + + @skipIfLLVMTargetMissing("X86") + def test_amd64(self): + """Test double-threaded amd64 core dump where thread 2 is signalled.""" + self.do_test("2lwp_t2_SIGSEGV.amd64", pid=622, region_count=24) + + +class NetBSD2LWPProcessSigCoreTestCase(NetBSDCoreCommonTestCase): + THREAD_COUNT = 2 + + def check_stack(self, process, pid, filename): + thread = process.GetSelectedThread() + self.assertTrue(thread) + self.assertEqual(thread.GetThreadID(), 2) + self.assertEqual(thread.GetThreadID(), 2) + self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal) + self.assertEqual(thread.GetStopReasonDataCount(), 1) + self.assertEqual(thread.GetStopReasonDataAtIndex(0), signal.SIGSEGV) + backtrace = ["_kill", "bar", "foo", "lwp_main"] + self.check_backtrace(thread, filename, backtrace) + + # thread 1 should have the same signal + thread = process.GetThreadByID(1) + self.assertEqual(thread.GetStopReason(), lldb.eStopReasonSignal) + self.assertEqual(thread.GetStopReasonDataCount(), 1) + self.assertEqual(thread.GetStopReasonDataAtIndex(0), signal.SIGSEGV) + + @skipIfLLVMTargetMissing("X86") + def test_amd64(self): + """Test double-threaded amd64 core dump where process is signalled.""" + self.do_test("2lwp_process_SIGSEGV.amd64", pid=141, region_count=24) |