Initial import of lldb

Change-Id: Ib244e837bee349effa12b2ff6ffffbe3d730e929
This commit is contained in:
2014-09-29 14:52:42 +02:00
committed by Lionel Sambuc
parent 35b65c5af1
commit 41f05bd8d7
3541 changed files with 875157 additions and 0 deletions

View File

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

View File

@@ -0,0 +1,226 @@
"""
Use lldb Python SBFrame API to get the argument values of the call stacks.
And other SBFrame API tests.
"""
import os, time
import re
import unittest2
import lldb, lldbutil
from lldbtest import *
class FrameAPITestCase(TestBase):
mydir = os.path.join("python_api", "frame")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_get_arg_vals_for_call_stack_with_dsym(self):
"""Exercise SBFrame.GetVariables() API to get argument vals."""
self.buildDsym()
self.do_get_arg_vals()
@python_api_test
@dwarf_test
def test_get_arg_vals_for_call_stack_with_dwarf(self):
"""Exercise SBFrame.GetVariables() API to get argument vals."""
self.buildDwarf()
self.do_get_arg_vals()
@python_api_test
def test_frame_api_boundary_condition(self):
"""Exercise SBFrame APIs with boundary condition inputs."""
self.buildDefault()
self.frame_api_boundary_condition()
@python_api_test
def test_frame_api_IsEqual(self):
"""Exercise SBFrame API IsEqual."""
self.buildDefault()
self.frame_api_IsEqual()
def do_get_arg_vals(self):
"""Get argument vals for the call stack when stopped on a breakpoint."""
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.BreakpointCreateByName('c', 'a.out')
#print "breakpoint:", breakpoint
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() == 1,
VALID_BREAKPOINT)
# Now launch the process, and do not stop at the entry point.
process = target.LaunchSimple(None, None, os.getcwd())
process = target.GetProcess()
self.assertTrue(process.GetState() == lldb.eStateStopped,
PROCESS_STOPPED)
# Keeps track of the number of times 'a' is called where it is within a
# depth of 3 of the 'c' leaf function.
callsOfA = 0
import StringIO
session = StringIO.StringIO()
while process.GetState() == lldb.eStateStopped:
thread = process.GetThreadAtIndex(0)
# Inspect at most 3 frames.
numFrames = min(3, thread.GetNumFrames())
for i in range(numFrames):
frame = thread.GetFrameAtIndex(i)
if self.TraceOn():
print "frame:", frame
name = frame.GetFunction().GetName()
if name == 'a':
callsOfA = callsOfA + 1
# We'll inspect only the arguments for the current frame:
#
# arguments => True
# locals => False
# statics => False
# in_scope_only => True
valList = frame.GetVariables(True, False, False, True)
argList = []
for val in valList:
argList.append("(%s)%s=%s" % (val.GetTypeName(),
val.GetName(),
val.GetValue()))
print >> session, "%s(%s)" % (name, ", ".join(argList))
# Also check the generic pc & stack pointer. We can't test their absolute values,
# but they should be valid. Uses get_GPRs() from the lldbutil module.
gpr_reg_set = lldbutil.get_GPRs(frame)
pc_value = gpr_reg_set.GetChildMemberWithName("pc")
self.assertTrue (pc_value, "We should have a valid PC.")
pc_value_str = pc_value.GetValue()
self.assertTrue (pc_value_str, "We should have a valid PC string.")
self.assertTrue (int(pc_value_str, 0) == frame.GetPC(), "PC gotten as a value should equal frame's GetPC")
sp_value = gpr_reg_set.GetChildMemberWithName("sp")
self.assertTrue (sp_value, "We should have a valid Stack Pointer.")
self.assertTrue (int(sp_value.GetValue(), 0) == frame.GetSP(), "SP gotten as a value should equal frame's GetSP")
print >> session, "---"
process.Continue()
# At this point, the inferior process should have exited.
self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)
# Expect to find 'a' on the call stacks two times.
self.assertTrue(callsOfA == 2,
"Expect to find 'a' on the call stacks two times")
# By design, the 'a' call frame has the following arg vals:
# o a((int)val=1, (char)ch='A')
# o a((int)val=3, (char)ch='A')
if self.TraceOn():
print "Full stack traces when stopped on the breakpoint 'c':"
print session.getvalue()
self.expect(session.getvalue(), "Argugment values displayed correctly",
exe=False,
substrs = ["a((int)val=1, (char)ch='A')",
"a((int)val=3, (char)ch='A')"])
def frame_api_boundary_condition(self):
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.BreakpointCreateByName('c', 'a.out')
#print "breakpoint:", breakpoint
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() == 1,
VALID_BREAKPOINT)
# Now launch the process, and do not stop at the entry point.
process = target.LaunchSimple(None, None, os.getcwd())
process = target.GetProcess()
self.assertTrue(process.GetState() == lldb.eStateStopped,
PROCESS_STOPPED)
thread = process.GetThreadAtIndex(0)
frame = thread.GetFrameAtIndex(0)
if self.TraceOn():
print "frame:", frame
# Boundary condition testings.
val1 = frame.FindVariable(None, True)
val2 = frame.FindVariable(None, False)
val3 = frame.FindValue(None, lldb.eValueTypeVariableGlobal)
if self.TraceOn():
print "val1:", val1
print "val2:", val2
frame.EvaluateExpression(None)
def frame_api_IsEqual(self):
"""Exercise SBFrame API IsEqual."""
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.BreakpointCreateByName('c', 'a.out')
#print "breakpoint:", breakpoint
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() == 1,
VALID_BREAKPOINT)
# Now launch the process, and do not stop at the entry point.
process = target.LaunchSimple(None, None, os.getcwd())
process = target.GetProcess()
self.assertTrue(process.GetState() == lldb.eStateStopped,
PROCESS_STOPPED)
thread = process.GetThreadAtIndex(0)
self.assertTrue(thread)
frameEntered = thread.GetFrameAtIndex(0)
if self.TraceOn():
print frameEntered
lldbutil.print_stacktrace(thread)
self.assertTrue(frameEntered)
# Doing two step overs while still inside c().
thread.StepOver()
thread.StepOver()
self.assertTrue(thread)
frameNow = thread.GetFrameAtIndex(0)
if self.TraceOn():
print frameNow
lldbutil.print_stacktrace(thread)
self.assertTrue(frameNow)
# The latest two frames are considered equal.
self.assertTrue(frameEntered.IsEqual(frameNow))
# Now let's step out of frame c().
thread.StepOutOfFrame(frameNow)
frameOutOfC = thread.GetFrameAtIndex(0)
if self.TraceOn():
print frameOutOfC
lldbutil.print_stacktrace(thread)
self.assertTrue(frameOutOfC)
# The latest two frames should not be equal.
self.assertFalse(frameOutOfC.IsEqual(frameNow))
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,9 @@
LEVEL = ../../../make
C_SOURCES := inlines.c
ifneq (,$(findstring icc,$(CC)))
CFLAGS += -debug inline-debug-info
endif
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,95 @@
"""
Testlldb Python SBFrame APIs IsInlined() and GetFunctionName().
"""
import os, time
import re
import unittest2
import lldb, lldbutil
from lldbtest import *
class InlinedFrameAPITestCase(TestBase):
mydir = os.path.join("python_api", "frame", "inlines")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_stop_at_outer_inline_with_dsym(self):
"""Exercise SBFrame.IsInlined() and SBFrame.GetFunctionName()."""
self.buildDsym()
self.do_stop_at_outer_inline()
@python_api_test
@dwarf_test
def test_stop_at_outer_inline_with_dwarf(self):
"""Exercise SBFrame.IsInlined() and SBFrame.GetFunctionName()."""
self.buildDwarf()
self.do_stop_at_outer_inline()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to of function 'c'.
self.source = 'inlines.c'
self.first_stop = line_number(self.source, '// This should correspond to the first break stop.')
self.second_stop = line_number(self.source, '// This should correspond to the second break stop.')
def do_stop_at_outer_inline(self):
"""Exercise SBFrame.IsInlined() and SBFrame.GetFunctionName()."""
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 the name of 'inner_inline'.
breakpoint = target.BreakpointCreateByName('inner_inline', 'a.out')
#print "breakpoint:", breakpoint
self.assertTrue(breakpoint and
breakpoint.GetNumLocations() > 1,
VALID_BREAKPOINT)
# Now launch the process, and do not stop at the entry point.
process = target.LaunchSimple(None, None, os.getcwd())
process = target.GetProcess()
self.assertTrue(process.GetState() == lldb.eStateStopped,
PROCESS_STOPPED)
import lldbutil
stack_traces1 = lldbutil.print_stacktraces(process, string_buffer=True)
if self.TraceOn():
print "Full stack traces when first stopped on the breakpoint 'inner_inline':"
print stack_traces1
# The first breakpoint should correspond to an inlined call frame.
# If it's an inlined call frame, expect to find, in the stack trace,
# that there is a frame which corresponds to the following call site:
#
# outer_inline (argc);
#
frame0 = process.GetThreadAtIndex(0).GetFrameAtIndex(0)
if frame0.IsInlined():
filename = frame0.GetLineEntry().GetFileSpec().GetFilename()
self.assertTrue(filename == self.source)
self.expect(stack_traces1, "First stop at %s:%d" % (self.source, self.first_stop), exe=False,
substrs = ['%s:%d' % (self.source, self.first_stop)])
# Expect to break again for the second time.
process.Continue()
self.assertTrue(process.GetState() == lldb.eStateStopped,
PROCESS_STOPPED)
stack_traces2 = lldbutil.print_stacktraces(process, string_buffer=True)
if self.TraceOn():
print "Full stack traces when stopped on the breakpoint 'inner_inline' for the second time:"
print stack_traces2
self.expect(stack_traces2, "Second stop at %s:%d" % (self.source, self.second_stop), exe=False,
substrs = ['%s:%d' % (self.source, self.second_stop)])
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@@ -0,0 +1,53 @@
#include <stdio.h>
#include "inlines.h"
#define INLINE_ME __inline__ __attribute__((always_inline))
int
not_inlined_2 (int input)
{
printf ("Called in not_inlined_2 with : %d.\n", input);
return input;
}
int
not_inlined_1 (int input)
{
printf ("Called in not_inlined_1 with %d.\n", input);
return not_inlined_2(input);
}
INLINE_ME int
inner_inline (int inner_input, int mod_value)
{
int inner_result;
inner_result = inner_input % mod_value;
printf ("Returning: %d.\n", inner_result);
return not_inlined_1 (inner_result);
}
INLINE_ME int
outer_inline (int outer_input)
{
int outer_result;
outer_result = inner_inline (outer_input, outer_input % 3);
return outer_result;
}
int
main (int argc, char **argv)
{
printf ("Starting...\n");
int (*func_ptr) (int);
func_ptr = outer_inline;
outer_inline (argc); // This should correspond to the first break stop.
func_ptr (argc); // This should correspond to the second break stop.
return 0;
}

