Engine SEGFAULT on crash() when ruby is not initialized fixed

This commit is contained in:
DepressedTWM 2026-08-14 12:30:10 +04:00
parent 59e271639f
commit ee555c92d8
7 changed files with 95 additions and 47 deletions

View File

@ -534,6 +534,7 @@ static void mriBindingExecute(){
RUBY_INIT_STACK; RUBY_INIT_STACK;
ruby_init(); ruby_init();
ruby_init_loadpath(); ruby_init_loadpath();
is_ruby_initialized = true;
rb_enc_set_default_external(rb_enc_from_encoding(rb_utf8_encoding())); rb_enc_set_default_external(rb_enc_from_encoding(rb_utf8_encoding()));
Config &conf = shState->rtData().config; Config &conf = shState->rtData().config;
if (!conf.rubyLoadpaths.empty()){ if (!conf.rubyLoadpaths.empty()){
@ -558,6 +559,7 @@ static void mriBindingExecute(){
showExc(exc, btData); showExc(exc, btData);
shState->rtData().rqTermAck.set(); shState->rtData().rqTermAck.set();
is_ruby_initialized = false;
} }
static void mriBindingTerminate(){ static void mriBindingTerminate(){

View File

@ -48,7 +48,7 @@
#define GUARD_MEGA \ #define GUARD_MEGA \
{ \ { \
if (p->megaSurface) \ if (p->megaSurface) \
crash(Exception::MKXPError, "Operation not supported for mega surfaces"); \ ErrorMsg(Exception::MKXPError, "Operation not supported for mega surfaces"); \
} }
#define OUTLINE_SIZE 1 #define OUTLINE_SIZE 1
@ -225,7 +225,7 @@ Bitmap::Bitmap(const char *filename){
SDL_Surface *imgSurf = handler.surf; SDL_Surface *imgSurf = handler.surf;
if (!imgSurf) if (!imgSurf)
crash(Exception::SDLError, "Error loading image '%s': %s", filename, SDL_GetError()); ErrorMsg(Exception::SDLError, "Error loading image '%s': %s", filename, SDL_GetError());
p->ensureFormat(imgSurf, SDL_PIXELFORMAT_ABGR8888); p->ensureFormat(imgSurf, SDL_PIXELFORMAT_ABGR8888);
@ -261,7 +261,7 @@ Bitmap::Bitmap(const char *filename){
Bitmap::Bitmap(int width, int height){ Bitmap::Bitmap(int width, int height){
if (width <= 0 || height <= 0) if (width <= 0 || height <= 0)
crash(Exception::RGSSError, "failed to create bitmap"); ErrorMsg(Exception::RGSSError, "failed to create bitmap");
TEXFBO tex = shState->texPool().request(width, height); TEXFBO tex = shState->texPool().request(width, height);

View File

@ -62,7 +62,7 @@ public:
protected: protected:
void guardDisposed() const{ void guardDisposed() const{
if (isDisposed()) if (isDisposed())
crash(Exception::RGSSError, "disposed %s", klassName()); ErrorMsg(Exception::RGSSError, "disposed %s", klassName());
} }
private: private:

View File

@ -90,8 +90,13 @@ void initGLFunctions(){
/* Assume single digit */ /* Assume single digit */
int glMajor = *ver - '0'; int glMajor = *ver - '0';
if (glMajor < 2) if (glMajor < 2){
crash(Exception::MKXPError, "At least OpenGL (ES) 2.0 is required"); #ifdef GLES2_HEADER
ErrorMsg("At least OpenGL ES 2.0 is required");
#else
ErrorMsg("At least OpenGL 2.0 is required");
#endif
}
if (gles){ if (gles){
GL_ES_FUN; GL_ES_FUN;
@ -126,7 +131,7 @@ void initGLFunctions(){
} }
} }
else{ else{
crash(Exception::MKXPError, "No FBO support available"); ErrorMsg("No FBO support available");
} }
/* VAO entrypoints */ /* VAO entrypoints */

View File

@ -202,7 +202,7 @@ static void setGamePathInRegistry() {
//TODO handle this for Linux/Mac //TODO handle this for Linux/Mac
} }
int main(int argc, char *argv[]){ int main(int argc, char *argv[]){
Debug() << VERSION_STRING; crash(Exception::SDLError, "DEBUGTEST");
startTime = boost::chrono::high_resolution_clock::now(); startTime = boost::chrono::high_resolution_clock::now();
loadLanguageMetadata(); //there will be a segfault on fclose if I don't move it here loadLanguageMetadata(); //there will be a segfault on fclose if I don't move it here
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0"); SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");

View File

@ -22,6 +22,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <ruby/version.h> #include <ruby/version.h>
#include <ruby/internal/interpreter.h>
#undef vsnprintf #undef vsnprintf
#undef snprintf #undef snprintf
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__NetBSD__) #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__NetBSD__)
@ -53,6 +54,57 @@ static inline const char* glGetStringInt(GLenum name){
return (const char*) gl.GetString(name); return (const char*) gl.GetString(name);
} }
static void get_reason_and_solution(Exception::Type t) {
switch (t) {
case Exception::ModLoaderError:
crash_reason = "Broken mod";
crash_possible_solution = "Fix mode manualy or ask developer to fix it or delete mod";
break;
case Exception::NoFileError:
crash_reason = "Broken installation";
crash_possible_solution = "Try reinstall game";
break;
case Exception::ShaderError:
crash_reason = "Broken Shader";
crash_possible_solution = "Try reinstall game";
break;
case Exception::RGSSError:
crash_reason = "Internal Error";
crash_possible_solution = "Try reinstall game or disable some mods";
break;
case Exception::RUBYError:
crash_reason = "Internal Error";
crash_possible_solution = "Try reinstall game or disable some mods";
break;
case Exception::IOError:
crash_reason = "Broken installation";
crash_possible_solution = "Try reinstall game";
break;
case Exception::TypeError:
crash_reason = "Internal Error";
crash_possible_solution = "Try reinstall game or disable some mods";
break;
case Exception::ArgumentError:
crash_reason = "Internal error";
crash_possible_solution = "Try reinstall game or disable some mods";
break;
case Exception::PHYSFSError:
crash_reason = "Internal error";
crash_possible_solution = "Maybe you tryed load corrupted mod via modloader, try delete it";
break;
case Exception::SDLError:
crash_reason = "Internal error";
crash_possible_solution = "Internal Engine Error, maybe something wrong with your device or operating system";
break;
case Exception::MKXPError:
crash_reason = "Internal error";
crash_possible_solution = "Try reinstall game or disable some mods";
break;
default:
break;
}
}
void crash(Exception::Type t, const char *fmt, ...) { void crash(Exception::Type t, const char *fmt, ...) {
static char crash_message[1024]; static char crash_message[1024];
static const char* crash_reason = nullptr; static const char* crash_reason = nullptr;
@ -70,44 +122,11 @@ void crash(Exception::Type t, const char *fmt, ...) {
SDL_vsnprintf(crash_message, sizeof(crash_message), fmt, args); SDL_vsnprintf(crash_message, sizeof(crash_message), fmt, args);
va_end(args); va_end(args);
get_reason_and_solution(t);
//TODO: rewrite to use switch :3
if (t == Exception::ModLoaderError) {
crash_reason = "Broken mod";
crash_possible_solution = "Fix mode manualy or ask developer to fix it or delete mod";
} else if (t == Exception::NoFileError) {
crash_reason = "Broken installation";
crash_possible_solution = "Try reinstall game";
} else if (t == Exception::ShaderError) {
crash_reason = "Broken Shader";
crash_possible_solution = "Try reinstall game";
} else if (t == Exception::RGSSError) {
crash_reason = "Internal Error";
crash_possible_solution = "Try reinstall game or disable some mods";
} else if (t == Exception::RUBYError) {
crash_reason = "Internal Error";
crash_possible_solution = "Try reinstall game or disable some mods";
} else if (t == Exception::IOError) {
crash_reason = "Broken installation";
crash_possible_solution = "Try reinstall game";
} else if (t == Exception::TypeError) {
crash_reason = "Internal Error";
crash_possible_solution = "Try reinstall game or disable some mods";
} else if (t == Exception::ArgumentError) {
crash_reason = "Internal error";
crash_possible_solution = "Try reinstall game or disable some mods";
} else if (t == Exception::PHYSFSError) {
crash_reason = "Internal error";
crash_possible_solution = "Maybe you tryed load corrupted mod via modloader, try delete it";
} else if (t == Exception::SDLError) {
crash_reason = "Internal error";
crash_possible_solution = "Internal Engine Error, maybe something wrong with your device or operating system";
} else if (t == Exception::MKXPError) {
crash_reason = "Internal error";
crash_possible_solution = "Try reinstall game or disable some mods";
}
show_crash_sceen = true; show_crash_sceen = true;
rb_exit(-1); //Protect against segfaults
if(is_ruby_initialized)
ruby_stop(-1);
} }
void crash_screen(SDL_Window* win){ void crash_screen(SDL_Window* win){
@ -293,6 +312,26 @@ void ErrorMsg(const char *fmt, ...) {
show_crash_sceen = true; show_crash_sceen = true;
} }
void ErrorMsg(Exception::Type t, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
va_list args_copy;
va_copy(args_copy, args);
unsigned int len = (unsigned int)SDL_vsnprintf(NULL, 0, fmt, args_copy);
va_end(args_copy);
char *buf = (char*)SDL_malloc((size_t)len + 1);
if (!buf) { va_end(args); return; }
SDL_vsnprintf(buf, (size_t)len + 1, fmt, args);
va_end(args);
SDL_snprintf(crash_message, sizeof(crash_message), "%s", buf);
get_reason_and_solution(t);
show_crash_sceen = true;
}
void WarnMsg(const char *fmt, ...) { void WarnMsg(const char *fmt, ...) {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);

View File

@ -7,10 +7,12 @@
inline std::vector<std::string> logs = {}; inline std::vector<std::string> logs = {};
inline bool show_crash_sceen = false; inline bool show_crash_sceen = false;
inline char crash_reason[1024] = "Unknown"; inline bool is_ruby_initialized = false;
inline char crash_message[1024] = ""; inline char crash_message[1024] = "";
inline char crash_possible_solution[1024] = "Unknown"; inline const char* crash_reason = "Unknown";
inline const char* crash_possible_solution = "Unknown";
void crash(Exception::Type t, const char *fmt, ...); void crash(Exception::Type t, const char *fmt, ...);
void ErrorMsg(const char *fmt, ...); void ErrorMsg(const char *fmt, ...);
void ErrorMsg(Exception::Type t, const char *fmt, ...);
void WarnMsg(const char *fmt, ...); void WarnMsg(const char *fmt, ...);
void crash_screen(SDL_Window* win); void crash_screen(SDL_Window* win);