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."""
20 target
= frame
.GetThread().GetProcess().GetTarget()
25 mo
= re
.match("^([0-9]+)$", linespec
)
28 # print "Matched <linenum>"
29 line_number
= int(mo
.group(1))
30 line_entry
= frame
.GetLineEntry()
31 if not line_entry
.IsValid():
33 "Specified a line in the current file, but the current frame doesn't have line table information.")
35 breakpoint
= target
.BreakpointCreateByLocation(
36 line_entry
.GetFileSpec(), line_number
)
39 mo
= re
.match("^\+([0-9]+)$", linespec
)
42 # print "Matched +<count>"
43 line_number
= int(mo
.group(1))
44 line_entry
= frame
.GetLineEntry()
45 if not line_entry
.IsValid():
47 "Specified a line in the current file, but the current frame doesn't have line table information.")
49 breakpoint
= target
.BreakpointCreateByLocation(
50 line_entry
.GetFileSpec(), (line_entry
.GetLine() + line_number
))
53 mo
= re
.match("^\-([0-9]+)$", linespec
)
56 # print "Matched -<count>"
57 line_number
= int(mo
.group(1))
58 line_entry
= frame
.GetLineEntry()
59 if not line_entry
.IsValid():
61 "Specified a line in the current file, but the current frame doesn't have line table information.")
63 breakpoint
= target
.BreakpointCreateByLocation(
64 line_entry
.GetFileSpec(), (line_entry
.GetLine() - line_number
))
67 mo
= re
.match("^(.*):([0-9]+)$", linespec
)
70 # print "Matched <filename>:<linenum>"
71 file_name
= mo
.group(1)
72 line_number
= int(mo
.group(2))
73 breakpoint
= target
.BreakpointCreateByLocation(
74 file_name
, line_number
)
77 mo
= re
.match("\*((0x)?([0-9a-f]+))$", linespec
)
80 # print "Matched <address-expression>"
81 address
= int(mo
.group(1), base
=0)
82 breakpoint
= target
.BreakpointCreateByAddress(address
)
85 # print "Trying <function-name>"
86 breakpoint
= target
.BreakpointCreateByName(linespec
)
88 num_locations
= breakpoint
.GetNumLocations()
90 if (num_locations
== 0):
92 "The line specification provided doesn't resolve to any addresses.")
96 for location_index
in range(num_locations
):
97 location
= breakpoint
.GetLocationAtIndex(location_index
)
98 addr_list
.append(location
.GetAddress())
100 target
.BreakpointDelete(breakpoint
.GetID())
106 return """ Sets the program counter to a specific address.
108 Syntax: jump <linespec> [<location-id>]
110 Command Options Usage:
114 jump <filename>:<linenum>
116 jump *<address-expression>
118 <location-id> serves to disambiguate when multiple locations could be meant."""
121 def jump(debugger
, command
, result
, internal_dict
):
123 result
.AppendMessage(usage_string())
125 args
= command
.split()
127 if not debugger
.IsValid():
128 result
.AppendMessage("Invalid debugger!")
131 target
= debugger
.GetSelectedTarget()
132 if not target
.IsValid():
133 result
.AppendMessage("jump requires a valid target.")
136 process
= target
.GetProcess()
137 if not process
.IsValid():
138 result
.AppendMessage("jump requires a valid process.")
141 thread
= process
.GetSelectedThread()
142 if not thread
.IsValid():
143 result
.AppendMessage("jump requires a valid thread.")
146 frame
= thread
.GetSelectedFrame()
147 if not frame
.IsValid():
148 result
.AppendMessage("jump requires a valid frame.")
151 addresses
= parse_linespec(args
[0], frame
, result
)
153 stream
= lldb
.SBStream()
155 if len(addresses
) == 0:
158 desired_address
= addresses
[0]
160 if len(addresses
) > 1:
162 desired_index
= int(args
[1])
163 if (desired_index
>= 0) and (desired_index
< len(addresses
)):
164 desired_address
= addresses
[desired_index
]
166 result
.AppendMessage(
169 " is not one of the options.")
173 result
.AppendMessage(
174 "The specified location resolves to multiple targets.")
175 for address
in addresses
:
177 address
.GetDescription(stream
)
178 result
.AppendMessage(
184 result
.AppendMessage(
185 "Please type 'jump " +
187 " <location-id>' to choose one.")
190 frame
.SetPC(desired_address
.GetLoadAddress(target
))
192 def __lldb_init_module(debugger
, internal_dict
):
193 # Module is being run inside the LLDB interpreter
194 jump
.__doc
__ = usage_string()
195 debugger
.HandleCommand('command script add -o -f jump.jump jump')
196 print('The "jump" command has been installed, type "help jump" or "jump <ENTER>" for detailed help.')