View File

@@ -0,0 +1,4 @@
int inner_inline (int inner_input, int mod_value);
int outer_inline (int outer_input);
int not_inlined_2 (int input);
int not_inlined_1 (int input);

View File

@@ -0,0 +1,58 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <stdio.h>
// This simple program is to test the lldb Python API related to frames.
int a(int, char);
int b(int, char);
int c(int, char);
int a(int val, char ch)
{
int my_val = val;
char my_ch = ch;
printf("a(val=%d, ch='%c')\n", val, ch);
if (val <= 1)
return b(val+1, ch+1);
else if (val >= 3)
return c(val+1, ch+1);
return val;
}
int b(int val, char ch)
{
int my_val = val;
char my_ch = ch;
printf("b(val=%d, ch='%c')\n", val, ch);
return c(val+1, ch+1);
}
int c(int val, char ch)
{
int my_val = val;
char my_ch = ch;
printf("c(val=%d, ch='%c')\n", val, ch);
return val + 3 + ch;
}
int main (int argc, char const *argv[])
{
int A1 = a(1, 'A'); // a(1, 'A') -> b(2, 'B') -> c(3, 'C')
printf("a(1, 'A') returns %d\n", A1);
int B2 = b(2, 'B'); // b(2, 'B') -> c(3, 'C')
printf("b(2, 'B') returns %d\n", B2);
int A3 = a(3, 'A'); // a(3, 'A') -> c(4, 'B')
printf("a(3, 'A') returns %d\n", A3);
return 0;
}