From aa18f59f8815b95e89826f41599734fc0d24b866 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 6 Sep 2013 18:10:44 +0000 Subject: Add an lldb wrapper script that implements gdb-compatible commands on top of lldb. This will be the new default method for executing the tests in this repository on Darwin. There is also a related patch for llvm/utils/test_debuginfo.pl coming. I also relaxed some of the checks to work with both gdb's and lldb's output. --- debuginfo-tests/aggregate-indirect-arg.cpp | 6 +- debuginfo-tests/llgdb.py | 137 +++++++++++++++++++++++++++++ debuginfo-tests/nested-struct.cpp | 2 +- debuginfo-tests/sret.cpp | 7 +- 4 files changed, 145 insertions(+), 7 deletions(-) create mode 100644 debuginfo-tests/llgdb.py (limited to 'debuginfo-tests') diff --git a/debuginfo-tests/aggregate-indirect-arg.cpp b/debuginfo-tests/aggregate-indirect-arg.cpp index f6b01b26dc8..26c571458ad 100644 --- a/debuginfo-tests/aggregate-indirect-arg.cpp +++ b/debuginfo-tests/aggregate-indirect-arg.cpp @@ -5,9 +5,9 @@ // DEBUGGER: break 22 // DEBUGGER: r // DEBUGGER: p v -// CHECK: $1 = { -// CHECK: Data = 0x0, -// CHECK: Kind = 2142 +// CHECK: ${{[0-9]+}} = { +// CHECK-NEXT: Data = 0x0{{,|(0+$)}} +// CHECK-NEXT: Kind = 2142 class SVal { public: diff --git a/debuginfo-tests/llgdb.py b/debuginfo-tests/llgdb.py new file mode 100644 index 00000000000..bfa5fb1fe05 --- /dev/null +++ b/debuginfo-tests/llgdb.py @@ -0,0 +1,137 @@ +#!/bin/env python +""" +A gdb-compatible frontend for lldb that implements just enough +commands to run the tests in the debuginfo-tests repository with lldb. +""" + +# ---------------------------------------------------------------------- +# Auto-detect lldb python module. +import commands, platform, os, sys +try: + # Just try for LLDB in case PYTHONPATH is already correctly setup. + import lldb +except ImportError: + lldb_python_dirs = list() + # lldb is not in the PYTHONPATH, try some defaults for the current platform. + platform_system = platform.system() + if platform_system == 'Darwin': + # On Darwin, try the currently selected Xcode directory + xcode_dir = commands.getoutput("xcode-select --print-path") + if xcode_dir: + lldb_python_dirs.append(os.path.realpath(xcode_dir + +'/../SharedFrameworks/LLDB.framework/Resources/Python')) + lldb_python_dirs.append(xcode_dir + +'/Library/PrivateFrameworks/LLDB.framework/Resources/Python') + lldb_python_dirs.append( +'/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python') + success = False + for lldb_python_dir in lldb_python_dirs: + if os.path.exists(lldb_python_dir): + if not (sys.path.__contains__(lldb_python_dir)): + sys.path.append(lldb_python_dir) + try: + import lldb + except ImportError: + pass + else: + print 'imported lldb from: "%s"' % (lldb_python_dir) + success = True + break + if not success: + print "error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly" + sys.exit(1) +# ---------------------------------------------------------------------- + +# Command line option handling. +import argparse +parser = argparse.ArgumentParser(description=__doc__) +parser.add_argument('--quiet', '-q', action="store_true", help='ignored') +parser.add_argument('-batch', action="store_true", + help='exit after processing comand line') +parser.add_argument('-n', action="store_true", help='ignore .lldb file') +parser.add_argument('-x', dest='script', type=file, help='execute commands from file') +parser.add_argument("target", help="the program to debug") +args = parser.parse_args() + + +# Create a new debugger instance. +debugger = lldb.SBDebugger.Create() +debugger.SkipLLDBInitFiles(args.n) + +# Don't return from lldb function calls until the process stops. +debugger.SetAsync(False) + +# Create a target from a file and arch. +target = debugger.CreateTargetWithFileAndArch(args.target, lldb.LLDB_ARCH_DEFAULT) + +if not target: + print "Could not create target", args.target + sys.exit(1) + +if not args.script: + print "Interactive mode is not implemented." + sys.exit(1) + +import re +for command in args.script: + # Strip newline and whitespaces and split into words. + cmd = command[:-1].strip().split() + if not cmd: + continue + + print '> %s'% command + + try: + if re.match('^r|(run)$', cmd[0]): + error = lldb.SBError() + launchinfo = lldb.SBLaunchInfo([]) + launchinfo.SetWorkingDirectory(os.getcwd()) + process = target.Launch(launchinfo, error) + if not process or error.fail: + print error + state = process.GetState() + print "State = %d" % state + print "Could not launch process." + sys.exit(1) + + elif re.match('^b|(break)$', cmd[0]) and len(cmd) == 2: + if re.match('[0-9]+', cmd[1]): + # b line + mainfile = target.FindFunctions('main')[0].compile_unit.file + print target.BreakpointCreateByLocation(mainfile, int(cmd[1])) + else: + # b file:line + file, line = cmd.split(':') + print target.BreakpointCreateByLocation(file, int(line)) + + elif re.match('^ptype$', cmd[0]) and len(cmd) == 2: + # GDB's ptype has multiple incarnations depending on its + # argument (global variable, function, type). The definition + # here is for looking up the signature of a function and only + # if that fails it looks for a type with that name. + # Type lookup in LLDB would be "image lookup --type". + for elem in target.FindFunctions(cmd[1]): + print elem.function.type + continue + print target.FindFirstType(cmd[1]) + + elif re.match('^po$', cmd[0]) and len(cmd) > 1: + opts = lldb.SBExpressionOptions() + opts.SetFetchDynamicValue(True) + opts.SetCoerceResultToId(True) + print target.EvaluateExpression(' '.join(cmd[1:]), opts) + + elif re.match('^p|(print)$', cmd[0]) and len(cmd) > 1: + opts = lldb.SBExpressionOptions() + print target.EvaluateExpression(' '.join(cmd[1:]), opts) + + elif re.match('^q|(quit)$', cmd[0]): + sys.exit(0) + + else: + print debugger.HandleCommand(' '.join(cmd)) + + except SystemExit, e: raise e + except: + print 'Could not handle the command "%s"' % ' '.join(cmd) + diff --git a/debuginfo-tests/nested-struct.cpp b/debuginfo-tests/nested-struct.cpp index 5a626c5418f..22f2344e79b 100644 --- a/debuginfo-tests/nested-struct.cpp +++ b/debuginfo-tests/nested-struct.cpp @@ -6,7 +6,7 @@ // gdb crashes in such cases. // DEBUGGER: ptype foo -// CHECK: type = int (void) +// CHECK: int (void) int foo() { struct Local { diff --git a/debuginfo-tests/sret.cpp b/debuginfo-tests/sret.cpp index 1903cdda53b..6405bde0d03 100644 --- a/debuginfo-tests/sret.cpp +++ b/debuginfo-tests/sret.cpp @@ -5,9 +5,10 @@ // DEBUGGER: break 62 // DEBUGGER: r // DEBUGGER: p a -// CHECK: $1 = { -// CHECK: _vptr$A = -// CHECK: m_int = 12 +// CHECK: ${{[0-9]+}} = { +// LLDB does not print artificial members. +// CHECK-NEXT: {{(_vptr\$A =)|(m_int = 12)}} +// CHECK-NEXT: {{(m_int = 12)|(})}} class A { -- cgit v1.2.3