Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@ -0,0 +1,5 @@
LEVEL = ../../make
C_SOURCES := main.c
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,115 @@
"""Test that lldb command 'process signal SIGUSR1' to send a signal to the inferior works."""
from __future__ import print_function
import os
import time
import signal
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class SendSignalTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break inside main().
self.line = line_number('main.c', 'Put breakpoint here')
@expectedFailureAll(
oslist=['freebsd'],
bugnumber="llvm.org/pr23318: does not report running state")
@skipIfWindows # Windows does not support signals
def test_with_run_command(self):
"""Test that lldb command 'process signal SIGUSR1' sends a signal to the inferior process."""
self.build()
exe = os.path.join(os.getcwd(), "a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# Now create a breakpoint on main.c by name 'c'.
breakpoint = target.BreakpointCreateByLocation('main.c', self.line)
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() == 1,
VALID_BREAKPOINT)
# Get the breakpoint location from breakpoint after we verified that,
# indeed, it has one location.
location = breakpoint.GetLocationAtIndex(0)
self.assertTrue(location and
location.IsEnabled(),
VALID_BREAKPOINT_LOCATION)
# Now launch the process, no arguments & do not stop at entry point.
launch_info = lldb.SBLaunchInfo([exe])
launch_info.SetWorkingDirectory(self.get_process_working_directory())
process_listener = lldb.SBListener("signal_test_listener")
launch_info.SetListener(process_listener)
error = lldb.SBError()
process = target.Launch(launch_info, error)
self.assertTrue(process, PROCESS_IS_VALID)
self.runCmd("process handle -n False -p True -s True SIGUSR1")
thread = lldbutil.get_stopped_thread(
process, lldb.eStopReasonBreakpoint)
self.assertTrue(thread.IsValid(), "We hit the first breakpoint.")
# After resuming the process, send it a SIGUSR1 signal.
self.setAsync(True)
self.assertTrue(
process_listener.IsValid(),
"Got a good process listener")
# Disable our breakpoint, we don't want to hit it anymore...
breakpoint.SetEnabled(False)
# Now continue:
process.Continue()
# If running remote test, there should be a connected event
if lldb.remote_platform:
self.match_state(process_listener, lldb.eStateConnected)
self.match_state(process_listener, lldb.eStateRunning)
# Now signal the process, and make sure it stops:
process.Signal(lldbutil.get_signal_number('SIGUSR1'))
self.match_state(process_listener, lldb.eStateStopped)
# Now make sure the thread was stopped with a SIGUSR1:
threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonSignal)
self.assertTrue(len(threads) == 1, "One thread stopped for a signal.")
thread = threads[0]
self.assertTrue(
thread.GetStopReasonDataCount() >= 1,
"There was data in the event.")
self.assertTrue(
thread.GetStopReasonDataAtIndex(0) == lldbutil.get_signal_number('SIGUSR1'),
"The stop signal was SIGUSR1")
def match_state(self, process_listener, expected_state):
num_seconds = 5
broadcaster = self.process().GetBroadcaster()
event_type_mask = lldb.SBProcess.eBroadcastBitStateChanged
event = lldb.SBEvent()
got_event = process_listener.WaitForEventForBroadcasterWithType(
num_seconds, broadcaster, event_type_mask, event)
self.assertTrue(got_event, "Got an event")
state = lldb.SBProcess.GetStateFromEvent(event)
self.assertTrue(state == expected_state,
"It was the %s state." %
lldb.SBDebugger_StateAsCString(expected_state))

View File

