فهرست منبع

core: add debug::crash()

Daniele Bartolini 9 ماه پیش
والد
کامیت
25bf1c2f5f
3فایلهای تغییر یافته به همراه79 افزوده شده و 36 حذف شده
  1. 37 0
      src/core/debug/debug.cpp
  2. 17 0
      src/core/debug/debug.h
  3. 25 36
      src/device/device.cpp

+ 37 - 0
src/core/debug/debug.cpp

@@ -4,6 +4,9 @@
  */
 
 #include "core/debug/debug.h"
+#include "core/error/error.inl"
+#include "core/memory/allocator.h"
+#include "core/memory/globals.h"
 #if CROWN_PLATFORM_EMSCRIPTEN
 #   include <emscripten/emscripten.h>
 #elif CROWN_PLATFORM_LINUX
@@ -29,6 +32,40 @@ namespace debug
 #endif
 	}
 
+	void crash(CrashType::Enum type)
+	{
+		CE_ALIGN_DECL(alignof(s64), u8 buf[16]);
+		volatile s64 zero = 0;
+
+		switch (type) {
+		case CrashType::DIVISION_BY_ZERO:
+			*((f32 *)buf) = 1.0f / f32(zero);
+			break;
+
+		case CrashType::UNALIGNED_ACCESS:
+			*((s64 *)&buf[1]) = zero;
+			break;
+
+		case CrashType::SEGMENTATION_FAULT:
+			*((s64 *)(uintptr_t)0xffffffffu) = zero;
+			break;
+
+		case CrashType::OUT_OF_MEMORY: {
+			s64 size = 512*1024*1024;
+			for (s64 i = 0; i < INT64_MAX; ++i, size *= 2)
+				*((s64 *)default_allocator().allocate(size)) = zero;
+			break;
+		}
+
+		case CrashType::ASSERT:
+			CE_ASSERT(false, "False");
+			break;
+
+		default:
+			break;
+		}
+	}
+
 } // namespace debug
 
 } // namespace crown

+ 17 - 0
src/core/debug/debug.h

@@ -11,6 +11,20 @@
 /// @ingroup Core
 namespace crown
 {
+struct CrashType
+{
+	enum Enum
+	{
+		DIVISION_BY_ZERO,
+		UNALIGNED_ACCESS,
+		SEGMENTATION_FAULT,
+		OUT_OF_MEMORY,
+		ASSERT,
+
+		COUNT
+	};
+};
+
 /// Debug utils.
 ///
 /// @ingroup Debug
@@ -19,6 +33,9 @@ namespace debug
 	/// Triggers a breakpoint.
 	void breakpoint();
 
+	/// Crashes the application.
+	void crash(CrashType::Enum type);
+
 } // namespace debug
 
 } // namespace crown

+ 25 - 36
src/device/device.cpp

@@ -5,6 +5,7 @@
 
 #include "config.h"
 #include "core/containers/array.inl"
+#include "core/debug/debug.h"
 #include "core/filesystem/file.h"
 #include "core/filesystem/filesystem.h"
 #include "core/filesystem/filesystem_apk.h"
@@ -234,32 +235,19 @@ static void device_command_crash(ConsoleServer &cs, u32 client_id, const JsonArr
 	CE_UNUSED(user_data);
 	TempAllocator1024 ta;
 
-	struct CrashType
-	{
-		enum Enum
-		{
-			DIVISION_BY_ZERO,
-			UNALIGNED_ACCESS,
-			SEGMENTATION_FAULT,
-			OUT_OF_MEMORY,
-			ASSERT,
-
-			COUNT
-		};
-	};
-
 	struct
 	{
-		const char *type;
+		const char *type_name;
 		const char *desc;
+		CrashType::Enum type;
 	}
 	crash_info[] =
 	{
-		{ "div_by_zero", "Divide a number by zero." },
-		{ "unaligned", "Do an unaligned memory access." },
-		{ "segfault", "Trigger a segmentation fault." },
-		{ "oom", "Allocate too much memory." },
-		{ "assert", "Call CE_ASSERT(false)." }
+		{ "div_by_zero", "Divide a number by zero.",       CrashType::DIVISION_BY_ZERO   },
+		{ "unaligned",   "Do an unaligned memory access.", CrashType::UNALIGNED_ACCESS   },
+		{ "segfault",    "Trigger a segmentation fault.",  CrashType::SEGMENTATION_FAULT },
+		{ "oom",         "Allocate too much memory.",      CrashType::OUT_OF_MEMORY      },
+		{ "assert",      "Call CE_ASSERT(false).",         CrashType::ASSERT             }
 	};
 	CE_STATIC_ASSERT(countof(crash_info) == CrashType::COUNT);
 
@@ -270,24 +258,25 @@ static void device_command_crash(ConsoleServer &cs, u32 client_id, const JsonArr
 
 	DynamicString subcmd(ta);
 	sjson::parse_string(subcmd, args[1]);
-	if (subcmd == crash_info[CrashType::DIVISION_BY_ZERO].type) {
-		f32(time::now()) / 0.0f;
-	} else if (subcmd == crash_info[CrashType::UNALIGNED_ACCESS].type) {
-		CE_ALIGN_DECL(alignof(s64), u8 buf[16]);
-		*((s64 *)&buf[1]) = time::now();
-	} else if (subcmd == crash_info[CrashType::SEGMENTATION_FAULT].type) {
-		*((s64 *)(uintptr_t)time::now()) = time::now();
-	} else if (subcmd == crash_info[CrashType::OUT_OF_MEMORY].type) {
-		while (s64 t = time::now())
-			*((s64 *)malloc(1024*1024)) = t;
-	} else if (subcmd == crash_info[CrashType::ASSERT].type) {
-		CE_ASSERT(false, "False");
-	} else if (subcmd == "help") {
-		for (u32 i = 0; i < CrashType::COUNT; ++i) {
-			logi(DEVICE, "%s %s", crash_info[i].type, crash_info[i].desc);
+
+	if (subcmd == "help") {
+		for (u32 i = 0; i < countof(crash_info); ++i) {
+			logi(DEVICE, "%s %s", crash_info[i].type_name, crash_info[i].desc);
 		}
 	} else {
-		loge(DEVICE, "Unknown crash parameter");
+		// Decode crash type.
+		CrashType::Enum crash_type = CrashType::COUNT;
+		for (u32 i = 0; i < countof(crash_info); ++i) {
+			if (subcmd == crash_info[i].type_name) {
+				crash_type = crash_info[i].type;
+				break;
+			}
+		}
+
+		if (crash_type == CrashType::COUNT)
+			loge(DEVICE, "Unknown crash parameter");
+		else
+			debug::crash(crash_type);
 	}
 }