[mlir] Allow fallback from file line col range to loc (#124321)
[llvm-project.git] / cross-project-tests / debuginfo-tests / llgdb-tests / llgdb.py
blob6795d3b989a306fd3c14bc7eb63a899dcc6ec5bd
1 #!/usr/bin/env python3
2 """
3 A gdb-compatible frontend for lldb that implements just enough
4 commands to run the tests in the debuginfo-tests repository with lldb.
5 """
7 # ----------------------------------------------------------------------
8 # Auto-detect lldb python module.
9 import subprocess, platform, os, sys
11 try:
12 # Just try for LLDB in case PYTHONPATH is already correctly setup.
13 import lldb
14 except ImportError:
15 # Ask the command line driver for the path to the lldb module. Copy over
16 # the environment so that SDKROOT is propagated to xcrun.
17 command = (
18 ["xcrun", "lldb", "-P"] if platform.system() == "Darwin" else ["lldb", "-P"]
20 # Extend the PYTHONPATH if the path exists and isn't already there.
21 lldb_python_path = subprocess.check_output(command).decode("utf-8").strip()
22 if os.path.exists(lldb_python_path) and not sys.path.__contains__(lldb_python_path):
23 sys.path.append(lldb_python_path)
24 # Try importing LLDB again.
25 try:
26 import lldb
28 print('imported lldb from: "%s"' % lldb_python_path)
29 except ImportError:
30 print(
31 "error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly"
33 sys.exit(1)
34 # ----------------------------------------------------------------------
36 # Command line option handling.
37 import argparse
39 parser = argparse.ArgumentParser(description=__doc__)
40 parser.add_argument("--quiet", "-q", action="store_true", help="ignored")
41 parser.add_argument(
42 "-batch", action="store_true", help="exit after processing comand line"
44 parser.add_argument("-n", action="store_true", help="ignore .lldb file")
45 parser.add_argument(
46 "-x", dest="script", type=argparse.FileType("r"), help="execute commands from file"
48 parser.add_argument("target", help="the program to debug")
49 args = parser.parse_args()
52 # Create a new debugger instance.
53 debugger = lldb.SBDebugger.Create()
54 debugger.SkipLLDBInitFiles(args.n)
56 # Make sure to clean up the debugger on exit.
57 import atexit
60 def on_exit():
61 debugger.Terminate()
64 atexit.register(on_exit)
66 # Don't return from lldb function calls until the process stops.
67 debugger.SetAsync(False)
69 # Create a target from a file and arch.
70 arch = os.popen("file " + args.target).read().split()[-1]
71 target = debugger.CreateTargetWithFileAndArch(args.target, arch)
73 if not target:
74 print("Could not create target %s" % args.target)
75 sys.exit(1)
77 if not args.script:
78 print("Interactive mode is not implemented.")
79 sys.exit(1)
81 import re
83 for command in args.script:
84 # Strip newline and whitespaces and split into words.
85 cmd = command[:-1].strip().split()
86 if not cmd:
87 continue
89 print("> %s" % command[:-1])
91 try:
92 if re.match("^r|(run)$", cmd[0]):
93 error = lldb.SBError()
94 launchinfo = lldb.SBLaunchInfo([])
95 launchinfo.SetWorkingDirectory(os.getcwd())
96 process = target.Launch(launchinfo, error)
97 print(error)
98 if not process or error.fail:
99 state = process.GetState()
100 print("State = %d" % state)
101 print(
103 ERROR: Could not launch process.
104 NOTE: There are several reasons why this may happen:
105 * Root needs to run "DevToolsSecurity --enable".
106 * Older versions of lldb cannot launch more than one process simultaneously.
109 sys.exit(1)
111 elif re.match("^b|(break)$", cmd[0]) and len(cmd) == 2:
112 if re.match("[0-9]+", cmd[1]):
113 # b line
114 mainfile = target.FindFunctions("main")[0].compile_unit.file
115 print(target.BreakpointCreateByLocation(mainfile, int(cmd[1])))
116 else:
117 # b file:line
118 file, line = cmd[1].split(":")
119 print(target.BreakpointCreateByLocation(file, int(line)))
121 elif re.match("^ptype$", cmd[0]) and len(cmd) == 2:
122 # GDB's ptype has multiple incarnations depending on its
123 # argument (global variable, function, type). The definition
124 # here is for looking up the signature of a function and only
125 # if that fails it looks for a type with that name.
126 # Type lookup in LLDB would be "image lookup --type".
127 for elem in target.FindFunctions(cmd[1]):
128 print(elem.function.type)
129 continue
130 print(target.FindFirstType(cmd[1]))
132 elif re.match("^po$", cmd[0]) and len(cmd) > 1:
133 try:
134 opts = lldb.SBExpressionOptions()
135 opts.SetFetchDynamicValue(True)
136 opts.SetCoerceResultToId(True)
137 print(target.EvaluateExpression(" ".join(cmd[1:]), opts))
138 except:
139 # FIXME: This is a fallback path for the lab.llvm.org
140 # buildbot running OS X 10.7; it should be removed.
141 thread = process.GetThreadAtIndex(0)
142 frame = thread.GetFrameAtIndex(0)
143 print(frame.EvaluateExpression(" ".join(cmd[1:])))
145 elif re.match("^p|(print)$", cmd[0]) and len(cmd) > 1:
146 thread = process.GetThreadAtIndex(0)
147 frame = thread.GetFrameAtIndex(0)
148 print(frame.EvaluateExpression(" ".join(cmd[1:])))
150 elif re.match("^n|(next)$", cmd[0]):
151 thread = process.GetThreadAtIndex(0)
152 thread.StepOver()
154 elif re.match("^q|(quit)$", cmd[0]):
155 sys.exit(0)
157 else:
158 print(debugger.HandleCommand(" ".join(cmd)))
160 except SystemExit:
161 raise
162 except:
163 print('Could not handle the command "%s"' % " ".join(cmd))