Browse Source

Handle crashes a bit better

Panagiotis Christopoulos Charitos 4 years ago
parent
commit
bcf9a2c269
7 changed files with 81 additions and 26 deletions
  1. 1 0
      .gitignore
  2. 60 0
      AnKi/Core/App.cpp
  3. 2 0
      AnKi/Core/App.h
  4. 2 2
      AnKi/Script/LuaBinder.cpp
  5. 7 8
      AnKi/Util/Assert.cpp
  6. 6 5
      AnKi/Util/System.cpp
  7. 3 11
      AnKi/Util/System.h

+ 1 - 0
.gitignore

@@ -1,3 +1,4 @@
 build*/*
 .vscode/*
+.vs/*
 out/*

+ 60 - 0
AnKi/Core/App.cpp

@@ -27,6 +27,7 @@
 #include <AnKi/Core/StagingGpuMemoryManager.h>
 #include <AnKi/Ui/UiManager.h>
 #include <AnKi/Ui/Canvas.h>
+#include <csignal>
 
 #if ANKI_OS_ANDROID
 #	include <android_native_app_glue.h>
@@ -307,6 +308,8 @@ Error App::init(const ConfigSet& config, AllocAlignedCallback allocCb, void* all
 
 Error App::initInternal(const ConfigSet& config_, AllocAlignedCallback allocCb, void* allocCbUserData)
 {
+	setSignalHandlers();
+
 	ConfigSet config = config_;
 	m_displayStats = config.getNumberU32("core_displayStats");
 
@@ -701,4 +704,61 @@ void App::initMemoryCallbacks(AllocAlignedCallback allocCb, void* allocCbUserDat
 	}
 }
 
+void App::setSignalHandlers()
+{
+	auto handler = [](int signum) -> void {
+		const char* name = nullptr;
+		switch(signum)
+		{
+		case SIGABRT:
+			name = "SIGABRT";
+			break;
+		case SIGSEGV:
+			name = "SIGSEGV";
+			break;
+#if ANKI_POSIX
+		case SIGBUS:
+			name = "SIGBUS";
+			break;
+#endif
+		case SIGILL:
+			name = "SIGILL";
+			break;
+		case SIGFPE:
+			name = "SIGFPE";
+			break;
+		}
+
+		if(name)
+			printf("Caught signal %d (%s)\n", signum, name);
+		else
+			printf("Caught signal %d\n", signum);
+
+		class BW : public BackTraceWalker
+		{
+		public:
+			U32 m_c = 0;
+
+			void operator()(const char* symbol)
+			{
+				printf("%.2u: %s\n", m_c++, symbol);
+			}
+		};
+
+		BW bw;
+		printf("Backtrace:\n");
+		getBacktrace(bw);
+
+		ANKI_DEBUG_BREAK();
+	};
+
+	signal(SIGSEGV, handler);
+	signal(SIGILL, handler);
+	signal(SIGFPE, handler);
+#if ANKI_POSIX
+	signal(SIGBUS, handler);
+#endif
+	// Ignore for now: signal(SIGABRT, handler);
+}
+
 } // end namespace anki

+ 2 - 0
AnKi/Core/App.h

@@ -216,6 +216,8 @@ private:
 
 	/// Inject a new UI element in the render queue for displaying various stuff.
 	void injectUiElements(DynamicArrayAuto<UiQueueElement>& elements, RenderQueue& rqueue);
+
+	void setSignalHandlers();
 };
 
 } // end namespace anki

+ 2 - 2
AnKi/Script/LuaBinder.cpp

@@ -30,8 +30,8 @@ static void wrapModules(lua_State* l)
 
 static int luaPanic(lua_State* l)
 {
-	ANKI_SCRIPT_LOGE("Lua panic attack: %s", lua_tostring(l, -1));
-	abort();
+	ANKI_SCRIPT_LOGF("Lua panic attack: %s", lua_tostring(l, -1));
+	return 0;
 }
 
 LuaBinder::LuaBinder()

+ 7 - 8
AnKi/Util/Assert.cpp

@@ -24,31 +24,30 @@ void akassert(const char* exprTxt, const char* file, int line, const char* func)
 #	else
 #		if ANKI_OS_LINUX
 	if(runningFromATerminal())
+	{
 		fprintf(stderr, "\033[1;31m(%s:%d %s) Assertion failed: %s\033[0m\n", file, line, func, exprTxt);
+	}
 	else
 #		endif
+	{
 		fprintf(stderr, "(%s:%d %s) Assertion failed: %s\n", file, line, func, exprTxt);
+	}
 #	endif
 
 	class BW : public BackTraceWalker
 	{
 	public:
-		BW()
-			: BackTraceWalker(10)
-		{
-		}
-
-		U m_c = 0;
+		U32 m_c = 0;
 
 		void operator()(const char* symbol)
 		{
-			printf("%.2u: %s\n", unsigned(m_c++), symbol);
+			printf("%.2u: %s\n", m_c++, symbol);
 		}
 	};
 
 	BW bw;
 	printf("Backtrace:\n");
-	bw.exec();
+	getBacktrace(bw);
 
 	ANKI_DEBUG_BREAK();
 }

+ 6 - 5
AnKi/Util/System.cpp

@@ -38,14 +38,15 @@ U32 getCpuCoresCount()
 #endif
 }
 
-void BackTraceWalker::exec()
+void getBacktrace(BackTraceWalker& walker)
 {
 #if ANKI_POSIX && !ANKI_OS_ANDROID
 	// Get addresses's for all entries on the stack
-	void** array = static_cast<void**>(malloc(m_stackSize * sizeof(void*)));
+	const U32 maxStackSize = 64;
+	void** array = static_cast<void**>(malloc(maxStackSize * sizeof(void*)));
 	if(array)
 	{
-		I32 size = backtrace(array, I32(m_stackSize));
+		const I32 size = backtrace(array, I32(maxStackSize));
 
 		// Get symbols
 		char** strings = backtrace_symbols(array, size);
@@ -54,7 +55,7 @@ void BackTraceWalker::exec()
 		{
 			for(I32 i = 0; i < size; ++i)
 			{
-				operator()(strings[i]);
+				walker(strings[i]);
 			}
 
 			free(strings);
@@ -63,7 +64,7 @@ void BackTraceWalker::exec()
 		free(array);
 	}
 #else
-	ANKI_UTIL_LOGW("BackTraceWalker::exec() Not supported in this platform");
+	walker("getBacktrace() not supported in " ANKI_OS_STR);
 #endif
 }
 

+ 3 - 11
AnKi/Util/System.h

@@ -16,27 +16,19 @@ namespace anki
 /// Get the number of CPU cores
 U32 getCpuCoresCount();
 
-/// Visit the program stack.
+/// Backtrace walker.
 class BackTraceWalker
 {
 public:
-	BackTraceWalker(U stackSize = 50)
-		: m_stackSize(stackSize)
-	{
-	}
-
 	virtual ~BackTraceWalker()
 	{
 	}
 
 	virtual void operator()(const char* symbol) = 0;
-
-	void exec();
-
-private:
-	U m_stackSize;
 };
 
+void getBacktrace(BackTraceWalker& walker);
+
 /// Return true if the engine is running from a terminal emulator.
 Bool runningFromATerminal();
 /// @}