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,7 @@
LEVEL = ../../../make
C_SOURCES := main.c
CFLAGS ?= -g -fomit-frame-pointer
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,52 @@
"""
Test that we can backtrace correctly from Non ABI functions on the stack
"""
from __future__ import print_function
import os
import time
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class EHFrameBasedUnwind(TestBase):
mydir = TestBase.compute_mydir(__file__)
@skipUnlessPlatform(['linux'])
@skipIf(archs=["aarch64", "arm", "i386", "i686"])
def test(self):
"""Test that we can backtrace correctly from Non ABI functions on the stack"""
self.build()
self.setTearDownCleanup()
exe = os.path.join(os.getcwd(), "a.out")
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
lldbutil.run_break_set_by_symbol(self, "func")
process = target.LaunchSimple(
["abc", "xyz"], None, self.get_process_working_directory())
if not process:
self.fail("SBTarget.Launch() failed")
if process.GetState() != lldb.eStateStopped:
self.fail("Process should be in the 'stopped' state, "
"instead the actual state is: '%s'" %
lldbutil.state_type_to_str(process.GetState()))
stacktraces = lldbutil.print_stacktraces(process, string_buffer=True)
self.expect(stacktraces, exe=False,
substrs=['(int)argc=3'])
self.runCmd("thread step-inst")
stacktraces = lldbutil.print_stacktraces(process, string_buffer=True)
self.expect(stacktraces, exe=False,
substrs=['(int)argc=3'])

View File

@ -0,0 +1,46 @@
void func() {
#ifndef __mips__
__asm__ (
"pushq $0x10;"
".cfi_def_cfa_offset 16;"
"jmp label;"
"movq $0x48, %rax;"
"label: subq $0x38, %rax;"
"movq $0x48, %rcx;"
"movq $0x48, %rdx;"
"movq $0x48, %rax;"
"popq %rax;"
);
#elif __mips64
__asm__ (
"daddiu $sp,$sp,-16;"
".cfi_def_cfa_offset 16;"
"sd $ra,8($sp);"
".cfi_offset 31, -8;"
"daddiu $ra,$zero,0;"
"ld $ra,8($sp);"
"daddiu $sp, $sp,16;"
".cfi_restore 31;"
".cfi_def_cfa_offset 0;"
);
#else
// For MIPS32
__asm__ (
"addiu $sp,$sp,-8;"
".cfi_def_cfa_offset 8;"
"sw $ra,4($sp);"
".cfi_offset 31, -4;"
"addiu $ra,$zero,0;"
"lw $ra,4($sp);"
"addiu $sp,$sp,8;"
".cfi_restore 31;"
".cfi_def_cfa_offset 0;"
);
#endif
}
int main(int argc, char const *argv[])
{
func();
}

View File

