| 278 | } |
| 279 | |
| 280 | static void device_command_crash(ConsoleServer &cs, u32 client_id, const JsonArray &args, void *user_data) |
| 281 | { |
| 282 | CE_UNUSED(user_data); |
| 283 | TempAllocator1024 ta; |
| 284 | |
| 285 | struct |
| 286 | { |
| 287 | const char *type_name; |
| 288 | const char *desc; |
| 289 | CrashType::Enum type; |
| 290 | } |
| 291 | crash_info[] = |
| 292 | { |
| 293 | { "div_by_zero", "Divide a number by zero.", CrashType::DIVISION_BY_ZERO }, |
| 294 | { "unaligned", "Do an unaligned memory access.", CrashType::UNALIGNED_ACCESS }, |
| 295 | { "segfault", "Trigger a segmentation fault.", CrashType::SEGMENTATION_FAULT }, |
| 296 | { "oom", "Allocate too much memory.", CrashType::OUT_OF_MEMORY }, |
| 297 | { "assert", "Call CE_ASSERT(false).", CrashType::ASSERT } |
| 298 | }; |
| 299 | CE_STATIC_ASSERT(countof(crash_info) == CrashType::COUNT); |
| 300 | |
| 301 | if (array::size(args) < 2) { |
| 302 | cs.error(client_id, "Usage: crash <type>"); |
| 303 | return; |
| 304 | } |
| 305 | |
| 306 | DynamicString subcmd(ta); |
| 307 | sjson::parse_string(subcmd, args[1]); |
| 308 | |
| 309 | if (subcmd == "help") { |
| 310 | for (u32 i = 0; i < countof(crash_info); ++i) { |
| 311 | logi(DEVICE, "%s %s", crash_info[i].type_name, crash_info[i].desc); |
| 312 | } |
| 313 | } else { |
| 314 | // Decode crash type. |
| 315 | CrashType::Enum crash_type = CrashType::COUNT; |
| 316 | for (u32 i = 0; i < countof(crash_info); ++i) { |
| 317 | if (subcmd == crash_info[i].type_name) { |
| 318 | crash_type = crash_info[i].type; |
| 319 | break; |
| 320 | } |
| 321 | } |
| 322 | |
| 323 | if (crash_type == CrashType::COUNT) |
| 324 | loge(DEVICE, "Unknown crash parameter"); |
| 325 | else |
| 326 | debug::crash(crash_type); |
| 327 | } |
| 328 | } |
| 329 | |
| 330 | static void device_message_resize(ConsoleServer & /*cs*/, u32 /*client_id*/, const char *json, void * /*user_data*/) |
| 331 | { |
nothing calls this directly
no test coverage detected