1 | /* |
2 | * Copyright (c) 2000-2020 Apple Inc. All rights reserved. |
3 | * |
4 | * @Apple_LICENSE_HEADER_START@ |
5 | * |
6 | * The contents of this file constitute Original Code as defined in and |
7 | * are subject to the Apple Public Source License Version 1.1 (the |
8 | * "License"). You may not use this file except in compliance with the |
9 | * License. Please obtain a copy of the License at |
10 | * http://www.apple.com/publicsource and read it before using this file. |
11 | * |
12 | * This Original Code and all software distributed under the License are |
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, |
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the |
17 | * License for the specific language governing rights and limitations |
18 | * under the License. |
19 | * |
20 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
21 | */ |
22 | |
23 | #include <sys/kdebug_common.h> |
24 | #include <sys/kdebug_triage.h> |
25 | |
26 | #define TRIAGE_KDCOPYBUF_COUNT 128 |
27 | #define TRIAGE_KDCOPYBUF_SIZE (TRIAGE_KDCOPYBUF_COUNT * sizeof(kd_buf)) |
28 | |
29 | struct kd_control kd_control_triage = { |
30 | .kds_free_list = { .raw = KDS_PTR_NULL }, |
31 | .mode = KDEBUG_MODE_TRIAGE, |
32 | .kdebug_events_per_storage_unit = TRIAGE_EVENTS_PER_STORAGE_UNIT, |
33 | .kdebug_min_storage_units_per_cpu = TRIAGE_MIN_STORAGE_UNITS_PER_CPU, |
34 | .kdebug_kdcopybuf_count = TRIAGE_KDCOPYBUF_COUNT, |
35 | .kdebug_kdcopybuf_size = TRIAGE_KDCOPYBUF_SIZE, |
36 | .kdc_flags = KDBG_DEBUGID_64, |
37 | .kdc_emit = KDEMIT_DISABLE, |
38 | .kdc_oldest_time = 0 |
39 | }; |
40 | |
41 | struct kd_buffer kd_buffer_triage = { |
42 | .kdb_event_count = 0, |
43 | .kdb_storage_count = 0, |
44 | .kdb_storage_threshold = 0, |
45 | .kdb_region_count = 0, |
46 | .kdb_info = NULL, |
47 | .kd_bufs = NULL, |
48 | .kdcopybuf = NULL |
49 | }; |
50 | |
51 | |
52 | static LCK_GRP_DECLARE(ktriage_grp, "ktriage" ); |
53 | static LCK_MTX_DECLARE(ktriage_mtx, &ktriage_grp); |
54 | |
55 | static void |
56 | ktriage_lock(void) |
57 | { |
58 | lck_mtx_lock(lck: &ktriage_mtx); |
59 | } |
60 | |
61 | static void |
62 | ktriage_unlock(void) |
63 | { |
64 | lck_mtx_unlock(lck: &ktriage_mtx); |
65 | } |
66 | |
67 | int |
68 | create_buffers_triage(void) |
69 | { |
70 | int error = 0; |
71 | int events_per_storage_unit, min_storage_units_per_cpu; |
72 | |
73 | if (kd_control_triage.kdc_flags & KDBG_BUFINIT) { |
74 | panic("create_buffers_triage shouldn't be called once we have inited the triage system." ); |
75 | } |
76 | |
77 | events_per_storage_unit = kd_control_triage.kdebug_events_per_storage_unit; |
78 | min_storage_units_per_cpu = kd_control_triage.kdebug_min_storage_units_per_cpu; |
79 | |
80 | kd_control_triage.kdebug_cpus = kdbg_cpu_count(); |
81 | kd_control_triage.alloc_cpus = kd_control_triage.kdebug_cpus; |
82 | kd_control_triage.kdc_coprocs = NULL; |
83 | |
84 | if (kd_buffer_triage.kdb_event_count < (kd_control_triage.kdebug_cpus * events_per_storage_unit * min_storage_units_per_cpu)) { |
85 | kd_buffer_triage.kdb_storage_count = kd_control_triage.kdebug_cpus * min_storage_units_per_cpu; |
86 | } else { |
87 | kd_buffer_triage.kdb_storage_count = kd_buffer_triage.kdb_event_count / events_per_storage_unit; |
88 | } |
89 | |
90 | kd_buffer_triage.kdb_event_count = kd_buffer_triage.kdb_storage_count * events_per_storage_unit; |
91 | |
92 | kd_buffer_triage.kd_bufs = NULL; |
93 | |
94 | error = create_buffers(ctl: &kd_control_triage, buf: &kd_buffer_triage, VM_KERN_MEMORY_TRIAGE); |
95 | |
96 | if (!error) { |
97 | kd_control_triage.kdc_oldest_time = mach_continuous_time(); |
98 | kd_control_triage.enabled = 1; |
99 | kd_buffer_triage.kdb_storage_threshold = kd_buffer_triage.kdb_storage_count / 2; |
100 | } |
101 | |
102 | return error; |
103 | } |
104 | |
105 | __attribute__((noreturn)) |
106 | void |
107 | delete_buffers_triage(void) |
108 | { |
109 | /* |
110 | * If create_buffers() for triage mode fails, it will call the generic delete_buffers() to |
111 | * free the resources. This specific call should never be invoked because we expect the |
112 | * triage system to always be ON. |
113 | */ |
114 | panic("delete_buffers_triage shouldn't be invoked" ); |
115 | } |
116 | |
117 | ktriage_strings_t ktriage_subsystems_strings[KDBG_TRIAGE_SUBSYS_MAX + 1]; |
118 | |
119 | static void |
120 | ktriage_convert_to_string(uint64_t debugid, uintptr_t arg, char *buf, uint32_t bufsz) |
121 | { |
122 | if (buf == NULL) { |
123 | return; |
124 | } |
125 | |
126 | uint8_t subsystem = KDBG_TRIAGE_EXTRACT_CLASS(debugid); |
127 | |
128 | /* zero subsystem means there is nothing to log */ |
129 | if (subsystem == 0) { |
130 | return; |
131 | } |
132 | |
133 | if (subsystem > KDBG_TRIAGE_SUBSYS_MAX) { |
134 | snprintf(buf, count: bufsz, "KTriage Error: Subsystem code %u is invalid\n" , subsystem); |
135 | return; |
136 | } |
137 | |
138 | int subsystem_num_strings = ktriage_subsystems_strings[subsystem].num_strings; |
139 | const char **subsystem_strings = ktriage_subsystems_strings[subsystem].strings; |
140 | uint16_t strindx = KDBG_TRIAGE_EXTRACT_CODE(debugid); |
141 | |
142 | /* fallback if ktriage doesn't know how to parse the given debugid */ |
143 | if (subsystem_num_strings < 1 || subsystem_strings == NULL || strindx >= subsystem_num_strings) { |
144 | snprintf(buf, count: bufsz, "KTriage: Subsystem %d reported %u with argument 0x%lx\n" , subsystem, strindx, arg); |
145 | return; |
146 | } |
147 | |
148 | snprintf(buf, count: bufsz, "%s(arg = 0x%lx) %s" , subsystem_strings[0], arg, subsystem_strings[strindx]); |
149 | |
150 | return; |
151 | } |
152 | |
153 | void |
154 | ktriage_record( |
155 | uint64_t thread_id, |
156 | uint64_t debugid, |
157 | uintptr_t arg) |
158 | { |
159 | struct kd_record kd_rec; |
160 | |
161 | if (thread_id == 0) { |
162 | thread_id = thread_tid(thread: current_thread()); |
163 | } |
164 | |
165 | kd_rec.cpu = -1; |
166 | kd_rec.timestamp = -1; |
167 | |
168 | /* |
169 | * use 64-bit debugid per our flag KDBG_DEBUGID_64 |
170 | * that is set in kd_control_triage (on LP64 only). |
171 | */ |
172 | assert(kd_control_triage.kdc_flags & KDBG_DEBUGID_64); |
173 | |
174 | kd_rec.debugid = 0; |
175 | kd_rec.arg4 = (uintptr_t)debugid; |
176 | |
177 | kd_rec.arg1 = arg; |
178 | kd_rec.arg2 = 0; |
179 | kd_rec.arg3 = 0; |
180 | kd_rec.arg5 = (uintptr_t)thread_id; |
181 | |
182 | kernel_debug_write(ctl: &kd_control_triage, |
183 | buf: &kd_buffer_triage, |
184 | kd_rec); |
185 | } |
186 | |
187 | void |
188 | ( |
189 | uint64_t thread_id, |
190 | void *buf, |
191 | uint32_t bufsz) |
192 | { |
193 | size_t i, record_bytes, record_cnt, record_bufsz; |
194 | void *record_buf; |
195 | void *local_buf; |
196 | int ret; |
197 | |
198 | |
199 | if (thread_id == 0 || buf == NULL || bufsz < KDBG_TRIAGE_MAX_STRLEN) { |
200 | return; |
201 | } |
202 | |
203 | local_buf = buf; |
204 | bzero(s: local_buf, n: bufsz); |
205 | |
206 | record_bytes = record_bufsz = kd_buffer_triage.kdb_event_count * sizeof(kd_buf); |
207 | record_buf = kalloc_data(record_bufsz, Z_WAITOK); |
208 | |
209 | if (record_buf == NULL) { |
210 | ret = ENOMEM; |
211 | } else { |
212 | ktriage_lock(); |
213 | ret = kernel_debug_read(ctl: &kd_control_triage, |
214 | buf: &kd_buffer_triage, |
215 | buffer: (user_addr_t) record_buf, number: &record_bytes, NULL, NULL, file_version: 0); |
216 | ktriage_unlock(); |
217 | } |
218 | |
219 | if (ret) { |
220 | printf("ktriage_extract: kernel_debug_read failed with %d\n" , ret); |
221 | kfree_data(record_buf, record_bufsz); |
222 | return; |
223 | } |
224 | |
225 | kd_buf *kd = (kd_buf*) record_buf; |
226 | i = 0; |
227 | record_cnt = record_bytes; /* kernel_debug_read() takes number of bytes that it |
228 | * converts to kd_bufs. It processes a max of those and |
229 | * returns number of kd_buf read/processed. We use a |
230 | * different variable here to make our units clear. |
231 | */ |
232 | |
233 | while (i < record_cnt) { |
234 | if (kd->arg5 == (uintptr_t)thread_id) { |
235 | ktriage_convert_to_string(debugid: kd->arg4, arg: kd->arg1, buf: local_buf, KDBG_TRIAGE_MAX_STRLEN); |
236 | local_buf = (void *)((uintptr_t)local_buf + KDBG_TRIAGE_MAX_STRLEN); |
237 | bufsz -= KDBG_TRIAGE_MAX_STRLEN; |
238 | if (bufsz < KDBG_TRIAGE_MAX_STRLEN) { |
239 | break; |
240 | } |
241 | } |
242 | i++; |
243 | kd++; |
244 | } |
245 | |
246 | kfree_data(record_buf, record_bufsz); |
247 | } |
248 | |
249 | int |
250 | ktriage_register_subsystem_strings(uint8_t subsystem, ktriage_strings_t *subsystem_strings) |
251 | { |
252 | if (subsystem == 0 || subsystem > KDBG_TRIAGE_SUBSYS_MAX || subsystem_strings == NULL) { |
253 | return EINVAL; |
254 | } |
255 | |
256 | ktriage_lock(); |
257 | |
258 | ktriage_subsystems_strings[subsystem].num_strings = subsystem_strings->num_strings; |
259 | ktriage_subsystems_strings[subsystem].strings = subsystem_strings->strings; |
260 | printf("ktriage_register_subsystem_strings: set subsystem %u strings\n" , subsystem); |
261 | |
262 | ktriage_unlock(); |
263 | |
264 | return 0; |
265 | } |
266 | |
267 | int |
268 | ktriage_unregister_subsystem_strings(uint8_t subsystem) |
269 | { |
270 | if (subsystem == 0 || subsystem > KDBG_TRIAGE_SUBSYS_MAX) { |
271 | return EINVAL; |
272 | } |
273 | |
274 | ktriage_lock(); |
275 | |
276 | if (ktriage_subsystems_strings[subsystem].num_strings == -1) { |
277 | // already unregistered - nothing to do |
278 | ktriage_unlock(); |
279 | return 0; |
280 | } |
281 | |
282 | ktriage_subsystems_strings[subsystem].num_strings = -1; |
283 | ktriage_subsystems_strings[subsystem].strings = NULL; |
284 | |
285 | ktriage_unlock(); |
286 | |
287 | return 0; |
288 | } |
289 | |
290 | /* KDBG_TRIAGE_CODE_* section */ |
291 | /* VM begin */ |
292 | |
293 | const char *vm_triage_strings[] = |
294 | { |
295 | [KDBG_TRIAGE_VM_PREFIX] = "VM - " , |
296 | [KDBG_TRIAGE_VM_NO_DATA] = "Didn't get back data for this file\n" , |
297 | [KDBG_TRIAGE_VM_TEXT_CORRUPTION] = "A memory corruption was found in executable text\n" , |
298 | [KDBG_TRIAGE_VM_ADDRESS_NOT_FOUND] = "Found no valid range containing this address\n" , |
299 | [KDBG_TRIAGE_VM_PROTECTION_FAILURE] = "Fault hit protection failure\n" , |
300 | [KDBG_TRIAGE_VM_FAULT_MEMORY_SHORTAGE] = "VM Fault hit memory shortage\n" , |
301 | [KDBG_TRIAGE_VM_FAULT_COPY_MEMORY_SHORTAGE] = "vm_fault_copy hit memory shortage\n" , |
302 | [KDBG_TRIAGE_VM_FAULT_OBJCOPYSLOWLY_MEMORY_SHORTAGE] = "vm_object_copy_slowly fault hit memory shortage\n" , |
303 | [KDBG_TRIAGE_VM_FAULT_OBJIOPLREQ_MEMORY_SHORTAGE] = "vm_object_iopl_request fault hit memory shortage\n" , |
304 | [KDBG_TRIAGE_VM_FAULT_INTERRUPTED] = "Fault was interrupted\n" , |
305 | [KDBG_TRIAGE_VM_SUCCESS_NO_PAGE] = "Returned success with no page\n" , |
306 | [KDBG_TRIAGE_VM_GUARDPAGE_FAULT] = "Guard page fault\n" , |
307 | [KDBG_TRIAGE_VM_NONZERO_PREEMPTION_LEVEL] = "Fault entered with non-zero preemption level\n" , |
308 | [KDBG_TRIAGE_VM_BUSYPAGE_WAIT_INTERRUPTED] = "Waiting on busy page was interrupted\n" , |
309 | [KDBG_TRIAGE_VM_PURGEABLE_FAULT_ERROR] = "Purgeable object hit an error in fault\n" , |
310 | [KDBG_TRIAGE_VM_OBJECT_SHADOW_SEVERED] = "Object has a shadow severed\n" , |
311 | [KDBG_TRIAGE_VM_OBJECT_NOT_ALIVE] = "Object is not alive\n" , |
312 | [KDBG_TRIAGE_VM_OBJECT_NO_PAGER] = "Object has no pager\n" , |
313 | [KDBG_TRIAGE_VM_OBJECT_NO_PAGER_FORCED_UNMOUNT] = "Object has no pager because the backing vnode was force unmounted\n" , |
314 | [KDBG_TRIAGE_VM_OBJECT_NO_PAGER_UNGRAFT] = "Object has no pager because the backing vnode was ungrafted\n" , |
315 | [KDBG_TRIAGE_VM_PAGE_HAS_ERROR] = "Page has error bit set\n" , |
316 | [KDBG_TRIAGE_VM_PAGE_HAS_RESTART] = "Page has restart bit set\n" , |
317 | [KDBG_TRIAGE_VM_FAILED_IMMUTABLE_PAGE_WRITE] = "Failed a writable mapping of an immutable page\n" , |
318 | [KDBG_TRIAGE_VM_FAILED_NX_PAGE_EXEC_MAPPING] = "Failed an executable mapping of a nx page\n" , |
319 | [KDBG_TRIAGE_VM_PMAP_ENTER_RESOURCE_SHORTAGE] = "pmap_enter retried due to resource shortage\n" , |
320 | [KDBG_TRIAGE_VM_COMPRESSOR_GET_OUT_OF_RANGE] = "Compressor offset requested out of range\n" , |
321 | [KDBG_TRIAGE_VM_COMPRESSOR_GET_NO_PAGE] = "Compressor doesn't have this page\n" , |
322 | [KDBG_TRIAGE_VM_COMPRESSOR_DECOMPRESS_FAILED] = "Decompressor hit a failure\n" , |
323 | [KDBG_TRIAGE_VM_SUBMAP_NO_COW_ON_EXECUTABLE] = "Submap disallowed cow on executable range\n" , |
324 | [KDBG_TRIAGE_VM_SUBMAP_COPY_SLOWLY_FAILED] = "Submap object copy_slowly failed\n" , |
325 | [KDBG_TRIAGE_VM_SUBMAP_COPY_STRAT_FAILED] = "Submap object copy_strategically failed\n" , |
326 | [KDBG_TRIAGE_VM_VNODEPAGER_CLREAD_NO_UPL] = "vnode_pager_cluster_read couldn't create a UPL\n" , |
327 | [KDBG_TRIAGE_VM_VNODEPAGEIN_NO_UBCINFO] = "vnode_pagein got a vnode with no ubcinfo\n" , |
328 | [KDBG_TRIAGE_VM_VNODEPAGEIN_FSPAGEIN_FAIL] = "Filesystem pagein returned an error in vnode_pagein\n" , |
329 | [KDBG_TRIAGE_VM_VNODEPAGEIN_NO_UPL] = "vnode_pagein couldn't create a UPL\n" , |
330 | [KDBG_TRIAGE_VM_ECC_DIRTY] = "Accessed a page that has uncorrected ECC error\n" , |
331 | [KDBG_TRIAGE_VM_ECC_CLEAN] = "Clean page had an uncorrected ECC error\n" , |
332 | [KDBG_TRIAGE_VM_COPYOUTMAP_SAMEMAP_ERROR] = "vm_copyout_map failed with same src-dest map\n" , |
333 | [KDBG_TRIAGE_VM_COPYOUTMAP_DIFFERENTMAP_ERROR] = "vm_copyout_map failed with different src-dest map\n" , |
334 | [KDBG_TRIAGE_VM_COPYOVERWRITE_FULL_NESTED_ERROR] = "vm_map_copy_overwrite_nested failed when trying full copy\n" , |
335 | [KDBG_TRIAGE_VM_COPYOVERWRITE_PARTIAL_NESTED_ERROR] = "vm_map_copy_overwrite_nested failed when trying partial copy\n" , |
336 | [KDBG_TRIAGE_VM_COPYOVERWRITE_PARTIAL_HEAD_NESTED_ERROR] = "vm_map_copy_overwrite_nested failed when trying misaligned head copy\n" , |
337 | [KDBG_TRIAGE_VM_COPYOVERWRITE_PARTIAL_TAIL_NESTED_ERROR] = "vm_map_copy_overwrite_nested failed when trying misaligned tail copy\n" , |
338 | [KDBG_TRIAGE_VM_COPYOUT_INTERNAL_SIZE_ERROR] = "vm_map_copyout_internal failed due to bad size\n" , |
339 | [KDBG_TRIAGE_VM_COPYOUT_KERNEL_BUFFER_ERROR] = "vm_map_copyout_kernel_buffer failed\n" , |
340 | [KDBG_TRIAGE_VM_COPYOUT_INTERNAL_ADJUSTING_ERROR] = "vm_map_copyout_internal failed when trying to adjust src-dest params\n" , |
341 | [KDBG_TRIAGE_VM_COPYOUT_INTERNAL_SPACE_ERROR] = "vm_map_copyout_internal failed because we couldn't locate space\n" , |
342 | [KDBG_TRIAGE_VM_ALLOCATE_KERNEL_BADFLAGS_ERROR] = "mach_vm_allocate_kernel failed due to bad flags\n" , |
343 | [KDBG_TRIAGE_VM_ALLOCATE_KERNEL_BADMAP_ERROR] = "mach_vm_allocate_kernel failed due to bad map\n" , |
344 | [KDBG_TRIAGE_VM_ALLOCATE_KERNEL_BADSIZE_ERROR] = "mach_vm_allocate_kernel failed due to bad size\n" , |
345 | [KDBG_TRIAGE_VM_ALLOCATE_KERNEL_VMMAPENTER_ERROR] = "mach_vm_allocate_kernel failed within call to vm_map_enter\n" , |
346 | }; |
347 | /* VM end */ |
348 | |
349 | /* Cluster begin */ |
350 | |
351 | const char *cluster_triage_strings[] = |
352 | { |
353 | [KDBG_TRIAGE_CL_PREFIX] = "CL - " , |
354 | [KDBG_TRIAGE_CL_PGIN_PAST_EOF] = "cluster_pagein past EOF\n" , |
355 | }; |
356 | /* Cluster end */ |
357 | |
358 | /* Shared Region begin */ |
359 | |
360 | const char *shared_region_triage_strings[] = |
361 | { |
362 | [KDBG_TRIAGE_SHARED_REGION_PREFIX] = "SR - " , |
363 | [KDBG_TRIAGE_SHARED_REGION_NO_UPL] = "shared_region_pager_data_request couldn't create a upl\n" , |
364 | [KDBG_TRIAGE_SHARED_REGION_SLIDE_ERROR] = "shared_region_pager_data_request hit a page sliding error\n" , |
365 | [KDBG_TRIAGE_SHARED_REGION_PAGER_MEMORY_SHORTAGE] = "shared_region_pager_data_request hit memory shortage\n" , |
366 | }; |
367 | /* Shared Region end */ |
368 | |
369 | /* Dyld Pager begin */ |
370 | |
371 | const char *[] = |
372 | { |
373 | [KDBG_TRIAGE_DYLD_PAGER_PREFIX] = "DP - " , |
374 | [KDBG_TRIAGE_DYLD_PAGER_NO_UPL] = "dyld_pager_data_request couldn't create a upl\n" , |
375 | [KDBG_TRIAGE_DYLD_PAGER_MEMORY_SHORTAGE] = "dyld_pager_data_request hit memory shortage\n" , |
376 | [KDBG_TRIAGE_DYLD_PAGER_SLIDE_ERROR] = "dyld_pager_data_request hit a page sliding error\n" , |
377 | [KDBG_TRIAGE_DYLD_PAGER_CHAIN_OUT_OF_RANGE] = "dyld_pager_data_request chain out of range\n" , |
378 | [KDBG_TRIAGE_DYLD_PAGER_SEG_INFO_OUT_OF_RANGE] = "dyld_pager_data_request seg_info out of range\n" , |
379 | [KDBG_TRIAGE_DYLD_PAGER_SEG_SIZE_OUT_OF_RANGE] = "dyld_pager_data_request seg->size out of range\n" , |
380 | [KDBG_TRIAGE_DYLD_PAGER_SEG_PAGE_CNT_OUT_OF_RANGE] = "dyld_pager_data_request seg->page_count out of range\n" , |
381 | [KDBG_TRIAGE_DYLD_PAGER_NO_SEG_FOR_VA] = "dyld_pager_data_request no segment for VA\n" , |
382 | [KDBG_TRIAGE_DYLD_PAGER_RANGE_NOT_FOUND] = "dyld_pager_data_request no range for offset\n" , |
383 | [KDBG_TRIAGE_DYLD_PAGER_DELTA_TOO_LARGE] = "dyld_pager_data_request delta * 4 > PAGE_SIZE\n" , |
384 | [KDBG_TRIAGE_DYLD_PAGER_PAGE_START_OUT_OF_RANGE] = "dyld_pager_data_request segInfo page_start out of range\n" , |
385 | [KDBG_TRIAGE_DYLD_PAGER_BAD_POINTER_FMT] = "dyld_pager_data_request unkown pointer format\n" , |
386 | [KDBG_TRIAGE_DYLD_PAGER_INVALID_AUTH_KEY] = "dyld_pager_data_request unkown auth key\n" , |
387 | [KDBG_TRIAGE_DYLD_PAGER_BIND_ORDINAL] = "dyld_pager_data_request invalid bind ordinal\n" , |
388 | }; |
389 | /* Dyld Pager end */ |
390 | |
391 | /* Apple Protect Pager begin */ |
392 | |
393 | const char *[] = |
394 | { |
395 | [KDBG_TRIAGE_APPLE_PROTECT_PAGER_PREFIX] = "APP - " , |
396 | [KDBG_TRIAGE_APPLE_PROTECT_PAGER_MEMORY_SHORTAGE] = "apple_protect_pager_data_request hit memory shortage\n" , |
397 | }; |
398 | /* Apple Protect Pager end */ |
399 | |
400 | /* Fourk Pager begin */ |
401 | |
402 | const char *[] = |
403 | { |
404 | [KDBG_TRIAGE_FOURK_PAGER_PREFIX] = "FP - " , |
405 | [KDBG_TRIAGE_FOURK_PAGER_MEMORY_SHORTAGE] = "fourk_pager_data_request hit memory shortage\n" , |
406 | }; |
407 | /* Fourk Pager end */ |
408 | |
409 | /* Corpse section begin */ |
410 | |
411 | const char *corpse_triage_strings[] = |
412 | { |
413 | [KDBG_TRIAGE_CORPSE_PREFIX] = "Corpse - " , |
414 | [KDBG_TRIAGE_CORPSE_PROC_TOO_BIG] = "Process too big for corpse. Corpse disallowed.\n" , |
415 | [KDBG_TRIAGE_CORPSE_FAIL_LIBGMALLOC] = "Process linked against libgmalloc. Corpse disallowed.\n" , |
416 | [KDBG_TRIAGE_CORPSE_BLOCKED_JETSAM] = "Jetsams happening in higher bands. Corpse disallowed.\n" , |
417 | [KDBG_TRIAGE_CORPSE_LIMIT] = "Too many corpses in flight. Corpse disallowed.\n" , |
418 | [KDBG_TRIAGE_CORPSES_DISABLED] = "Corpse disabled on system.\n" , |
419 | [KDBG_TRIAGE_CORPSE_DISABLED_FOR_PROC] = "Corpse disabled for this process.\n" , |
420 | }; |
421 | /* Corpse section end */ |
422 | |
423 | /* subsystems starts at index 1 */ |
424 | ktriage_strings_t ktriage_subsystems_strings[KDBG_TRIAGE_SUBSYS_MAX + 1] = { |
425 | [KDBG_TRIAGE_SUBSYS_VM] = {VM_MAX_TRIAGE_STRINGS, vm_triage_strings}, |
426 | [KDBG_TRIAGE_SUBSYS_CLUSTER] = {CLUSTER_MAX_TRIAGE_STRINGS, cluster_triage_strings}, |
427 | [KDBG_TRIAGE_SUBSYS_SHARED_REGION] = {SHARED_REGION_MAX_TRIAGE_STRINGS, shared_region_triage_strings}, |
428 | [KDBG_TRIAGE_SUBSYS_DYLD_PAGER] = {DYLD_PAGER_MAX_TRIAGE_STRINGS, dyld_pager_triage_strings}, |
429 | [KDBG_TRIAGE_SUBSYS_APPLE_PROTECT_PAGER] = {APPLE_PROTECT_PAGER_MAX_TRIAGE_STRINGS, apple_protect_pager_triage_strings}, |
430 | [KDBG_TRIAGE_SUBSYS_FOURK_PAGER] = {FOURK_PAGER_MAX_TRIAGE_STRINGS, fourk_pager_triage_strings}, |
431 | |
432 | [KDBG_TRIAGE_SUBSYS_APFS] = {-1, NULL}, |
433 | [KDBG_TRIAGE_SUBSYS_DECMPFS] = {-1, NULL}, |
434 | [KDBG_TRIAGE_SUBSYS_CORPSE] = {CORPSE_MAX_TRIAGE_STRINGS, corpse_triage_strings}, |
435 | }; |
436 | |
437 | /* KDBG_TRIAGE_CODE_* section */ |
438 | |