Linux diagnostics updates
This commit is contained in:
+1
-1
@@ -241,7 +241,7 @@ if a.platform == "linux":
|
||||
else:
|
||||
# the menu and runtime as a DLL at 0x40000000, plus the small launcher that owns PS2 RAM
|
||||
dll = os.path.join(out, "rac1_game.dll")
|
||||
link = zig + ["cc", "-shared", "-target", target, "-o", dll, objs_rsp("link")] + ["-Wl,--image-base=0x40000000", "-Wl,--no-dynamicbase", "-lshell32", "-lwinmm", "-lgdi32", "-luser32"]
|
||||
link = zig + ["cc", "-shared", "-target", target, "-o", dll, objs_rsp("link")] + ["-Wl,--image-base=0x40000000", "-Wl,--no-dynamicbase", "-lshell32", "-lwinmm", "-lgdi32", "-luser32", "-ladvapi32"]
|
||||
r = subprocess.run(link, capture_output=True, text=True)
|
||||
if r.returncode:
|
||||
print(r.stderr[-6000:]); sys.exit("link failed (dll)")
|
||||
|
||||
@@ -23,6 +23,7 @@ extern const int uya_tramp_count;
|
||||
/* platform layer */
|
||||
int plat_map_fixed(uint32_t addr, uint32_t size, int exec); /* 0 on success */
|
||||
int plat_install_trap_handler(void); /* calls into unmapped PS2 code */
|
||||
void plat_log_system(void); /* the system, for bug reports (once, at start) */
|
||||
void plat_flush_icache(void *p, size_t n);
|
||||
const char *plat_exe_dir(void); /* folder of the running program */
|
||||
void plat_at_exit(void);
|
||||
|
||||
@@ -63,6 +63,7 @@ int uya_main(int argc, char **argv)
|
||||
uya_log_open();
|
||||
uya_log("Project Solana: starting");
|
||||
plat_install_trap_handler(); /* first: a crash from here on is logged */
|
||||
plat_log_system();
|
||||
{ /* renderer=gl|soft in the cfg (UYA_RENDERER overrides it) */
|
||||
extern const char *uya_renderer_cfg;
|
||||
const char *r = cfg_value("renderer");
|
||||
|
||||
@@ -180,8 +180,30 @@ int plat_install_trap_handler(void)
|
||||
sigaction(SIGBUS, &sa, 0);
|
||||
sigaction(SIGILL, &sa, 0);
|
||||
sigaction(SIGFPE, &sa, 0);
|
||||
sigaction(SIGABRT, &sa, 0); /* (a library giving up: assert, abort) */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <sys/utsname.h>
|
||||
void plat_log_system(void)
|
||||
{
|
||||
struct utsname u;
|
||||
char os[160] = "unknown", line[256], cpu[160] = "?";
|
||||
FILE *f = fopen("/etc/os-release", "r");
|
||||
while (f && fgets(line, sizeof line, f))
|
||||
if (!strncmp(line, "PRETTY_NAME=", 12)) { char *v = line + 12; if (*v == '"') v++; v[strcspn(v, "\"\n")] = 0; snprintf(os, sizeof os, "%s", v); }
|
||||
if (f) fclose(f);
|
||||
f = fopen("/proc/cpuinfo", "r");
|
||||
while (f && fgets(line, sizeof line, f))
|
||||
if (!strncmp(line, "model name", 10)) { char *v = strchr(line, ':'); if (v) { v += 2; v[strcspn(v, "\n")] = 0; snprintf(cpu, sizeof cpu, "%s", v); break; } }
|
||||
if (f) fclose(f);
|
||||
if (uname(&u) == 0) uya_log("system: Linux %s (%s), %s", u.release, u.machine, os);
|
||||
uya_log("system: %s, %ld cores, %ld MB RAM", cpu, sysconf(_SC_NPROCESSORS_ONLN), (long)((long long)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE) >> 20));
|
||||
const char *st = getenv("XDG_SESSION_TYPE"), *de = getenv("XDG_CURRENT_DESKTOP");
|
||||
uya_log("system: session %s%s%s, DISPLAY %s, WAYLAND_DISPLAY %s%s", st ? st : "?", de ? ", desktop " : "", de ? de : "",
|
||||
getenv("DISPLAY") ? getenv("DISPLAY") : "-", getenv("WAYLAND_DISPLAY") ? getenv("WAYLAND_DISPLAY") : "-",
|
||||
getenv("SteamDeck") && !strcmp(getenv("SteamDeck"), "1") ? ", Steam Deck" : getenv("SteamAppId") ? ", started by Steam" : "");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
@@ -83,6 +83,9 @@ static struct {
|
||||
int (*QueueAudio)(SDL_AudioDeviceID, const void *, uint32_t);
|
||||
uint32_t (*GetQueuedAudioSize)(SDL_AudioDeviceID);
|
||||
void (*ClearQueuedAudio)(SDL_AudioDeviceID);
|
||||
void (*GetVersion)(uint8_t v[3]);
|
||||
const char *(*GetCurrentVideoDriver)(void);
|
||||
const char *(*GetCurrentAudioDriver)(void);
|
||||
} sdl;
|
||||
|
||||
/* 1: SDL is there and a display is (the game draws in a window); 0: headless */
|
||||
@@ -105,7 +108,7 @@ static int sdl_on(void)
|
||||
"SDL_NumJoysticks", "SDL_IsGameController", "SDL_GameControllerOpen", "SDL_GameControllerClose",
|
||||
"SDL_GameControllerGetAttached", "SDL_GameControllerName", "SDL_GameControllerGetButton", "SDL_GameControllerGetAxis",
|
||||
"SDL_OpenAudioDevice", "SDL_CloseAudioDevice", "SDL_PauseAudioDevice", "SDL_QueueAudio", "SDL_GetQueuedAudioSize",
|
||||
"SDL_ClearQueuedAudio",
|
||||
"SDL_ClearQueuedAudio", "SDL_GetVersion", "SDL_GetCurrentVideoDriver", "SDL_GetCurrentAudioDriver",
|
||||
};
|
||||
void **fp = (void **)&sdl;
|
||||
for (unsigned i = 0; i < sizeof names / sizeof names[0]; i++)
|
||||
@@ -116,6 +119,12 @@ static int sdl_on(void)
|
||||
uya_log("SDL2: cannot start (%s)", sdl.GetError());
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
uint8_t v[3] = {0, 0, 0};
|
||||
const char *vd = sdl.GetCurrentVideoDriver(), *ad = sdl.GetCurrentAudioDriver();
|
||||
sdl.GetVersion(v);
|
||||
uya_log("SDL %d.%d.%d: video %s, audio %s", v[0], v[1], v[2], vd ? vd : "none", ad ? ad : "none");
|
||||
}
|
||||
sdl_state = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -180,11 +180,37 @@ static LONG CALLBACK on_exception(EXCEPTION_POINTERS *ep)
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
#include <signal.h>
|
||||
/* abort() (a library giving up) ends the process without an exception: raise one, so the
|
||||
* crash handler reports it with the call chain */
|
||||
static void on_abort(int sig)
|
||||
{
|
||||
(void)sig;
|
||||
uya_log("crash: abort() was called");
|
||||
RaiseException(0xE0000ABE, EXCEPTION_NONCONTINUABLE, 0, 0);
|
||||
}
|
||||
int plat_install_trap_handler(void)
|
||||
{
|
||||
signal(SIGABRT, on_abort);
|
||||
return AddVectoredExceptionHandler(1, on_exception) ? 0 : -1;
|
||||
}
|
||||
|
||||
void plat_log_system(void)
|
||||
{
|
||||
typedef struct { ULONG size, major, minor, build, platform; WCHAR sp[128]; } osv_t;
|
||||
HMODULE nt = GetModuleHandleA("ntdll.dll");
|
||||
LONG (WINAPI *rtl_ver)(osv_t *) = nt ? (void *)GetProcAddress(nt, "RtlGetVersion") : 0;
|
||||
const char *(*wine_ver)(void) = nt ? (void *)GetProcAddress(nt, "wine_get_version") : 0;
|
||||
osv_t v; memset(&v, 0, sizeof v); v.size = sizeof v;
|
||||
if (rtl_ver) rtl_ver(&v);
|
||||
SYSTEM_INFO si; GetNativeSystemInfo(&si);
|
||||
MEMORYSTATUSEX ms; memset(&ms, 0, sizeof ms); ms.dwLength = sizeof ms; GlobalMemoryStatusEx(&ms);
|
||||
char cpu[128] = "?"; DWORD cl = sizeof cpu;
|
||||
RegGetValueA(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", "ProcessorNameString", RRF_RT_REG_SZ, 0, cpu, &cl);
|
||||
uya_log("system: Windows %lu.%lu build %lu%s%s, %s, %lu cores, %llu MB RAM", v.major, v.minor, v.build,
|
||||
wine_ver ? ", Wine " : "", wine_ver ? wine_ver() : "", cpu, si.dwNumberOfProcessors, (unsigned long long)(ms.ullTotalPhys >> 20));
|
||||
}
|
||||
|
||||
uint64_t plat_time_us(void)
|
||||
{
|
||||
static LARGE_INTEGER f;
|
||||
|
||||
@@ -109,6 +109,11 @@ void uya_log_open(void)
|
||||
{
|
||||
char p[1024];
|
||||
snprintf(p, sizeof p, "%s/rac1_log.txt", plat_exe_dir());
|
||||
{ /* the previous run's log is kept as rac1_log.prev.txt (a retry after a crash keeps the crash) */
|
||||
char q[1100];
|
||||
snprintf(q, sizeof q, "%s/rac1_log.prev.txt", plat_exe_dir());
|
||||
remove(q); rename(p, q);
|
||||
}
|
||||
logfile = fopen(p, "w");
|
||||
if (logfile) fprintf(stderr, "[uya] log file: %s\n", p);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user