]>
git.saurik.com Git - apple/xnu.git/blob - tools/lldbmacros/kdp.py
5 current_KDP_mode
= "swhosted"
7 def GetKDPPacketHeaderInt(request
=0, is_reply
=False, seq
=0, length
=0, key
=0):
8 """ create a 64 bit number that could be saved as pkt_hdr_t
10 request:int - 7 bit kdp_req_t request type
11 is_reply:bool - False => request, True => reply
12 seq: int - 8 sequence number within session
13 length: int - 16 bit length of entire pkt including hdr
14 key: int - session key
16 int - 64 bit number to be saved in memory
21 retval
= (seq
<< 8) | retval
22 retval
= (length
<< 16) | retval
23 #retval = (retval << 32) | key
24 retval
= (key
<< 32) | retval
28 def KDPDumpInfo(subcmd
, file_name
="", dest_ip
="", router_ip
="", port
=0):
29 """ Setup the state for DUMP INFO commands for sending coredump etc
31 if "kdp" != GetConnectionProtocol():
32 print "Target is not connected over kdp. Nothing to do here."
34 input_address
= unsigned(addressof(kern
.globals.manual_pkt
.input))
35 len_address
= unsigned(addressof(kern
.globals.manual_pkt
.len))
36 data_address
= unsigned(addressof(kern
.globals.manual_pkt
.data
))
37 if not WriteInt32ToMemoryAddress(0, input_address
):
40 kdp_pkt_size
= GetType('kdp_dumpinfo_req_t').GetByteSize()
41 if not WriteInt32ToMemoryAddress(kdp_pkt_size
, len_address
):
44 data_addr
= int(addressof(kern
.globals.manual_pkt
))
45 pkt
= kern
.GetValueFromAddress(data_addr
, 'kdp_dumpinfo_req_t *')
46 if len(file_name
) > 49:
47 file_name
= file_name
[:49]
49 dest_ip
= dest_ip
[:15]
50 if len(router_ip
) > 15:
51 router_ip
= router_ip
[:15]
53 header_value
=GetKDPPacketHeaderInt(request
=GetEnumValue('kdp_req_t::KDP_DUMPINFO'), length
=kdp_pkt_size
)
54 # 0x1f is same as KDP_DUMPINFO
55 if ( WriteInt64ToMemoryAddress((header_value
), int(addressof(pkt
.hdr
))) and
56 WriteInt32ToMemoryAddress(subcmd
, int(addressof(pkt
.type))) and
57 WriteStringToMemoryAddress(file_name
, int(addressof(pkt
.name
))) and
58 WriteStringToMemoryAddress(dest_ip
, int(addressof(pkt
.destip
))) and
59 WriteStringToMemoryAddress(router_ip
, int(addressof(pkt
.routerip
)))
61 #We have saved important data successfully
63 if not WriteInt32ToMemoryAddress(port
, int(addressof(pkt
.port
))):
65 if WriteInt32ToMemoryAddress(1, input_address
):
69 @lldb_command('sendcore')
70 def KDPSendCore(cmd_args
=None):
71 """ Configure kernel to send a coredump to the specified IP
72 Syntax: sendcore <IP address> [filename]
73 Configure the kernel to transmit a kernel coredump to a server (kdumpd)
74 at the specified IP address. This is useful when the remote target has
75 not been previously configured to transmit coredumps, and you wish to
76 preserve kernel state for later examination. NOTE: You must issue a "continue"
77 command after using this macro to trigger the kernel coredump. The kernel
78 will resume waiting in the debugger after completion of the coredump. You
79 may disable coredumps by executing the "disablecore" macro. You can
80 optionally specify the filename to be used for the generated core file.
83 if cmd_args
== None or len(cmd_args
) < 1:
84 print KDPSendCore
.__doc
__
86 ip_address
= cmd_args
[0]
89 filename
= cmd_args
[1].strip()
90 retval
= KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_CORE'), file_name
=filename
, dest_ip
=ip_address
)
92 print "Remote system has been setup for coredump. Please detach/continue the system. "
95 print "Something went wrong. Failed to setup the coredump on the target."
99 @lldb_command('sendsyslog')
100 def KDPSendSyslog(cmd_args
=None):
101 """ Configure kernel to send a system log to the specified IP
102 Syntax: sendsyslog <IP address> [filename]
103 Configure the kernel to transmit a kernel system log to a server (kdumpd)
104 at the specified IP address. NOTE: You must issue a "continue"
105 command after using this macro to trigger the kernel system log. The kernel
106 will resume waiting in the debugger after completion. You can optionally
107 specify the name to be used for the generated system log.
109 if cmd_args
== None or len(cmd_args
) < 1:
110 print KDPSendSyslog
.__doc
__
112 ip_address
= cmd_args
[0]
114 if len(cmd_args
) >=2:
115 filename
= cmd_args
[1].strip()
116 retval
= KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SYSTEMLOG'), file_name
= filename
, dest_ip
= ip_address
)
118 print "Remote system has been setup to send system log. please detach/continue the system."
121 print "Something went wrong. Failed to setup the systemlog on the target."
124 @lldb_command('sendpaniclog')
125 def KDPSendPaniclog(cmd_args
=None):
126 """ Configure kernel to send a panic log to the specified IP
127 Syntax: sendpaniclog <IP address> [filename]
128 Configure the kernel to transmit a kernel paniclog to a server (kdumpd)
129 at the specified IP address. NOTE: You must issue a "continue"
130 command after using this macro to trigger the kernel panic log. The kernel
131 will resume waiting in the debugger after completion. You can optionally
132 specify the name to be used for the generated panic log.
134 if cmd_args
== None or len(cmd_args
) < 1:
135 print KDPSendPaniclog
.__doc
__
137 ip_address
= cmd_args
[0]
139 if len(cmd_args
) >=2:
140 filename
= cmd_args
[1].strip()
141 retval
= KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_PANICLOG'), file_name
= filename
, dest_ip
= ip_address
)
143 print "Remote system has been setup to send panic log. please detach/continue the system."
146 print "Something went wrong. Failed to setup the paniclog on the target."
150 @lldb_command('disablecore')
151 def KDPDisableCore(cmd_args
=None):
152 """ Configure the kernel to disable coredump transmission
153 Reconfigures the kernel so that it no longer transmits kernel coredumps. This
154 complements the "sendcore" macro, but it may be used if the kernel has been
155 configured to transmit coredumps through boot-args as well.
158 retval
= KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_DISABLE'))
160 print "Disabled coredump functionality on remote system."
162 print "Failed to disable coredump functionality."
165 @lldb_command('resume_on')
166 def KDPResumeON(cmd_args
=None):
167 """ The target system will resume when detaching or exiting from lldb.
168 This is the default behavior.
170 subcmd
= GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SETINFO') |
GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_RESUME')
171 retval
= KDPDumpInfo(subcmd
)
173 print "Target system will resume on detaching from lldb."
175 print "Failed to enable resume functionality."
178 @lldb_command('resume_off')
179 def KDPResumeOFF(cmd_args
=None):
180 """ The target system will not resume when detaching or exiting from lldb.
182 subcmd
= GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SETINFO') |
GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_NORESUME')
183 retval
= KDPDumpInfo(subcmd
)
185 print "Target system will not resume on detaching from lldb."
187 print "Failed to disable resume functionality."
192 @lldb_command('getdumpinfo')
193 def KDPGetDumpInfo(cmd_args
=None):
194 """ Retrieve the current remote dump settings.
196 if not KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_GETINFO')):
197 print "Failed to get dump settings."
199 dumpinfo
= Cast(addressof(kern
.globals.manual_pkt
.data
), 'kdp_dumpinfo_reply_t *')
200 target_dump_type
= int(dumpinfo
.type)
201 if target_dump_type
& GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_REBOOT'):
202 print "System will reboot after kernel info gets dumped."
204 print "System will not reboot after kernel info gets dumped."
205 if target_dump_type
& GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_RESUME'):
206 print "System will allow a re-attach after KDP disconnect."
208 print "System will not allow a re-attach after KDP disconnect."
209 target_dump_type
= target_dump_type
& GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_MASK')
210 if target_dump_type
== GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_DISABLE'):
211 print "Kernel not setup for remote dumps."
214 if target_dump_type
== GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_CORE'):
215 kern_dump_type
= "Core File"
216 elif target_dump_type
== GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_PANICLOG'):
217 kern_dump_type
= "Panic Log"
218 elif target_dump_type
== GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SYSTEMLOG'):
219 kern_dump_type
= "System Log"
220 print "Kernel dump type:" + kern_dump_type
221 fname
= "(autogenerated)"
222 if int(dumpinfo
.name
[0]) != 0:
223 fname
= str(dumpinfo
.name
)
224 print "Filename: " + fname
225 print "Network Info: {:s} [{:d}] , Router: {:s}".format(dumpinfo
.destip
, dumpinfo
.port
, dumpinfo
.routerip
)
226 # end of get dump info
229 @lldb_command('kdp-reenter')
230 def KDPReenter(cmd_args
=None):
231 """ Schedules reentry into the debugger
232 after <seconds> seconds, and resumes the target.
233 usage: kdp-reenter <seconds>
235 if len(cmd_args
) < 1:
236 print "Please provide valid time in seconds"
237 print KDPReenter
.__doc
__
240 if "kdp" != GetConnectionProtocol():
241 print "Target is not connected over kdp. Nothing to do here."
244 num_seconds
= ArgumentStringToInt(cmd_args
[0])
245 milliseconds_to_sleep
= num_seconds
* 1000
246 if WriteInt32ToMemoryAddress(milliseconds_to_sleep
, addressof(kern
.globals.kdp_reentry_deadline
)):
247 lldb
.debugger
.HandleCommand('process continue')
249 print "Failed to setup kdp-reentry."
252 @lldb_command('kdp-reboot')
253 def KDPReboot(cmd_args
=None):
254 """ Restart the remote target
256 if "kdp" != GetConnectionProtocol():
257 print "Target is not connected over kdp. Nothing to do here."
260 print "Rebooting the remote machine."
261 lldb
.debugger
.HandleCommand('process plugin packet send --command 0x13')
262 lldb
.debugger
.HandleCommand('detach')
265 @lldb_command('setdumpinfo')
266 def KDPSetDumpInfo(cmd_args
=None):
267 """ Configure the current remote dump settings.
268 Specify "" if you want to use the defaults (filename) or previously configured
269 settings (ip/router). Specify 0 for the port if you wish to
270 use the previously configured/default setting for that.
271 Syntax: setdumpinfo <filename> <ip> <router> <port>
274 print KDPSetDumpInfo
.__doc
__
276 if len(cmd_args
) < 4:
277 print "Not enough arguments."
278 print KDPSetDumpInfo
.__doc
__
280 portnum
= ArgumentStringToInt(cmd_args
[3])
281 retval
= KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SETINFO'), cmd_args
[0], cmd_args
[1], cmd_args
[2], portnum
)
283 print "Successfully saved the dumpinfo."
285 print "Failed to save the dumpinfo."
288 @lldb_command('kdpmode')
289 def KDPMode(cmd_args
=None):
291 Change KDP mode between software hosted and hardware probe.
292 When lldb is connected to a KDP server backed by a hardware debug tool
293 setting this to 'hwprobe' enables physical memory access.
295 swhosted: LLDB is connected to the target using a serial or socket connection.
296 hwprobe: LLDB is connected to the target using a hardware probe.
298 usage: kdpmode <mode>
299 mode: 'swhosted' or 'hwprobe'
301 global current_KDP_mode
303 if cmd_args
== None or len(cmd_args
) == 0:
304 return current_KDP_mode
305 if len(cmd_args
) > 1 or cmd_args
[0] not in {'swhosted', 'hwprobe'}
:
306 print "Invalid Arguments", KDPMode
.__doc
__
308 current_KDP_mode
= cmd_args
[0]