[OpenACC] Enable 'attach' clause for combined constructs
[llvm-project.git] / lldb / examples / python / jump.py
blobe086df5fd1528286e9ba8f2732e57e1dc7eeac02
1 import lldb
2 import re
5 def parse_linespec(linespec, frame, result):
6 """Handles a subset of GDB-style linespecs. Specifically:
8 number - A line in the current file
9 +offset - The line /offset/ lines after this line
10 -offset - The line /offset/ lines before this line
11 filename:number - Line /number/ in file /filename/
12 function - The start of /function/
13 *address - The pointer target of /address/, which must be a literal (but see `` in LLDB)
15 We explicitly do not handle filename:function because it is ambiguous in Objective-C.
17 This function returns a list of addresses."""
19 breakpoint = None
20 target = frame.GetThread().GetProcess().GetTarget()
22 matched = False
24 if not matched:
25 mo = re.match("^([0-9]+)$", linespec)
26 if mo is not None:
27 matched = True
28 # print "Matched <linenum>"
29 line_number = int(mo.group(1))
30 line_entry = frame.GetLineEntry()
31 if not line_entry.IsValid():
32 result.AppendMessage(
33 "Specified a line in the current file, but the current frame doesn't have line table information."
35 return
36 breakpoint = target.BreakpointCreateByLocation(
37 line_entry.GetFileSpec(), line_number
40 if not matched:
41 mo = re.match("^\+([0-9]+)$", linespec)
42 if mo is not None:
43 matched = True
44 # print "Matched +<count>"
45 line_number = int(mo.group(1))
46 line_entry = frame.GetLineEntry()
47 if not line_entry.IsValid():
48 result.AppendMessage(
49 "Specified a line in the current file, but the current frame doesn't have line table information."
51 return
52 breakpoint = target.BreakpointCreateByLocation(
53 line_entry.GetFileSpec(), (line_entry.GetLine() + line_number)
56 if not matched:
57 mo = re.match("^\-([0-9]+)$", linespec)
58 if mo is not None:
59 matched = True
60 # print "Matched -<count>"
61 line_number = int(mo.group(1))
62 line_entry = frame.GetLineEntry()
63 if not line_entry.IsValid():
64 result.AppendMessage(
65 "Specified a line in the current file, but the current frame doesn't have line table information."
67 return
68 breakpoint = target.BreakpointCreateByLocation(
69 line_entry.GetFileSpec(), (line_entry.GetLine() - line_number)
72 if not matched:
73 mo = re.match("^(.*):([0-9]+)$", linespec)
74 if mo is not None:
75 matched = True
76 # print "Matched <filename>:<linenum>"
77 file_name = mo.group(1)
78 line_number = int(mo.group(2))
79 breakpoint = target.BreakpointCreateByLocation(file_name, line_number)
81 if not matched:
82 mo = re.match("\*((0x)?([0-9a-f]+))$", linespec)
83 if mo is not None:
84 matched = True
85 # print "Matched <address-expression>"
86 address = int(mo.group(1), base=0)
87 breakpoint = target.BreakpointCreateByAddress(address)
89 if not matched:
90 # print "Trying <function-name>"
91 breakpoint = target.BreakpointCreateByName(linespec)
93 num_locations = breakpoint.GetNumLocations()
95 if num_locations == 0:
96 result.AppendMessage(
97 "The line specification provided doesn't resolve to any addresses."
100 addr_list = []
102 for location_index in range(num_locations):
103 location = breakpoint.GetLocationAtIndex(location_index)
104 addr_list.append(location.GetAddress())
106 target.BreakpointDelete(breakpoint.GetID())
108 return addr_list
111 def usage_string():
112 return """ Sets the program counter to a specific address.
114 Syntax: jump <linespec> [<location-id>]
116 Command Options Usage:
117 jump <linenum>
118 jump +<count>
119 jump -<count>
120 jump <filename>:<linenum>
121 jump <function-name>
122 jump *<address-expression>
124 <location-id> serves to disambiguate when multiple locations could be meant."""
127 def jump(debugger, command, result, internal_dict):
128 if command == "":
129 result.AppendMessage(usage_string())
131 args = command.split()
133 if not debugger.IsValid():
134 result.AppendMessage("Invalid debugger!")
135 return
137 target = debugger.GetSelectedTarget()
138 if not target.IsValid():
139 result.AppendMessage("jump requires a valid target.")
140 return
142 process = target.GetProcess()
143 if not process.IsValid():
144 result.AppendMessage("jump requires a valid process.")
145 return
147 thread = process.GetSelectedThread()
148 if not thread.IsValid():
149 result.AppendMessage("jump requires a valid thread.")
150 return
152 frame = thread.GetSelectedFrame()
153 if not frame.IsValid():
154 result.AppendMessage("jump requires a valid frame.")
155 return
157 addresses = parse_linespec(args[0], frame, result)
159 stream = lldb.SBStream()
161 if len(addresses) == 0:
162 return
164 desired_address = addresses[0]
166 if len(addresses) > 1:
167 if len(args) == 2:
168 desired_index = int(args[1])
169 if (desired_index >= 0) and (desired_index < len(addresses)):
170 desired_address = addresses[desired_index]
171 else:
172 result.AppendMessage(
173 "Desired index " + args[1] + " is not one of the options."
175 return
176 else:
177 index = 0
178 result.AppendMessage("The specified location resolves to multiple targets.")
179 for address in addresses:
180 stream.Clear()
181 address.GetDescription(stream)
182 result.AppendMessage(
183 " Location ID " + str(index) + ": " + stream.GetData()
185 index = index + 1
186 result.AppendMessage(
187 "Please type 'jump " + command + " <location-id>' to choose one."
189 return
191 frame.SetPC(desired_address.GetLoadAddress(target))
194 def __lldb_init_module(debugger, internal_dict):
195 # Module is being run inside the LLDB interpreter
196 jump.__doc__ = usage_string()
197 debugger.HandleCommand("command script add -o -f jump.jump jump")
198 print(
199 'The "jump" command has been installed, type "help jump" or "jump <ENTER>" for detailed help.'