]>
git.saurik.com Git - apple/xnu.git/blob - tools/lldbmacros/kdp.py
5 def GetKDPPacketHeaderInt(request
=0, is_reply
=False, seq
=0, length
=0, key
=0):
6 """ create a 64 bit number that could be saved as pkt_hdr_t
8 request:int - 7 bit kdp_req_t request type
9 is_reply:bool - False => request, True => reply
10 seq: int - 8 sequence number within session
11 length: int - 16 bit length of entire pkt including hdr
12 key: int - session key
14 int - 64 bit number to be saved in memory
19 retval
= (seq
<< 8) | retval
20 retval
= (length
<< 16) | retval
21 #retval = (retval << 32) | key
22 retval
= (key
<< 32) | retval
26 def KDPDumpInfo(subcmd
, file_name
="", dest_ip
="", router_ip
="", port
=0):
27 """ Setup the state for DUMP INFO commands for sending coredump etc
29 if "kdp" != GetConnectionProtocol():
30 print "Target is not connected over kdp. Nothing to do here."
32 input_address
= unsigned(addressof(kern
.globals.manual_pkt
.input))
33 len_address
= unsigned(addressof(kern
.globals.manual_pkt
.len))
34 data_address
= unsigned(addressof(kern
.globals.manual_pkt
.data
))
35 if not WriteInt32ToMemoryAddress(0, input_address
):
38 kdp_pkt_size
= GetType('kdp_dumpinfo_req_t').GetByteSize()
39 if not WriteInt32ToMemoryAddress(kdp_pkt_size
, len_address
):
42 data_addr
= int(addressof(kern
.globals.manual_pkt
))
43 pkt
= kern
.GetValueFromAddress(data_addr
, 'kdp_dumpinfo_req_t *')
44 if len(file_name
) > 49:
45 file_name
= file_name
[:49]
47 dest_ip
= dest_ip
[:15]
48 if len(router_ip
) > 15:
49 router_ip
= router_ip
[:15]
51 header_value
=GetKDPPacketHeaderInt(request
=GetEnumValue('kdp_req_t::KDP_DUMPINFO'), length
=kdp_pkt_size
)
52 # 0x1f is same as KDP_DUMPINFO
53 if ( WriteInt64ToMemoryAddress((header_value
), int(addressof(pkt
.hdr
))) and
54 WriteInt32ToMemoryAddress(subcmd
, int(addressof(pkt
.type))) and
55 WriteStringToMemoryAddress(file_name
, int(addressof(pkt
.name
))) and
56 WriteStringToMemoryAddress(dest_ip
, int(addressof(pkt
.destip
))) and
57 WriteStringToMemoryAddress(router_ip
, int(addressof(pkt
.routerip
)))
59 #We have saved important data successfully
61 if not WriteInt32ToMemoryAddress(port
, int(addressof(pkt
.port
))):
63 if WriteInt32ToMemoryAddress(1, input_address
):
67 @lldb_command('sendcore')
68 def KDPSendCore(cmd_args
=None):
69 """ Configure kernel to send a coredump to the specified IP
70 Syntax: sendcore <IP address> [filename]
71 Configure the kernel to transmit a kernel coredump to a server (kdumpd)
72 at the specified IP address. This is useful when the remote target has
73 not been previously configured to transmit coredumps, and you wish to
74 preserve kernel state for later examination. NOTE: You must issue a "continue"
75 command after using this macro to trigger the kernel coredump. The kernel
76 will resume waiting in the debugger after completion of the coredump. You
77 may disable coredumps by executing the "disablecore" macro. You can
78 optionally specify the filename to be used for the generated core file.
81 if cmd_args
== None or len(cmd_args
) < 1:
82 print KDPSendCore
.__doc
__
84 ip_address
= cmd_args
[0]
87 filename
= cmd_args
[1].strip()
88 retval
= KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_CORE'), file_name
=filename
, dest_ip
=ip_address
)
90 print "Remote system has been setup for coredump. Please detach/continue the system. "
93 print "Something went wrong. Failed to setup the coredump on the target."
97 @lldb_command('sendsyslog')
98 def KDPSendSyslog(cmd_args
=None):
99 """ Configure kernel to send a system log to the specified IP
100 Syntax: sendsyslog <IP address> [filename]
101 Configure the kernel to transmit a kernel system log to a server (kdumpd)
102 at the specified IP address. NOTE: You must issue a "continue"
103 command after using this macro to trigger the kernel system log. The kernel
104 will resume waiting in the debugger after completion. You can optionally
105 specify the name to be used for the generated system log.
107 if cmd_args
== None or len(cmd_args
) < 1:
108 print KDPSendSyslog
.__doc
__
110 ip_address
= cmd_args
[0]
112 if len(cmd_args
) >=2:
113 filename
= cmd_args
[1].strip()
114 retval
= KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SYSTEMLOG'), file_name
= filename
, dest_ip
= ip_address
)
116 print "Remote system has been setup to send system log. please detach/continue the system."
119 print "Something went wrong. Failed to setup the systemlog on the target."
122 @lldb_command('sendpaniclog')
123 def KDPSendPaniclog(cmd_args
=None):
124 """ Configure kernel to send a panic log to the specified IP
125 Syntax: sendpaniclog <IP address> [filename]
126 Configure the kernel to transmit a kernel paniclog to a server (kdumpd)
127 at the specified IP address. NOTE: You must issue a "continue"
128 command after using this macro to trigger the kernel panic log. The kernel
129 will resume waiting in the debugger after completion. You can optionally
130 specify the name to be used for the generated panic log.
132 if cmd_args
== None or len(cmd_args
) < 1:
133 print KDPSendPaniclog
.__doc
__
135 ip_address
= cmd_args
[0]
137 if len(cmd_args
) >=2:
138 filename
= cmd_args
[1].strip()
139 retval
= KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_PANICLOG'), file_name
= filename
, dest_ip
= ip_address
)
141 print "Remote system has been setup to send panic log. please detach/continue the system."
144 print "Something went wrong. Failed to setup the paniclog on the target."
148 @lldb_command('disablecore')
149 def KDPDisableCore(cmd_args
=None):
150 """ Configure the kernel to disable coredump transmission
151 Reconfigures the kernel so that it no longer transmits kernel coredumps. This
152 complements the "sendcore" macro, but it may be used if the kernel has been
153 configured to transmit coredumps through boot-args as well.
156 retval
= KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_DISABLE'))
158 print "Disabled coredump functionality on remote system."
160 print "Failed to disable coredump functionality."
163 @lldb_command('resume_on')
164 def KDPResumeON(cmd_args
=None):
165 """ The target system will resume when detaching or exiting from lldb.
166 This is the default behavior.
168 subcmd
= GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SETINFO') |
GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_RESUME')
169 retval
= KDPDumpInfo(subcmd
)
171 print "Target system will resume on detaching from lldb."
173 print "Failed to enable resume functionality."
176 @lldb_command('resume_off')
177 def KDPResumeON(cmd_args
=None):
178 """ The target system will not resume when detaching or exiting from lldb.
180 subcmd
= GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SETINFO') |
GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_NORESUME')
181 retval
= KDPDumpInfo(subcmd
)
183 print "Target system will not resume on detaching from lldb."
185 print "Failed to disable resume functionality."
190 @lldb_command('getdumpinfo')
191 def KDPGetDumpInfo(cmd_args
=None):
192 """ Retrieve the current remote dump settings.
194 if not KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_GETINFO')):
195 print "Failed to get dump settings."
197 dumpinfo
= Cast(addressof(kern
.globals.manual_pkt
.data
), 'kdp_dumpinfo_reply_t *')
198 target_dump_type
= int(dumpinfo
.type)
199 if target_dump_type
& GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_REBOOT'):
200 print "System will reboot after kernel info gets dumped."
202 print "System will not reboot after kernel info gets dumped."
203 if target_dump_type
& GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_RESUME'):
204 print "System will allow a re-attach after KDP disconnect."
206 print "System will not allow a re-attach after KDP disconnect."
207 target_dump_type
= target_dump_type
& GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_MASK')
208 if target_dump_type
== GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_DISABLE'):
209 print "Kernel not setup for remote dumps."
212 if target_dump_type
== GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_CORE'):
213 kern_dump_type
= "Core File"
214 elif target_dump_type
== GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_PANICLOG'):
215 kern_dump_type
= "Panic Log"
216 elif target_dump_type
== GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SYSTEMLOG'):
217 kern_dump_type
= "System Log"
218 print "Kernel dump type:" + kern_dump_type
219 fname
= "(autogenerated)"
220 if int(dumpinfo
.name
[0]) != 0:
221 fname
= str(dumpinfo
.name
)
222 print "Filename: " + fname
223 print "Network Info: {:s} [{:d}] , Router: {:s}".format(dumpinfo
.destip
, dumpinfo
.port
, dumpinfo
.routerip
)
224 # end of get dump info
227 @lldb_command('kdp-reenter')
228 def KDPReenter(cmd_args
=None):
229 """ Schedules reentry into the debugger
230 after <seconds> seconds, and resumes the target.
231 usage: kdp-reenter <seconds>
233 if len(cmd_args
) < 1:
234 print "Please provide valid time in seconds"
235 print KDPReenter
.__doc
__
238 if "kdp" != GetConnectionProtocol():
239 print "Target is not connected over kdp. Nothing to do here."
242 num_seconds
= ArgumentStringToInt(cmd_args
[0])
243 milliseconds_to_sleep
= num_seconds
* 1000
244 if WriteInt32ToMemoryAddress(milliseconds_to_sleep
, addressof(kern
.globals.kdp_reentry_deadline
)):
245 lldb
.debugger
.HandleCommand('process continue')
247 print "Failed to setup kdp-reentry."
250 @lldb_command('kdp-reboot')
251 def KDPReboot(cmd_args
=None):
252 """ Restart the remote target
254 if "kdp" != GetConnectionProtocol():
255 print "Target is not connected over kdp. Nothing to do here."
258 print "Rebooting the remote machine."
259 lldb
.debugger
.HandleCommand('process plugin packet send --command 0x13')
260 lldb
.debugger
.HandleCommand('detach')
263 @lldb_command('setdumpinfo')
264 def KDPSetDumpInfo(cmd_args
=None):
265 """ Configure the current remote dump settings.
266 Specify "" if you want to use the defaults (filename) or previously configured
267 settings (ip/router). Specify 0 for the port if you wish to
268 use the previously configured/default setting for that.
269 Syntax: setdumpinfo <filename> <ip> <router> <port>
272 print KDPSetDumpInfo
.__doc
__
274 if len(cmd_args
) < 4:
275 print "Not enough arguments."
276 print KDPSetDumpInfo
.__doc
__
278 portnum
= ArgumentStringToInt(cmd_args
[3])
279 retval
= KDPDumpInfo(GetEnumValue('kdp_dumpinfo_t::KDP_DUMPINFO_SETINFO'), cmd_args
[0], cmd_args
[1], cmd_args
[2], portnum
)
281 print "Successfully saved the dumpinfo."
283 print "Failed to save the dumpinfo."