@ -0,0 +1,5 @@
LEVEL = ../../../make
C_SOURCES := main.c
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,49 @@
"""Test that we can debug inferiors that handle SIGSEGV by themselves"""
from __future__ import print_function
import os
import re
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class HandleSegvTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfWindows # signals do not exist on Windows
@skipIfDarwin
def test_inferior_handle_sigsegv(self):
self.build()
exe = os.path.join(os.getcwd(), "a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
# launch
process = target.LaunchSimple(
None, None, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
self.assertEqual(process.GetState(), lldb.eStateStopped)
signo = process.GetUnixSignals().GetSignalNumberFromName("SIGSEGV")
thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
self.assertTrue(
thread and thread.IsValid(),
"Thread should be stopped due to a signal")
self.assertTrue(
thread.GetStopReasonDataCount() >= 1,
"There was data in the event.")
self.assertEqual(thread.GetStopReasonDataAtIndex(0),
signo, "The stop signal was SIGSEGV")
# Continue until we exit.
process.Continue()
self.assertEqual(process.GetState(), lldb.eStateExited)
self.assertEqual(process.GetExitStatus(), 0)

View File

@ -0,0 +1,58 @@
#include <sys/mman.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
enum {
kMmapSize = 0x1000,
kMagicValue = 47,
};
void *address;
volatile sig_atomic_t signaled = 0;
void handler(int sig)
{
signaled = 1;
if (munmap(address, kMmapSize) != 0)
{
perror("munmap");
_exit(5);
}
void* newaddr = mmap(address, kMmapSize, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_FIXED | MAP_PRIVATE, -1, 0);
if (newaddr != address)
{
fprintf(stderr, "Newly mmaped address (%p) does not equal old address (%p).\n",
newaddr, address);
_exit(6);
}
*(int*)newaddr = kMagicValue;
}
int main()
{
if (signal(SIGSEGV, handler) == SIG_ERR)
{
perror("signal");
return 1;
}
address = mmap(NULL, kMmapSize, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0);
if (address == MAP_FAILED)
{
perror("mmap");
return 2;
}
// This should first trigger a segfault. Our handler will make the memory readable and write
// the magic value into memory.
if (*(int*)address != kMagicValue)
return 3;
if (! signaled)
return 4;
return 0;
}

View File

@ -0,0 +1,27 @@
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void handler_usr1 (int i)
{
puts ("got signal usr1");
}
void handler_alrm (int i)
{
puts ("got signal ALRM");
}
int main ()
{
int i = 0;
signal (SIGUSR1, handler_usr1);
signal (SIGALRM, handler_alrm);
puts ("Put breakpoint here");
while (i++ < 20)
sleep (1);
}

View File

@ -0,0 +1,5 @@
LEVEL = ../../../make
C_SOURCES := main.c
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,279 @@
"""Test that we handle inferiors that send signals to themselves"""
from __future__ import print_function
import os
import lldb
import re
from lldbsuite.test.lldbplatformutil import getDarwinOSTriples
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
@skipIfWindows # signals do not exist on Windows
class RaiseTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
NO_DEBUG_INFO_TESTCASE = True
def test_sigstop(self):
self.build()
self.signal_test('SIGSTOP', False)
# passing of SIGSTOP is not correctly handled, so not testing that
# scenario: https://llvm.org/bugs/show_bug.cgi?id=23574
@skipIfDarwin # darwin does not support real time signals
@skipIfTargetAndroid()
def test_sigsigrtmin(self):
self.build()
self.signal_test('SIGRTMIN', True)
def test_sigtrap(self):
self.build()
self.signal_test('SIGTRAP', True)
def launch(self, target, signal):
# launch the process, do not stop at entry point.
process = target.LaunchSimple(
[signal], None, self.get_process_working_directory())
self.assertTrue(process, PROCESS_IS_VALID)
self.assertEqual(process.GetState(), lldb.eStateStopped)
thread = lldbutil.get_stopped_thread(
process, lldb.eStopReasonBreakpoint)
self.assertTrue(
thread.IsValid(),
"Thread should be stopped due to a breakpoint")
return process
def set_handle(self, signal, pass_signal, stop_at_signal, notify_signal):
return_obj = lldb.SBCommandReturnObject()
self.dbg.GetCommandInterpreter().HandleCommand(
"process handle %s -p %s -s %s -n %s" %
(signal, pass_signal, stop_at_signal, notify_signal), return_obj)
self.assertTrue(
return_obj.Succeeded(),
"Setting signal handling failed")
def signal_test(self, signal, test_passing):
"""Test that we handle inferior raising signals"""
exe = os.path.join(os.getcwd(), "a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
lldbutil.run_break_set_by_symbol(self, "main")
# launch
process = self.launch(target, signal)
signo = process.GetUnixSignals().GetSignalNumberFromName(signal)
# retrieve default signal disposition
return_obj = lldb.SBCommandReturnObject()
self.dbg.GetCommandInterpreter().HandleCommand(
"process handle %s " % signal, return_obj)
match = re.match(
'NAME *PASS *STOP *NOTIFY.*(false|true) *(false|true) *(false|true)',
return_obj.GetOutput(),
re.IGNORECASE | re.DOTALL)
if not match:
self.fail('Unable to retrieve default signal disposition.')
default_pass = match.group(1)
default_stop = match.group(2)
default_notify = match.group(3)
# Make sure we stop at the signal
self.set_handle(signal, "false", "true", "true")
process.Continue()
self.assertEqual(process.GetState(), lldb.eStateStopped)
thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
self.assertTrue(
thread.IsValid(),
"Thread should be stopped due to a signal")
self.assertTrue(
thread.GetStopReasonDataCount() >= 1,
"There was data in the event.")
self.assertEqual(thread.GetStopReasonDataAtIndex(0), signo,
"The stop signal was %s" % signal)
# Continue until we exit.
process.Continue()
self.assertEqual(process.GetState(), lldb.eStateExited)
self.assertEqual(process.GetExitStatus(), 0)
# launch again
process = self.launch(target, signal)
# Make sure we do not stop at the signal. We should still get the
# notification.
self.set_handle(signal, "false", "false", "true")
self.expect(
"process continue",
substrs=[
"stopped and restarted",
signal])
self.assertEqual(process.GetState(), lldb.eStateExited)
self.assertEqual(process.GetExitStatus(), 0)
# launch again
process = self.launch(target, signal)
# Make sure we do not stop at the signal, and we do not get the
# notification.
self.set_handle(signal, "false", "false", "false")
self.expect(
"process continue",
substrs=["stopped and restarted"],
matching=False)
self.assertEqual(process.GetState(), lldb.eStateExited)
self.assertEqual(process.GetExitStatus(), 0)
if not test_passing:
# reset signal handling to default
self.set_handle(signal, default_pass, default_stop, default_notify)
return
# launch again
process = self.launch(target, signal)
# Make sure we stop at the signal
self.set_handle(signal, "true", "true", "true")
process.Continue()
self.assertEqual(process.GetState(), lldb.eStateStopped)
thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
self.assertTrue(
thread.IsValid(),
"Thread should be stopped due to a signal")
self.assertTrue(
thread.GetStopReasonDataCount() >= 1,
"There was data in the event.")
self.assertEqual(
thread.GetStopReasonDataAtIndex(0),
process.GetUnixSignals().GetSignalNumberFromName(signal),
"The stop signal was %s" %
signal)
# Continue until we exit. The process should receive the signal.
process.Continue()
self.assertEqual(process.GetState(), lldb.eStateExited)
self.assertEqual(process.GetExitStatus(), signo)
# launch again
process = self.launch(target, signal)
# Make sure we do not stop at the signal. We should still get the notification. Process
# should receive the signal.
self.set_handle(signal, "true", "false", "true")
self.expect(
"process continue",
substrs=[
"stopped and restarted",
signal])
self.assertEqual(process.GetState(), lldb.eStateExited)
self.assertEqual(process.GetExitStatus(), signo)
# launch again
process = self.launch(target, signal)
# Make sure we do not stop at the signal, and we do not get the notification. Process
# should receive the signal.
self.set_handle(signal, "true", "false", "false")
self.expect(
"process continue",
substrs=["stopped and restarted"],
matching=False)
self.assertEqual(process.GetState(), lldb.eStateExited)
self.assertEqual(process.GetExitStatus(), signo)
# reset signal handling to default
self.set_handle(signal, default_pass, default_stop, default_notify)
@expectedFailureAll(
oslist=["linux"] +
getDarwinOSTriples(),
bugnumber="llvm.org/pr20231")
def test_restart_bug(self):
"""Test that we catch a signal in the edge case where the process receives it while we are
about to interrupt it"""
self.build()
exe = os.path.join(os.getcwd(), "a.out")
# Create a target by the debugger.
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
bkpt = target.BreakpointCreateByName("main")
self.assertTrue(bkpt.IsValid(), VALID_BREAKPOINT)
# launch the inferior and don't wait for it to stop
self.dbg.SetAsync(True)
error = lldb.SBError()
listener = lldb.SBListener("my listener")
process = target.Launch(listener,
["SIGSTOP"], # argv
None, # envp
None, # stdin_path
None, # stdout_path
None, # stderr_path
None, # working directory
0, # launch flags
False, # Stop at entry
error) # error
self.assertTrue(process and process.IsValid(), PROCESS_IS_VALID)
event = lldb.SBEvent()
# Give the child enough time to reach the breakpoint,
# while clearing out all the pending events.
# The last WaitForEvent call will time out after 2 seconds.
while listener.WaitForEvent(2, event):
if self.TraceOn():
print(
"Process changing state to:",
self.dbg.StateAsCString(
process.GetStateFromEvent(event)))
# now the process should be stopped
self.assertEqual(
process.GetState(),
lldb.eStateStopped,
PROCESS_STOPPED)
self.assertEqual(len(lldbutil.get_threads_stopped_at_breakpoint(
process, bkpt)), 1, "A thread should be stopped at breakpoint")
# Remove all breakpoints. This makes sure we don't have to single-step over them when we
# resume the process below
target.DeleteAllBreakpoints()
# resume the process and immediately try to set another breakpoint. When using the remote
# stub, this will trigger a request to stop the process just as it is about to stop
# naturally due to a SIGSTOP signal it raises. Make sure we do not lose
# this signal.
process.Continue()
self.assertTrue(target.BreakpointCreateByName(
"handler").IsValid(), VALID_BREAKPOINT)
# Clear the events again
while listener.WaitForEvent(2, event):
if self.TraceOn():
print(
"Process changing state to:",
self.dbg.StateAsCString(
process.GetStateFromEvent(event)))
# The process should be stopped due to a signal
self.assertEqual(process.GetState(), lldb.eStateStopped)
thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal)
self.assertTrue(
thread.IsValid(),
"Thread should be stopped due to a signal")
self.assertTrue(
thread.GetStopReasonDataCount() >= 1,
"There was data in the event.")
signo = process.GetUnixSignals().GetSignalNumberFromName("SIGSTOP")
self.assertEqual(thread.GetStopReasonDataAtIndex(0), signo,
"The stop signal was %s" % signal)
# We are done
process.Kill()

View File

@ -0,0 +1,49 @@
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
void handler(int signo)
{
_exit(signo);
}
int main (int argc, char *argv[])
{
if (signal(SIGTRAP, handler) == SIG_ERR)
{
perror("signal(SIGTRAP)");
return 1;
}
#ifndef __APPLE__
// Real time signals not supported on apple platforms.
if (signal(SIGRTMIN, handler) == SIG_ERR)
{
perror("signal(SIGRTMIN)");
return 1;
}
#endif
if (argc < 2)
{
puts("Please specify a signal to raise");
return 1;
}
if (strcmp(argv[1], "SIGSTOP") == 0)
raise(SIGSTOP);
else if (strcmp(argv[1], "SIGTRAP") == 0)
raise(SIGTRAP);
#ifndef __APPLE__
else if (strcmp(argv[1], "SIGRTMIN") == 0)
raise(SIGRTMIN);
#endif
else
{
printf("Unknown signal: %s\n", argv[1]);
return 1;
}
return 0;
}