@ -0,0 +1,7 @@
LEVEL = ../../../make
C_SOURCES := main.c
CFLAGS ?= -g -Os
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,86 @@
"""
Test that we can backtrace correctly with 'noreturn' functions on the stack
"""
from __future__ import print_function
import os
import time
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class NoreturnUnwind(TestBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfWindows # clang-cl does not support gcc style attributes.
# clang does not preserve LR in noreturn functions, making unwinding impossible
@skipIf(compiler="clang", archs=['arm'], oslist=['linux'])
@expectedFailureAll(bugnumber="llvm.org/pr33452", triple='^mips')
def test(self):
"""Test that we can backtrace correctly with 'noreturn' functions on the stack"""
self.build()
self.setTearDownCleanup()
exe = os.path.join(os.getcwd(), "a.out")
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
process = target.LaunchSimple(
None, None, self.get_process_working_directory())
if not process:
self.fail("SBTarget.Launch() failed")
if process.GetState() != lldb.eStateStopped:
self.fail("Process should be in the 'stopped' state, "
"instead the actual state is: '%s'" %
lldbutil.state_type_to_str(process.GetState()))
thread = process.GetThreadAtIndex(0)
abort_frame_number = 0
for f in thread.frames:
# Some C libraries mangle the abort symbol into __GI_abort.
if f.GetFunctionName() in ["abort", "__GI_abort"]:
break
abort_frame_number = abort_frame_number + 1
if self.TraceOn():
print("Backtrace once we're stopped:")
for f in thread.frames:
print(" %d %s" % (f.GetFrameID(), f.GetFunctionName()))
# I'm going to assume that abort() ends up calling/invoking another
# function before halting the process. In which case if abort_frame_number
# equals 0, we didn't find abort() in the backtrace.
if abort_frame_number == len(thread.frames):
self.fail("Unable to find abort() in backtrace.")
func_c_frame_number = abort_frame_number + 1
if thread.GetFrameAtIndex(
func_c_frame_number).GetFunctionName() != "func_c":
self.fail("Did not find func_c() above abort().")
# This depends on whether we see the func_b inlined function in the backtrace
# or not. I'm not interested in testing that aspect of the backtrace here
# right now.
if thread.GetFrameAtIndex(
func_c_frame_number +
1).GetFunctionName() == "func_b":
func_a_frame_number = func_c_frame_number + 2
else:
func_a_frame_number = func_c_frame_number + 1
if thread.GetFrameAtIndex(
func_a_frame_number).GetFunctionName() != "func_a":
self.fail("Did not find func_a() above func_c().")
main_frame_number = func_a_frame_number + 1
if thread.GetFrameAtIndex(
main_frame_number).GetFunctionName() != "main":
self.fail("Did not find main() above func_a().")

View File

@ -0,0 +1,35 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static void func_a (void) __attribute__((noinline));
static void func_b (void) __attribute__((noreturn));
static void func_c (void) __attribute__((noinline));
static void
func_c (void)
{
abort ();
}
static void
func_b (void)
{
func_c ();
while (1)
;
}
static void
func_a (void)
{
func_b ();
}
int
main (int argc, char *argv[])
{
func_a ();
return 0;
}

View File

@ -0,0 +1,53 @@
"""
Test that we properly display the backtrace when a noreturn function happens to
be at the end of the stack.
"""
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 TestNoreturnModuleEnd(TestBase):
NO_DEBUG_INFO_TESTCASE = True
mydir = TestBase.compute_mydir(__file__)
def setUp(self):
super(TestNoreturnModuleEnd, self).setUp()
self._initial_platform = lldb.DBG.GetSelectedPlatform()
def tearDown(self):
lldb.DBG.SetSelectedPlatform(self._initial_platform)
super(TestNoreturnModuleEnd, self).tearDown()
def test(self):
target = self.dbg.CreateTarget("test.out")
process = target.LoadCore("test.core")
self.assertTrue(process.IsValid(), PROCESS_IS_VALID)
self.assertEqual(process.GetNumThreads(), 1)
thread = process.GetSelectedThread()
self.assertTrue(thread.IsValid())
backtrace = [
["func2", 3],
["func1", 8],
["_start", 8],
]
self.assertEqual(thread.GetNumFrames(), len(backtrace))
for i in range(len(backtrace)):
frame = thread.GetFrameAtIndex(i)
self.assertTrue(frame.IsValid())
symbol = frame.GetSymbol()
self.assertTrue(symbol.IsValid())
self.assertEqual(symbol.GetName(), backtrace[i][0])
function_start = symbol.GetStartAddress().GetLoadAddress(target)
self.assertEquals(function_start + backtrace[i][1], frame.GetPC())
self.dbg.DeleteTarget(target)

View File

@ -0,0 +1,35 @@
# compile this with:
# as a.s -o a.o --32 && ld a.o -m elf_i386
# generate core file with:
# ulimit -s 12 && ./a.out
.text
.globl func2
.type func2, @function
func2:
pushl %ebp
movl %esp, %ebp
movl 0, %eax
popl %ebp
ret
.size func2, .-func2
.globl _start
.type _start, @function
_start:
pushl %ebp
movl %esp, %ebp
call func1
popl %ebp
ret
.size _start, .-_start
.globl func1
.type func1, @function
func1:
pushl %ebp
movl %esp, %ebp
call func2
.size func1, .-func1

View File

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

View File

@ -0,0 +1,95 @@
"""
Test that we can backtrace correctly with 'sigtramp' functions on the stack
"""
from __future__ import print_function
import os
import time
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class SigtrampUnwind(TestBase):
mydir = TestBase.compute_mydir(__file__)
# On different platforms the "_sigtramp" and "__kill" frames are likely to be different.
# This test could probably be adapted to run on linux/*bsd easily enough.
@skipUnlessDarwin
@expectedFailureAll(oslist=["ios", "watchos", "tvos", "bridgeos"], bugnumber="<rdar://problem/34006863>") # lldb skips 1 frame on arm64 above _sigtramp
def test(self):
"""Test that we can backtrace correctly with _sigtramp on the stack"""
self.build()
self.setTearDownCleanup()
exe = os.path.join(os.getcwd(), "a.out")
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
lldbutil.run_break_set_by_file_and_line(self, "main.c", line_number(
'main.c', '// Set breakpoint here'), num_expected_locations=1)
process = target.LaunchSimple(
None, None, self.get_process_working_directory())
if not process:
self.fail("SBTarget.Launch() failed")
if process.GetState() != lldb.eStateStopped:
self.fail("Process should be in the 'stopped' state, "
"instead the actual state is: '%s'" %
lldbutil.state_type_to_str(process.GetState()))
self.expect(
"pro handle -n false -p true -s false SIGUSR1",
"Have lldb pass SIGUSR1 signals",
substrs=[
"SIGUSR1",
"true",
"false",
"false"])
lldbutil.run_break_set_by_symbol(
self,
"handler",
num_expected_locations=1,
module_name="a.out")
self.runCmd("continue")
thread = process.GetThreadAtIndex(0)
found_handler = False
found_sigtramp = False
found_kill = False
found_main = False
for f in thread.frames:
if f.GetFunctionName() == "handler":
found_handler = True
if f.GetFunctionName() == "_sigtramp":
found_sigtramp = True
if f.GetFunctionName() == "__kill":
found_kill = True
if f.GetFunctionName() == "main":
found_main = True
if self.TraceOn():
print("Backtrace once we're stopped:")
for f in thread.frames:
print(" %d %s" % (f.GetFrameID(), f.GetFunctionName()))
if not found_handler:
self.fail("Unable to find handler() in backtrace.")
if not found_sigtramp:
self.fail("Unable to find _sigtramp() in backtrace.")
if not found_kill:
self.fail("Unable to find kill() in backtrace.")
if not found_main:
self.fail("Unable to find main() in backtrace.")

View File

@ -0,0 +1,27 @@
#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void handler (int in)
{
puts ("in handler routine");
while (1)
;
}
void
foo ()
{
puts ("in foo ()");
kill (getpid(), SIGUSR1);
}
int main ()
{
puts ("in main"); // Set breakpoint here
signal (SIGUSR1, handler);
puts ("signal handler set up");
foo();
puts ("exiting");
return 0;
}

View File

@ -0,0 +1,3 @@
LEVEL = ../../../make
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,178 @@
"""
Test that we can backtrace correctly from standard functions.
This test suit is a collection of automatically generated tests from the source files in the
directory. Please DON'T add individual test cases to this file.
To add a new test case to this test suit please create a simple C/C++ application and put the
source file into the directory of the test cases. The test suit will automatically pick the
file up and generate a test case from it in run time (with name test_standard_unwind_<file_name>
after escaping some special characters).
"""
from __future__ import print_function
import unittest2
import os
import time
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
test_source_dirs = ["."]
class StandardUnwindTest(TestBase):
mydir = TestBase.compute_mydir(__file__)
def standard_unwind_tests(self):
# The following variables have to be defined for each architecture and OS we testing for:
# base_function_names: List of function names where we accept that the stack unwinding is
# correct if they are on the stack. It should include the bottom most
# function on the stack and a list of functions where we know we can't
# unwind for any reason (list of expected failure functions)
# no_step_function_names: The list of functions where we don't want to step through
# instruction by instruction for any reason. (A valid reason is if
# it is impossible to step through a function instruction by
# instruction because it is special for some reason.) For these
# functions we will immediately do a step-out when we hit them.
triple = self.dbg.GetSelectedPlatform().GetTriple()
if re.match("arm-.*-.*-android", triple):
base_function_names = [
"_start", # Base function on the stack
"__memcpy_base", # Function reached by a fall through from the previous function
"__memcpy_base_aligned",
# Function reached by a fall through from the previous function
]
no_step_function_names = [
"__sync_fetch_and_add_4", # Calls into a special SO where we can't set a breakpoint
"pthread_mutex_lock",
# Uses ldrex and strex what interferes with the software single
# stepping
"pthread_mutex_unlock",
# Uses ldrex and strex what interferes with the software single
# stepping
"pthread_once",
# Uses ldrex and strex what interferes with the software single
# stepping
]
elif re.match("aarch64-.*-.*-android", triple):
base_function_names = [
"do_arm64_start", # Base function on the stack
]
no_step_function_names = [
None,
"__cxa_guard_acquire",
# Uses ldxr and stxr what interferes with the software single
# stepping
"__cxa_guard_release",
# Uses ldxr and stxr what interferes with the software single
# stepping
"pthread_mutex_lock",
# Uses ldxr and stxr what interferes with the software single
# stepping
"pthread_mutex_unlock",
# Uses ldxr and stxr what interferes with the software single
# stepping
"pthread_once",
# Uses ldxr and stxr what interferes with the software single
# stepping
]
else:
self.skipTest("No expectations for the current architecture")
exe = os.path.join(os.getcwd(), "a.out")
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
target.BreakpointCreateByName("main")
process = target.LaunchSimple(
None, None, self.get_process_working_directory())
self.assertTrue(process is not None, "SBTarget.Launch() failed")
self.assertEqual(
process.GetState(),
lldb.eStateStopped,
"The process didn't hit main")
index = 0
while process.GetState() == lldb.eStateStopped:
index += 1
if process.GetNumThreads() > 1:
# In case of a multi threaded inferior if one of the thread is stopped in a blocking
# syscall and we try to step it then
# SBThread::StepInstruction() will block forever
self.skipTest(
"Multi threaded inferiors are not supported by this test")
thread = process.GetThreadAtIndex(0)
if self.TraceOn():
print("INDEX: %u" % index)
for f in thread.frames:
print(f)
if thread.GetFrameAtIndex(0).GetFunctionName() is not None:
found_main = False
for f in thread.frames:
if f.GetFunctionName() in base_function_names:
found_main = True
break
self.assertTrue(found_main,
"Main function isn't found on the backtrace")
if thread.GetFrameAtIndex(
0).GetFunctionName() in no_step_function_names:
thread.StepOut()
else:
thread.StepInstruction(False)
# Collect source files in the specified directories
test_source_files = set([])
for d in test_source_dirs:
if os.path.isabs(d):
dirname = d
else:
dirname = os.path.join(os.path.dirname(__file__), d)
for root, _, files in os.walk(dirname):
test_source_files = test_source_files | set(
os.path.abspath(os.path.join(root, f)) for f in files)
# Generate test cases based on the collected source files
for f in test_source_files:
if f.endswith(".cpp") or f.endswith(".c"):
@add_test_categories(["dwarf"])
@unittest2.skipIf(
TestBase.skipLongRunningTest(),
"Skip this long running test")
def test_function_dwarf(self, f=f):
if f.endswith(".cpp"):
d = {'CXX_SOURCES': f}
elif f.endswith(".c"):
d = {'C_SOURCES': f}
# If we can't compile the inferior just skip the test instead of failing it.
# It makes the test suit more robust when testing on several different architecture
# avoid the hassle of skipping tests manually.
try:
self.buildDwarf(dictionary=d)
self.setTearDownCleanup(d)
except:
if self.TraceOn():
print(sys.exc_info()[0])
self.skipTest("Inferior not supported")
self.standard_unwind_tests()
test_name = "test_unwind_" + str(f)
for c in ".=()/\\":
test_name = test_name.replace(c, '_')
test_function_dwarf.__name__ = test_name
setattr(
StandardUnwindTest,
test_function_dwarf.__name__,
test_function_dwarf)

View File

@ -0,0 +1,15 @@
//===-- divmod.cpp ----------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
int
main(int argc, char const *argv[])
{
signed long long a = 123456789, b = 12, c = a / b, d = a % b;
unsigned long long e = 123456789, f = 12, g = e / f, h = e % f;
}

View File

@ -0,0 +1,16 @@
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <cstdio>
int
main(int argc, char const *argv[])
{
fprintf(stderr, "%d %p %s\n", argc, argv, argv[0]);
}

View File

@ -0,0 +1,15 @@
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
int
main(int argc, char const *argv[])
{
int* p = new int;
delete p;
}