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."
36 breakpoint
= target
.BreakpointCreateByLocation(
37 line_entry
.GetFileSpec(), line_number
41 mo
= re
.match("^\+([0-9]+)$", linespec
)
44 # print "Matched +<count>"
45 line_number
= int(mo
.group(1))
46 line_entry
= frame
.GetLineEntry()
47 if not line_entry
.IsValid():
49 "Specified a line in the current file, but the current frame doesn't have line table information."
52 breakpoint
= target
.BreakpointCreateByLocation(
53 line_entry
.GetFileSpec(), (line_entry
.GetLine() + line_number
)
57 mo
= re
.match("^\-([0-9]+)$", linespec
)
60 # print "Matched -<count>"
61 line_number
= int(mo
.group(1))
62 line_entry
= frame
.GetLineEntry()
63 if not line_entry
.IsValid():
65 "Specified a line in the current file, but the current frame doesn't have line table information."
68 breakpoint
= target
.BreakpointCreateByLocation(
69 line_entry
.GetFileSpec(), (line_entry
.GetLine() - line_number
)
73 mo
= re
.match("^(.*):([0-9]+)$", linespec
)
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
)
82 mo
= re
.match("\*((0x)?([0-9a-f]+))$", linespec
)
85 # print "Matched <address-expression>"
86 address
= int(mo
.group(1), base
=0)
87 breakpoint
= target
.BreakpointCreateByAddress(address
)
90 # print "Trying <function-name>"
91 breakpoint
= target
.BreakpointCreateByName(linespec
)
93 num_locations
= breakpoint
.GetNumLocations()
95 if num_locations
== 0:
97 "The line specification provided doesn't resolve to any addresses."
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())
112 return """ Sets the program counter to a specific address.
114 Syntax: jump <linespec> [<location-id>]
116 Command Options Usage:
120 jump <filename>:<linenum>
122 jump *<address-expression>
124 <location-id> serves to disambiguate when multiple locations could be meant."""
127 def jump(debugger
, command
, result
, internal_dict
):
129 result
.AppendMessage(usage_string())
131 args
= command
.split()
133 if not debugger
.IsValid():
134 result
.AppendMessage("Invalid debugger!")
137 target
= debugger
.GetSelectedTarget()
138 if not target
.IsValid():
139 result
.AppendMessage("jump requires a valid target.")
142 process
= target
.GetProcess()
143 if not process
.IsValid():
144 result
.AppendMessage("jump requires a valid process.")
147 thread
= process
.GetSelectedThread()
148 if not thread
.IsValid():
149 result
.AppendMessage("jump requires a valid thread.")
152 frame
= thread
.GetSelectedFrame()
153 if not frame
.IsValid():
154 result
.AppendMessage("jump requires a valid frame.")
157 addresses
= parse_linespec(args
[0], frame
, result
)
159 stream
= lldb
.SBStream()
161 if len(addresses
) == 0:
164 desired_address
= addresses
[0]
166 if len(addresses
) > 1:
168 desired_index
= int(args
[1])
169 if (desired_index
>= 0) and (desired_index
< len(addresses
)):
170 desired_address
= addresses
[desired_index
]
172 result
.AppendMessage(
173 "Desired index " + args
[1] + " is not one of the options."
178 result
.AppendMessage("The specified location resolves to multiple targets.")
179 for address
in addresses
:
181 address
.GetDescription(stream
)
182 result
.AppendMessage(
183 " Location ID " + str(index
) + ": " + stream
.GetData()
186 result
.AppendMessage(
187 "Please type 'jump " + command
+ " <location-id>' to choose one."
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")
199 'The "jump" command has been installed, type "help jump" or "jump <ENTER>" for detailed help.'