diff options
Diffstat (limited to 'lldb/packages/Python/lldbsuite')
12 files changed, 369 insertions, 0 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/TestGCore.py b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/TestGCore.py new file mode 100644 index 00000000000..5a11a52e93a --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/TestGCore.py @@ -0,0 +1,52 @@ +""" +Test signal reporting when debugging with linux core files. +""" + +from __future__ import print_function + +import shutil +import struct + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class GCoreTestCase(TestBase): + NO_DEBUG_INFO_TESTCASE = True + + mydir = TestBase.compute_mydir(__file__) + _initial_platform = lldb.DBG.GetSelectedPlatform() + + _i386_pid = 5586 + _x86_64_pid = 5669 + + @skipIf(oslist=['windows']) + @skipIf(triple='^mips') + def test_i386(self): + """Test that lldb can read the process information from an i386 linux core file.""" + self.do_test("linux-i386", self._i386_pid) + + @skipIf(oslist=['windows']) + @skipIf(triple='^mips') + def test_x86_64(self): + """Test that lldb can read the process information from an x86_64 linux core file.""" + self.do_test("linux-x86_64", self._x86_64_pid) + + def do_test(self, filename, pid): + target = self.dbg.CreateTarget("") + process = target.LoadCore(filename + ".core") + self.assertTrue(process, PROCESS_IS_VALID) + self.assertEqual(process.GetNumThreads(), 3) + self.assertEqual(process.GetProcessID(), pid) + + for thread in process: + reason = thread.GetStopReason() + self.assertEqual(reason, lldb.eStopReasonSignal) + signal = thread.GetStopReasonDataAtIndex(1) + # Check we got signal 19 (SIGSTOP) + self.assertEqual(signal, 19) + + self.dbg.DeleteTarget(target) + lldb.DBG.SetSelectedPlatform(self._initial_platform) diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/linux-i386.core b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/linux-i386.core new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/linux-i386.core diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/linux-x86_64.core b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/linux-x86_64.core new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/linux-x86_64.core diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/main.cpp b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/main.cpp new file mode 100644 index 00000000000..9908faffb6e --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/main.cpp @@ -0,0 +1,63 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// This test verifies the correct handling of child thread exits. + +#include <atomic> +#include <thread> +#include <csignal> + +pseudo_barrier_t g_barrier1; +pseudo_barrier_t g_barrier2; + +void * +thread1 () +{ + // Synchronize with the main thread. + pseudo_barrier_wait(g_barrier1); + + // Synchronize with the main thread and thread2. + pseudo_barrier_wait(g_barrier2); + + // Return + return NULL; +} + +void * +thread2 () +{ + + // Synchronize with thread1 and the main thread. + pseudo_barrier_wait(g_barrier2); // Should not reach here. + + // Return + return NULL; +} + +int main () +{ + + pseudo_barrier_init(g_barrier1, 2); + pseudo_barrier_init(g_barrier2, 3); + + // Create a thread. + std::thread thread_1(thread1); + + // Wait for thread1 to start. + pseudo_barrier_wait(g_barrier1); + + // Wait for thread1 to start. + std::thread thread_2(thread2); + + // Thread 2 is waiting for another thread to reach the barrier. + // This should have for ever. (So we can run gcore against this process.) + thread_2.join(); + + return 0; +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/main.mk b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/main.mk new file mode 100755 index 00000000000..ff874a21f76 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/main.mk @@ -0,0 +1,5 @@ +LEVEL = ../../../../make + +CXX_SOURCES := main.cpp +ENABLE_THREADS := YES +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/make-core.sh b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/make-core.sh new file mode 100755 index 00000000000..b6979c7790d --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/gcore/make-core.sh @@ -0,0 +1,56 @@ +#! /bin/sh + +linux_check_ptrace_scope() +{ + if grep -q '1' </proc/sys/kernel/yama/ptrace_scope; then + cat <<EOF +Your system prevents the use of PTRACE to attach to non-child processes. The core file +cannot be generated. Please reset /proc/sys/kernel/yama/ptrace_scope to 0 (requires root +privileges) to enable core generation via gcore. +EOF + exit 1 + fi +} + +set -e -x + +OS=$(uname -s) +if [ "$OS" = Linux ]; then + linux_check_ptrace_scope +fi + +rm -f a.out +make -f main.mk + +cat <<EOF +Executable file is in a.out. +Core file will be saved as core.<pid>. +EOF + +stack_size=`ulimit -s` + +# Decrease stack size to 16k => smaller core files. +# gcore won't run with the smaller stack +ulimit -Ss 16 + +core_dump_filter=`cat /proc/self/coredump_filter` +echo 0 > /proc/self/coredump_filter + +./a.out & + +pid=$! + +echo $core_dump_filter > /proc/self/coredump_filter + +# Reset stack size as so there's enough space to run gcore. +ulimit -s $stack_size + +echo "Sleeping for 5 seconds to wait for $pid" + +sleep 5 +echo "Taking core from process $pid" + +gcore -o core $pid + +echo "Killing process $pid" +kill -9 $pid diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/TestLinuxCoreThreads.py b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/TestLinuxCoreThreads.py new file mode 100644 index 00000000000..7cc3c0775ce --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/TestLinuxCoreThreads.py @@ -0,0 +1,61 @@ +""" +Test signal reporting when debugging with linux core files. +""" + +from __future__ import print_function + +import shutil +import struct + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class LinuxCoreThreadsTestCase(TestBase): + NO_DEBUG_INFO_TESTCASE = True + + mydir = TestBase.compute_mydir(__file__) + _initial_platform = lldb.DBG.GetSelectedPlatform() + + _i386_pid = 5193 + _x86_64_pid = 5222 + + # Thread id for the failing thread. + _i386_tid = 5195 + _x86_64_tid = 5250 + + @skipIf(oslist=['windows']) + @skipIf(triple='^mips') + def test_i386(self): + """Test that lldb can read the process information from an i386 linux core file.""" + self.do_test("linux-i386", self._i386_pid, self._i386_tid) + + @skipIf(oslist=['windows']) + @skipIf(triple='^mips') + def test_x86_64(self): + """Test that lldb can read the process information from an x86_64 linux core file.""" + self.do_test("linux-x86_64", self._x86_64_pid, self._x86_64_tid) + + def do_test(self, filename, pid, tid): + target = self.dbg.CreateTarget("") + process = target.LoadCore(filename + ".core") + self.assertTrue(process, PROCESS_IS_VALID) + self.assertEqual(process.GetNumThreads(), 3) + self.assertEqual(process.GetProcessID(), pid) + + for thread in process: + reason = thread.GetStopReason() + if( thread.GetThreadID() == tid ): + self.assertEqual(reason, lldb.eStopReasonSignal) + signal = thread.GetStopReasonDataAtIndex(1) + # Check we got signal 4 (SIGILL) + self.assertEqual(signal, 4) + else: + signal = thread.GetStopReasonDataAtIndex(1) + # Check we got no signal on the other threads + self.assertEqual(signal, 0) + + self.dbg.DeleteTarget(target) + lldb.DBG.SetSelectedPlatform(self._initial_platform) diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/linux-i386.core b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/linux-i386.core new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/linux-i386.core diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/linux-x86_64.core b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/linux-x86_64.core new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/linux-x86_64.core diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/main.cpp b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/main.cpp new file mode 100644 index 00000000000..826d9d3fa97 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/main.cpp @@ -0,0 +1,63 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// This test verifies the correct handling of child thread exits. + +#include <atomic> +#include <thread> +#include <csignal> + +pseudo_barrier_t g_barrier1; +pseudo_barrier_t g_barrier2; + +void * +thread1 () +{ + // Synchronize with the main thread. + pseudo_barrier_wait(g_barrier1); + + // Synchronize with the main thread and thread2. + pseudo_barrier_wait(g_barrier2); + + // Return + return NULL; // Should not reach here. (thread2 should raise SIGILL) +} + +void * +thread2 () +{ + raise(SIGILL); // Raise SIGILL + + // Synchronize with thread1 and the main thread. + pseudo_barrier_wait(g_barrier2); // Should not reach here. + + // Return + return NULL; +} + +int main () +{ + pseudo_barrier_init(g_barrier1, 2); + pseudo_barrier_init(g_barrier2, 3); + + // Create a thread. + std::thread thread_1(thread1); + + // Wait for thread1 to start. + pseudo_barrier_wait(g_barrier1); + + // Create another thread. + std::thread thread_2(thread2); + + // Wait for thread2 to start. + // Second thread should crash but first thread and main thread may reach here. + pseudo_barrier_wait(g_barrier2); + + return 0; +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/main.mk b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/main.mk new file mode 100755 index 00000000000..ff874a21f76 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/main.mk @@ -0,0 +1,5 @@ +LEVEL = ../../../../make + +CXX_SOURCES := main.cpp +ENABLE_THREADS := YES +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/make-core.sh b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/make-core.sh new file mode 100755 index 00000000000..ea263c86ea4 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/elf-core/thread_crash/make-core.sh @@ -0,0 +1,64 @@ +#! /bin/sh + +linux_check_core_pattern() +{ + if grep -q '^|' </proc/sys/kernel/core_pattern; then + cat <<EOF +Your system uses a crash report tool ($(cat /proc/sys/kernel/core_pattern)). Core files +will not be generated. Please reset /proc/sys/kernel/core_pattern (requires root +privileges) to enable core generation. +EOF + exit 1 + fi +} + +OS=$(uname -s) +case "$OS" in +FreeBSD) + core_pattern=$(sysctl -n kern.corefile) + ;; +Linux) + core_pattern=$(cat /proc/sys/kernel/core_pattern) + ;; +*) + echo "OS $OS not supported" >&2 + exit 1 + ;; +esac + +set -e -x + +if [ "$OS" = Linux ]; then + linux_check_core_pattern +fi + +ulimit -c 1000 +real_limit=$(ulimit -c) +if [ $real_limit -lt 100 ]; then + cat <<EOF +Unable to increase the core file limit. Core file may be truncated! +To fix this, increase HARD core file limit (ulimit -H -c 1000). This may require root +privileges. +EOF +fi + +rm -f a.out +make -f main.mk + +cat <<EOF +Executable file is in a.out. +Core file will be saved according to pattern $core_pattern. +EOF + +# Save stack size and core_dump_filter +stack_size=`ulimit -s` +ulimit -Ss 32 # Decrease stack size to 32k => smaller core files. + +core_dump_filter=`cat /proc/self/coredump_filter` +echo 0 > /proc/self/coredump_filter + +exec ./a.out + +# Reset stack size and core_dump_filter +echo core_dump_filter > /proc/self/coredump_filter +ulimit -s $stack_size |