From cbb70ce070d220642b038ea101d9c0f9fbf860d6 Mon Sep 17 00:00:00 2001 From: dim Date: Sun, 20 Feb 2011 12:57:14 +0000 Subject: Vendor import of llvm trunk r126079: http://llvm.org/svn/llvm-project/llvm/trunk@126079 --- utils/CollectDebugInfoUsingLLDB.py | 182 +++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100755 utils/CollectDebugInfoUsingLLDB.py (limited to 'utils/CollectDebugInfoUsingLLDB.py') diff --git a/utils/CollectDebugInfoUsingLLDB.py b/utils/CollectDebugInfoUsingLLDB.py new file mode 100755 index 0000000..4dbd19a --- /dev/null +++ b/utils/CollectDebugInfoUsingLLDB.py @@ -0,0 +1,182 @@ +#!/usr/bin/python + +#---------------------------------------------------------------------- +# +# Be sure to add the python path that points to the LLDB shared library. +# On MacOSX csh, tcsh: +# setenv PYTHONPATH /Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python +# On MacOSX sh, bash: +# export PYTHONPATH=/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python +# +# This script collect debugging information using LLDB. This script is +# used by TEST=dbg in llvm testsuite to measure quality of debug info in +# optimized builds. +# +# Usage: +# export PYTHONPATH=... +# ./CollectDebugInfUsingLLDB.py program bp_file out_file +# program - Executable program with debug info. +# bp_file - Simple text file listing breakpoints. +# +# out_file - Output file where the debug info will be emitted. +#---------------------------------------------------------------------- + +import lldb +import os +import sys +import time + +# AlreadyPrintedValues - A place to keep track of recursive values. +AlreadyPrintedValues = {} + +# ISAlreadyPrinted - Return true if value is already printed. +def IsAlreadyPrinted(value_name): + if AlreadyPrintedValues.get(value_name) is None: + AlreadyPrintedValues[value_name] = 1 + return False + return True + + +# print_var_value - Print a variable's value. +def print_var_value (v, file, frame): + if v.IsValid() == False: + return + if IsAlreadyPrinted(v.GetName()): + return + total_children = v.GetNumChildren() + if total_children > 0: + c = 0 + while (c < total_children) : + child = v.GetChildAtIndex(c) + if child is None: + file.write("None") + else: + if (child.GetName()) is None: + file.write("None") + else: + file.write(child.GetName()) + file.write('=') + print_var_value(child, file, frame) + file.write(',') + c = c + 1 + else: + if v.GetValue(frame) is None: + file.write("None") + else: + file.write(v.GetValue(frame)) + +# print_vars - Print variable values in output file. +def print_vars (tag, vars, fname, line, file, frame, target, thread): + # disable this thread. + count = thread.GetStopReasonDataCount() + bid = 0 + tid = 0 + for i in range(count): + id = thread.GetStopReasonDataAtIndex(i) + bp = target.FindBreakpointByID(id) + if bp.IsValid(): + if bp.IsEnabled() == True: + bid = bp.GetID() + tid = bp.GetThreadID() + bp.SetEnabled(False) + else: + bp_loc = bp.FindLocationByID(thread.GetStopReasonDataAtIndex(i+1)) + if bp_loc.IsValid(): + bid = bp_loc.GetBreakPoint().GetID() + tid = bp_loc.ThreadGetID() + bp_loc.SetEnabled(False); + + for i in range(vars.GetSize()): + v = vars.GetValueAtIndex(i) + if v.GetName() is not None: + file.write(tag) + file.write(fname) + file.write(':') + file.write(str(line)) + file.write(' ') + file.write(str(tid)) + file.write(':') + file.write(str(bid)) + file.write(' ') + file.write(v.GetName()) + file.write(' ') + AlreadyPrintedValues.clear() + print_var_value (v, file, frame) + file.write('\n') + +# set_breakpoints - set breakpoints as listed in input file. +def set_breakpoints (target, breakpoint_filename, file): + f = open(breakpoint_filename, "r") + lines = f.readlines() + for l in range(len(lines)): + c = lines[l].split() + # print "setting break point - ", c + bp = target.BreakpointCreateByLocation (str(c[0]), int(c[1])) + file.write("#Breakpoint ") + file.write(str(c[0])) + file.write(':') + file.write(str(c[1])) + file.write(' ') + file.write(str(bp.GetThreadID())) + file.write(':') + file.write(str(bp.GetID())) + file.write('\n') + f.close() + +# stopeed_at_breakpoint - Return True if process is stopeed at a +# breakpoint. +def stopped_at_breakpoint (process): + if process.IsValid(): + state = process.GetState() + if state == lldb.eStateStopped: + thread = process.GetThreadAtIndex(0) + if thread.IsValid(): + if thread.GetStopReason() == lldb.eStopReasonBreakpoint: + return True + return False + +# Create a new debugger instance +debugger = lldb.SBDebugger.Create() + +# When we step or continue, don't return from the function until the process +# stops. We do this by setting the async mode to false. +debugger.SetAsync (False) + +# Create a target from a file and arch +##print "Creating a target for '%s'" % sys.argv[1] + +target = debugger.CreateTargetWithFileAndArch (sys.argv[1], lldb.LLDB_ARCH_DEFAULT) + +if target.IsValid(): + #print "target is valid" + file=open(str(sys.argv[3]), 'w') + set_breakpoints (target, sys.argv[2], file) + + # Launch the process. Since we specified synchronous mode, we won't return + # from this function until we hit the breakpoint at main + sberror = lldb.SBError() + process = target.Launch (None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, sberror) + # Make sure the launch went ok + while stopped_at_breakpoint(process): + thread = process.GetThreadAtIndex (0) + frame = thread.GetFrameAtIndex (0) + if frame.IsValid(): + # #Print some simple frame info + ##print frame + #print "frame is valid" + function = frame.GetFunction() + if function.IsValid(): + fname = function.GetMangledName() + if fname is None: + fname = function.GetName() + #print "function : ",fname + line = frame.GetLineEntry().GetLine() + vars = frame.GetVariables(1,0,0,0) + print_vars ("#Argument ", vars, fname, line, file, frame, target, thread) + # vars = frame.GetVariables(0,1,0,0) + # print_vars ("#Variables ", vars, fname, line, file, frame, target, thread) + + process.Continue() + file.close() + +lldb.SBDebugger.Terminate() -- cgit v1.1