| 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 | |