From e8841153c61592f4fd31d748ee526413145e123d Mon Sep 17 00:00:00 2001 From: krzosa Date: Sun, 23 Feb 2025 11:36:44 +0100 Subject: [PATCH] add stacktrace, improve assert, improve debugbreak --- .gitignore | 2 + build_file.c | 4 +- src/app/app.gen.c | 4 +- src/app/app.gen.h | 4 +- src/core/core.c | 9 + src/core/core.h | 2 +- src/core/core_basic.h | 31 +-- src/core/core_log.h | 6 +- src/core/core_platform_unix.c | 22 ++ src/core/core_platform_win32.c | 12 + src/core/stacktrace.h | 412 +++++++++++++++++++++++++++++++++ src/render/render.c | 2 +- src/render/render.gen.c | 2 +- src/render/render_font.c | 2 +- src/render/render_opengl.c | 2 +- src/testing/testing_main.c | 1 + src/ui/ui.gen.c | 2 +- src/ui/ui.gen.h | 2 +- src/wasm_app/main.c | 1 - src/wasm_app/wasm_app.gen.c | 2 +- 20 files changed, 493 insertions(+), 31 deletions(-) create mode 100644 src/core/stacktrace.h diff --git a/.gitignore b/.gitignore index 6b7b91c..cab6fcb 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ multimedia.h playground.py ui_notes.txt +l.log + build/ *.wasm diff --git a/build_file.c b/build_file.c index 544b433..029a817 100644 --- a/build_file.c +++ b/build_file.c @@ -39,9 +39,9 @@ int main(int argc, char **argv) { b32 run_server = false; b32 core_test_target = false; - b32 win32_target = true; + b32 win32_target = false; b32 standalone_w32_target = false; - b32 wasm_target = false; + b32 wasm_target = true; if (run_server) { os_systemf("start /D ..\\package ..\\package\\run_server.bat"); diff --git a/src/app/app.gen.c b/src/app/app.gen.c index a555b09..1d4f77b 100644 --- a/src/app/app.gen.c +++ b/src/app/app.gen.c @@ -1,4 +1,4 @@ -// automatically generated using: C:\dev\wasm\src/app/app.meta.c +// automatically generated using: D:\dev\wasm\src/app/app.meta.c type_t type__app_key_t = { type_kind_enum, s8_const_lit("app_key_t"), sizeof(app_key_t), .members = (type_member_t[]){ @@ -228,7 +228,7 @@ app_key_t w32_map_wparam_to_app_key(WPARAM wparam) { default: {return app_key_null;} break; } } -#endif/*C:\dev\wasm\src/app/app.meta.c(135)*/ +#endif/*D:\dev\wasm\src/app/app.meta.c(135)*/ type_t type__app_mouse_button_t = { type_kind_enum, s8_const_lit("app_mouse_button_t"), sizeof(app_mouse_button_t), .members = (type_member_t[]){ {.name = s8_const_lit("app_mouse_button_null"), .value = app_mouse_button_null}, diff --git a/src/app/app.gen.h b/src/app/app.gen.h index 9308a21..98150fd 100644 --- a/src/app/app.gen.h +++ b/src/app/app.gen.h @@ -1,4 +1,4 @@ -// automatically generated using: C:\dev\wasm\src/app/app.meta.c +// automatically generated using: D:\dev\wasm\src/app/app.meta.c typedef enum { app_key_null, app_key_1, @@ -71,7 +71,7 @@ app_key_page_up, app_key_page_down, app_key_count, } app_key_t; -/*C:\dev\wasm\src/app/app.meta.c(135)*/ +/*D:\dev\wasm\src/app/app.meta.c(135)*/ typedef enum { app_mouse_button_null, app_mouse_button_left, diff --git a/src/core/core.c b/src/core/core.c index 922d237..8e5d726 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -9,6 +9,9 @@ #include #include #include + #include + #define B_STACKTRACE_IMPL + #include "stacktrace.h" #include "core_platform_win32.c" #else #include @@ -17,6 +20,12 @@ #include #include #include + #include + + #define B_STACKTRACE_IMPL + #include "stacktrace.h" +//:unix_debug_break +//static void os_unix_sigtrap(int signum) { signal(SIGTRAP, SIG_DFL); } #include "core_platform_unix.c" #endif diff --git a/src/core/core.h b/src/core/core.h index 336026d..04459c3 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -13,4 +13,4 @@ #include "core_intrin.h" #include "core_platform.h" #include "core_hash_table.h" -#include "core_ctx.h" \ No newline at end of file +#include "core_ctx.h" diff --git a/src/core/core_basic.h b/src/core/core_basic.h index 5ea8cdd..5a56dee 100644 --- a/src/core/core_basic.h +++ b/src/core/core_basic.h @@ -106,9 +106,9 @@ union convert_f32_i32_t { f32 f; i32 i; }; #define STACK_CAP(stack) (lengthof((stack).data)) #define STACK_EMPTY(stack) ((stack).len == 0) #define STACK_FULL(stack) ((stack).len == STACK_CAP(stack)) -#define STACK_PUSH(stack, ...) (assert(!STACK_FULL(stack)), (stack).data[(stack).len++] = __VA_ARGS__) -#define STACK_POP(stack) (assert(!STACK_EMPTY(stack)), (stack).data[--(stack).len]) -#define STACK_TOP(stack) (assert(!STACK_EMPTY(stack)), (stack).data[((stack).len-1)]) +#define STACK_PUSH(stack, ...) (assert_expr(!STACK_FULL(stack)), (stack).data[(stack).len++] = __VA_ARGS__) +#define STACK_POP(stack) (assert_expr(!STACK_EMPTY(stack)), (stack).data[--(stack).len]) +#define STACK_TOP(stack) (assert_expr(!STACK_EMPTY(stack)), (stack).data[((stack).len-1)]) #define STRINGIFY_(S) #S #define STRINGIFY(S) STRINGIFY_(S) @@ -141,11 +141,14 @@ union convert_f32_i32_t { f32 f; i32 i; }; #endif #if PLATFORM_CL - #define debug__break() __debugbreak() + #define debug__break() (IsDebuggerPresent() && (__debugbreak(), 1)) #else #define debug__break() __builtin_trap() + //:unix_debug_break + // https://github.com/r-lyeh/tinybits/blob/master/tinyassert.c + // #define debug__break() (signal(SIGTRAP, break_handler_), raise(SIGTRAP)) #endif -#define debug_break() (debug__break(), 0) +#define debug_break() (debug__break(), 1) #if PLATFORM_WASM #define gb_thread @@ -164,7 +167,7 @@ union convert_f32_i32_t { f32 f; i32 i; }; // Single linked list Queue #define SLLQ_APPEND_EX(f, l, n, next) \ do { \ - assert((n)->next == NULL); \ + assert_expr((n)->next == NULL); \ if ((f) == 0) { \ (f) = (l) = (n); \ } else { \ @@ -175,7 +178,7 @@ union convert_f32_i32_t { f32 f; i32 i; }; #define SLLQ_PREPEND_EX(f, l, n, next) \ do { \ - assert((n)->next == NULL); \ + assert_expr((n)->next == NULL); \ if ((f) == 0) { \ (f) = (l) = (n); \ } else { \ @@ -217,8 +220,8 @@ union convert_f32_i32_t { f32 f; i32 i; }; // Doubly linked list Queue #define DLLQ_APPEND_EX(f, l, node, next, prev) \ do { \ - assert((node)->next == NULL); \ - assert((node)->prev == NULL); \ + assert_expr((node)->next == NULL); \ + assert_expr((node)->prev == NULL); \ if ((f) == 0) { \ (f) = (l) = (node); \ } else { \ @@ -231,8 +234,8 @@ union convert_f32_i32_t { f32 f; i32 i; }; #define DLLQ_PREPEND_EX(f, l, node, next, prev) \ do { \ - assert((node)->next == NULL); \ - assert((node)->prev == NULL); \ + assert_expr((node)->next == NULL); \ + assert_expr((node)->prev == NULL); \ if ((f) == 0) { \ (f) = (l) = (node); \ } else { \ @@ -248,7 +251,7 @@ union convert_f32_i32_t { f32 f; i32 i; }; #define DLLQ_REMOVE_EX(first, last, node, next, prev) \ do { \ if ((first) == (last)) { \ - assert((node) == (first)); \ + assert_expr((node) == (first)); \ (first) = (last) = 0; \ } else if ((last) == (node)) { \ (last) = (last)->prev; \ @@ -270,8 +273,8 @@ union convert_f32_i32_t { f32 f; i32 i; }; // Doubly linked list Stack #define DLLS_PUSH_EX(first, node, next, prev) \ do { \ - assert((node)->next == NULL); \ - assert((node)->prev == NULL); \ + assert_expr((node)->next == NULL); \ + assert_expr((node)->prev == NULL); \ (node)->next = (first); \ if ((first)) \ (first)->prev = (node); \ diff --git a/src/core/core_log.h b/src/core/core_log.h index 7070884..af92320 100644 --- a/src/core/core_log.h +++ b/src/core/core_log.h @@ -26,9 +26,11 @@ fn void default_log_proc(log_level_t level, s8_t file_and_line, s8_t string); fn void log_basef(log_level_t level, s8_t file_and_line, const char *str, ...); #if PLATFORM_DEBUG_ASSERT -#define assert(x) (!(x) && (os_error_box(FILE_AND_LINE ": assertion failed: " #x "\n"), debug_break())) +#define assert_expr(x) (!(x) && (os_error_box(FILE_AND_LINE ": assertion failed: " #x "\n"), debug_break())) +#define assert(x) do { static int once = 1; for (;once;once=0) assert_expr(x); } while(0) #else -#define assert(x) (void)(x) +#define assert_expr(x) (void)(x) +#define assert(x) do { (void)(x); } while(0) #endif #define not_implemented assert(!"not implemented!") #define invalid_codepath assert(!"invalid code path!") diff --git a/src/core/core_platform_unix.c b/src/core/core_platform_unix.c index 6c8b60d..90f5618 100644 --- a/src/core/core_platform_unix.c +++ b/src/core/core_platform_unix.c @@ -33,7 +33,29 @@ fn f64 os_parse_float(char *str) { return strtod(str, NULL); } +fn void os_unix_crash_handler(int signal, siginfo_t* info, void* context) { + context; // unused + printf("signal: %d", signal); + if (signal == SIGSEGV) { + printf(" at addr: %p", info->si_addr); + } + puts(""); + puts(b_stacktrace_get_string()); + exit(1); +} + +fn void os_unix_register_crash_handler() { + struct sigaction sa; + sa.sa_sigaction = os_unix_crash_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART | SA_SIGINFO; + + sigaction(SIGSEGV, &sa, NULL); + sigaction(SIGABRT, &sa, NULL); +} + fn void os_core_init(void) { tcx->temp = ma_create(ma_default_reserve_size); ma_init(&tcx->perm, ma_default_reserve_size); + os_unix_register_crash_handler(); } \ No newline at end of file diff --git a/src/core/core_platform_win32.c b/src/core/core_platform_win32.c index e610723..2a3d0d4 100644 --- a/src/core/core_platform_win32.c +++ b/src/core/core_platform_win32.c @@ -34,7 +34,19 @@ fn f64 os_parse_float(char *str) { return strtod(str, NULL); } +fn void os_win32_crash_handler(int signal) { + printf("signal: %d\n", signal); + puts(b_stacktrace_get_string()); + exit(1); +} + +fn void os_win32_register_crash_handler() { + signal(SIGSEGV, os_win32_crash_handler); + signal(SIGABRT, os_win32_crash_handler); +} + fn void os_core_init(void) { tcx->temp = ma_create(ma_default_reserve_size); ma_init(&tcx->perm, ma_default_reserve_size); + os_win32_register_crash_handler(); } \ No newline at end of file diff --git a/src/core/stacktrace.h b/src/core/stacktrace.h new file mode 100644 index 0000000..288df9a --- /dev/null +++ b/src/core/stacktrace.h @@ -0,0 +1,412 @@ +#if !defined(B_STACKTRACE_INCLUDED) +#define B_STACKTRACE_INCLUDED (1) +/* +b_stacktrace v0.21 -- a cross-platform stack-trace generator +SPDX-License-Identifier: MIT +URL: https://github.com/iboB/b_stacktrace + +Usage +===== + +#define B_STACKTRACE_IMPL before including b_stacktrace.h in *one* C or C++ +file to create the implementation + +#include "b_stacktrace.h" to get access to the following functions: + +char* b_stacktrace_get_string(); + Returns a human-readable stack-trace string from the point of view of the + caller. + The string is allocated with `malloc` and needs to be freed with `free` + +b_stacktrace_handle b_stacktrace_get(); + Returns a stack-trace handle from the point of view of the caller which + can be expanded to a string via b_stacktrace_to_string. + The handle is allocated with `malloc` and needs to be freed with `free` + +b_stacktrace_to_string(b_stacktrace_handle stacktrace); + Converts a stack-trace handle to a human-readable string. + The string is allocated with `malloc` and needs to be freed with `free` + + +Config +====== + +#define B_STACKTRACE_API to custom export symbols to export the library +functions from a shared lib + +Revision History +================ + +* 0.21 (2022-12-20) Fixed typo +* 0.20 (2022-12-18) Beta. + Expanded interface + Minor fixes +* 0.10 (2020-12-07) Initial public release. Alpha version + +MIT License +=========== + +Copyright (c) 2020-2023 Borislav Stanimirov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#if !defined(B_STACKTRACE_API) +#define B_STACKTRACE_API extern +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + A stacktrace handle +*/ +typedef struct b_stacktrace_tag* b_stacktrace_handle; + +/* + Returns a stack-trace handle from the point of view of the caller which + can be expanded to a string via b_stacktrace_to_string. + The handle is allocated with `malloc` and needs to be freed with `free` +*/ +B_STACKTRACE_API b_stacktrace_handle b_stacktrace_get(); + +/* + Converts a stack-trace handle to a human-readable string. + The string is allocated with `malloc` and needs to be freed with `free` +*/ +B_STACKTRACE_API char* b_stacktrace_to_string(b_stacktrace_handle stacktrace); + +/* + Returns a human-readable stack-trace string from the point of view of the + caller. + The string is allocated with `malloc` and needs to be freed with `free` +*/ +B_STACKTRACE_API char* b_stacktrace_get_string(void); + +/* version */ +#define B_STACKTRACE_VER_MAJOR 0 +#define B_STACKTRACE_VER_MINOR 20 + +#ifdef __cplusplus +} +#endif + +#if defined(B_STACKTRACE_IMPL) + +#if defined(__linux__) && !defined(_GNU_SOURCE) +#define _GNU_SOURCE +#endif + +#include +#include +#include + +typedef struct print_buf { + char* buf; + int pos; + int size; +} print_buf; + +static print_buf buf_init(void) { + print_buf ret = { + (char*) malloc(1024), + 0, + 1024 + }; + return ret; +} + +static void buf_printf(print_buf* b, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + const int len = vsnprintf(NULL, 0, fmt, args) + 1; + va_end(args); + + const int new_end = b->pos + len; + + if (new_end > b->size) { + while (new_end > b->size) b->size *= 2; + b->buf = (char*)realloc(b->buf, b->size); + } + + va_start(args, fmt); + b->pos += vsnprintf(b->buf + b->pos, len, fmt, args); + va_end(args); +} + +char* b_stacktrace_get_string(void) { + b_stacktrace_handle h = b_stacktrace_get(); + char* ret = b_stacktrace_to_string(h); + free(h); + return ret; +} + +#define B_STACKTRACE_MAX_DEPTH 1024 + +#if defined(_WIN32) + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#pragma comment(lib, "DbgHelp.lib") + +#define B_STACKTRACE_ERROR_FLAG ((DWORD64)1 << 63) + +typedef struct b_stacktrace_entry { + DWORD64 AddrPC_Offset; + DWORD64 AddrReturn_Offset; +} b_stacktrace_entry; + +static int SymInitialize_called = 0; + +b_stacktrace_handle b_stacktrace_get(void) { + HANDLE process = GetCurrentProcess(); + HANDLE thread = GetCurrentThread(); + CONTEXT context; + STACKFRAME64 frame; /* in/out stackframe */ + DWORD imageType; + b_stacktrace_entry* ret = (b_stacktrace_entry*)malloc(B_STACKTRACE_MAX_DEPTH * sizeof(b_stacktrace_entry)); + int i = 0; + + if (!SymInitialize_called) { + SymInitialize(process, NULL, TRUE); + SymInitialize_called = 1; + } + + RtlCaptureContext(&context); + + memset(&frame, 0, sizeof(frame)); +#ifdef _M_IX86 + imageType = IMAGE_FILE_MACHINE_I386; + frame.AddrPC.Offset = context.Eip; + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrFrame.Offset = context.Ebp; + frame.AddrFrame.Mode = AddrModeFlat; + frame.AddrStack.Offset = context.Esp; + frame.AddrStack.Mode = AddrModeFlat; +#elif _M_X64 + imageType = IMAGE_FILE_MACHINE_AMD64; + frame.AddrPC.Offset = context.Rip; + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrFrame.Offset = context.Rsp; + frame.AddrFrame.Mode = AddrModeFlat; + frame.AddrStack.Offset = context.Rsp; + frame.AddrStack.Mode = AddrModeFlat; +#elif _M_IA64 + imageType = IMAGE_FILE_MACHINE_IA64; + frame.AddrPC.Offset = context.StIIP; + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrFrame.Offset = context.IntSp; + frame.AddrFrame.Mode = AddrModeFlat; + frame.AddrBStore.Offset = context.RsBSP; + frame.AddrBStore.Mode = AddrModeFlat; + frame.AddrStack.Offset = context.IntSp; + frame.AddrStack.Mode = AddrModeFlat; +#else + #error "Platform not supported!" +#endif + + while (1) { + b_stacktrace_entry* cur = ret + i++; + if (i == B_STACKTRACE_MAX_DEPTH) { + cur->AddrPC_Offset = 0; + cur->AddrReturn_Offset = 0; + break; + } + + if (!StackWalk64(imageType, process, thread, &frame, &context, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL)) { + cur->AddrPC_Offset = frame.AddrPC.Offset; + cur->AddrReturn_Offset = B_STACKTRACE_ERROR_FLAG; /* mark error */ + cur->AddrReturn_Offset |= GetLastError(); + break; + } + + cur->AddrPC_Offset = frame.AddrPC.Offset; + cur->AddrReturn_Offset = frame.AddrReturn.Offset; + + if (frame.AddrReturn.Offset == 0) { + break; + } + } + + return (b_stacktrace_handle)(ret); +} + +char* b_stacktrace_to_string(b_stacktrace_handle h) { + const b_stacktrace_entry* entries = (b_stacktrace_entry*)h; + int i = 0; + HANDLE process = GetCurrentProcess(); + print_buf out = buf_init(); + IMAGEHLP_SYMBOL64* symbol = (IMAGEHLP_SYMBOL64*)malloc(sizeof(IMAGEHLP_SYMBOL64) + 1024); + symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); + symbol->MaxNameLength = 1024; + + while (1) { + IMAGEHLP_LINE64 lineData; + DWORD lineOffset = 0; + DWORD64 symOffset = 0; + const b_stacktrace_entry* cur = entries + i++; + + if (cur->AddrReturn_Offset & B_STACKTRACE_ERROR_FLAG) { + DWORD error = cur->AddrReturn_Offset & 0xFFFFFFFF; + buf_printf(&out, "StackWalk64 error: %d @ %p\n", error, cur->AddrPC_Offset); + break; + } + + if (cur->AddrPC_Offset == cur->AddrReturn_Offset) { + buf_printf(&out, "Stack overflow @ %p\n", cur->AddrPC_Offset); + break; + } + + SymGetLineFromAddr64(process, cur->AddrPC_Offset, &lineOffset, &lineData); + buf_printf(&out, "%s(%d): ", lineData.FileName, lineData.LineNumber); + + if (SymGetSymFromAddr64(process, cur->AddrPC_Offset, &symOffset, symbol)) { + buf_printf(&out, "%s\n", symbol->Name); + } + else { + buf_printf(&out, " Unkown symbol @ %p\n", cur->AddrPC_Offset); + } + + if (cur->AddrReturn_Offset == 0) { + break; + } + } + + free(symbol); + return out.buf; +} + +#elif defined(__APPLE__) + +#include +#include +#include + +typedef struct b_stacktrace { + void* trace[B_STACKTRACE_MAX_DEPTH]; + int trace_size; +} b_stacktrace; + +b_stacktrace_handle b_stacktrace_get(void) { + b_stacktrace* ret = (b_stacktrace*)malloc(sizeof(b_stacktrace)); + ret->trace_size = backtrace(ret->trace, B_STACKTRACE_MAX_DEPTH); + return (b_stacktrace_handle)(ret); +} + +char* b_stacktrace_to_string(b_stacktrace_handle h) { + const b_stacktrace* stacktrace = (b_stacktrace*)h; + char** messages = backtrace_symbols(stacktrace->trace, stacktrace->trace_size); + print_buf out = buf_init(); + *out.buf = 0; + + for (int i = 0; i < stacktrace->trace_size; ++i) { + buf_printf(&out, "%s\n", messages[i]); + } + + free(messages); + return out.buf; +} + +#elif defined(__linux__) + +#include +#include +#include +#include +#include + +typedef struct b_stacktrace { + void* trace[B_STACKTRACE_MAX_DEPTH]; + int trace_size; +} b_stacktrace; + +b_stacktrace_handle b_stacktrace_get(void) { + b_stacktrace* ret = (b_stacktrace*)malloc(sizeof(b_stacktrace)); + ret->trace_size = backtrace(ret->trace, B_STACKTRACE_MAX_DEPTH); + return (b_stacktrace_handle)(ret); +} + +char* b_stacktrace_to_string(b_stacktrace_handle h) { + const b_stacktrace* stacktrace = (b_stacktrace*)h; + char** messages = backtrace_symbols(stacktrace->trace, stacktrace->trace_size); + print_buf out = buf_init(); + + for (int i = 0; i < stacktrace->trace_size; ++i) { + void* tracei = stacktrace->trace[i]; + char* msg = messages[i]; + + /* calculate load offset */ + Dl_info info; + dladdr(tracei, &info); + if (info.dli_fbase == (void*)0x400000) { + /* address from executable, so don't offset */ + info.dli_fbase = NULL; + } + + while (*msg && *msg != '(') ++msg; + *msg = 0; + + { + char cmd[1024]; + char line[2048]; + + FILE* fp; + snprintf(cmd, 1024, "addr2line -e %s -f -C -p %p 2>/dev/null", messages[i], (void*)((char*)tracei - (char*)info.dli_fbase)); + + fp = popen(cmd, "r"); + if (!fp) { + buf_printf(&out, "Failed to generate trace further...\n"); + break; + } + + while (fgets(line, sizeof(line), fp)) { + buf_printf(&out, "%s: ", messages[i]); + if (strstr(line, "?? ")) { + /* just output address if nothing can be found */ + buf_printf(&out, "%p\n", tracei); + } + else { + buf_printf(&out, "%s", line); + } + } + + pclose(fp); + } + } + + free(messages); + return out.buf; +} + +#else +/* noop implementation */ +char* b_stacktrace_get_string(void) { + print_buf out = buf_init(); + buf_printf("b_stacktrace: unsupported platform\n"); + return out.buf; +} +#endif /* platform */ + +#endif /* B_STACKTRACE_IMPL */ +#endif /* B_STACKTRACE_INCLUDED */ + diff --git a/src/render/render.c b/src/render/render.c index 9c271ee..c239933 100644 --- a/src/render/render.c +++ b/src/render/render.c @@ -9,7 +9,7 @@ #define STBTT_cos(x) (f64_cos(x)) #define STBTT_acos(x) (f64_acos(x)) #define STBTT_fabs(x) (f64_abs(x)) -#define STBTT_assert(x) (assert(x)) +#define STBTT_assert(x) assert(x) #define STBTT_malloc(x,u) (ma_push_size(tcx->temp, x)) #define STBTT_free(x,u) #define STBTT_strlen(x) (str_len(x)) diff --git a/src/render/render.gen.c b/src/render/render.gen.c index 84754a9..1237253 100644 --- a/src/render/render.gen.c +++ b/src/render/render.gen.c @@ -1,4 +1,4 @@ -// automatically generated using: C:\dev\wasm\src/render/render.meta.c +// automatically generated using: D:\dev\wasm\src/render/render.meta.c gb_read_only u8 main_font_data[] = { 0,1,0,0,0,16,1,0,0,4,0,0,71,68,69,70,9,171,18,85,0,0,2,40,0,0,1,242,71,80,79,83,196,118,81,155,0,0,24,140,0,0,22,52,71,83,85,66,112,248,190,150,0,0,222,16,0,0,83,202,79,83,47,50, 138,149,152,224,0,0,1,200,0,0,0,96,83,84,65,84,121,145,108,221,0,0,1,96,0,0,0,46,99,109,97,112,147,243,132,151,0,0,75,136,0,0,65,218,103,97,115,112,0,0,0,16,0,0,1,20,0,0,0,8,103,108,121,102, diff --git a/src/render/render_font.c b/src/render/render_font.c index 3173ac2..e1cfaf7 100644 --- a/src/render/render_font.c +++ b/src/render/render_font.c @@ -92,7 +92,7 @@ fn b32 rn_reload_font_atlas(rn_font_t *font, s8_t font_data, rn_atlas_t *atlas, i32 xadvance, left_side_bearing; stbtt_GetCodepointHMetrics(&stb_font, ascii_symbol, &xadvance, &left_side_bearing); - rn_glyph_t glyph = {}; + rn_glyph_t glyph = {0}; glyph.atlas_bounding_box = rn_pack_bitmap(atlas, bitmap, width, height); glyph.size = (v2f32_t){(f32)width, (f32)height}; glyph.offset = (v2f32_t){(f32)xoff, (f32)yoff}; diff --git a/src/render/render_opengl.c b/src/render/render_opengl.c index 5bf620f..951a3f3 100644 --- a/src/render/render_opengl.c +++ b/src/render/render_opengl.c @@ -1,5 +1,5 @@ fn rn_shader_t rn_create_shader(char *glsl_vshader, char *glsl_fshader) { - rn_shader_t result = {}; + rn_shader_t result = {0}; result.vshader = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vshader); result.fshader = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &glsl_fshader); diff --git a/src/testing/testing_main.c b/src/testing/testing_main.c index cf7b147..6250bda 100644 --- a/src/testing/testing_main.c +++ b/src/testing/testing_main.c @@ -120,6 +120,7 @@ fn void test_s8(void) { assert(s8_are_equal(s0, s8_lit("23456789"))); assert(s8_are_equal(s1, s8_lit("01"))); } + ma_destroy(arena); } diff --git a/src/ui/ui.gen.c b/src/ui/ui.gen.c index 3210f0b..e151efb 100644 --- a/src/ui/ui.gen.c +++ b/src/ui/ui.gen.c @@ -1,4 +1,4 @@ -// automatically generated using: C:\dev\wasm\src/ui/ui.meta.c +// automatically generated using: D:\dev\wasm\src/ui/ui.meta.c type_t type__ui_color_t = { type_kind_enum, s8_const_lit("ui_color_t"), sizeof(ui_color_t), .members = (type_member_t[]){ diff --git a/src/ui/ui.gen.h b/src/ui/ui.gen.h index 5ccbc6d..9cbc0ce 100644 --- a/src/ui/ui.gen.h +++ b/src/ui/ui.gen.h @@ -1,4 +1,4 @@ -// automatically generated using: C:\dev\wasm\src/ui/ui.meta.c +// automatically generated using: D:\dev\wasm\src/ui/ui.meta.c typedef enum { ui_color_rect, ui_color_rect_hot, diff --git a/src/wasm_app/main.c b/src/wasm_app/main.c index 1e16205..90b7559 100644 --- a/src/wasm_app/main.c +++ b/src/wasm_app/main.c @@ -3,7 +3,6 @@ #include "app/app.h" #include "ui/ui.h" - #include "core/core.c" #include "os/os.c" #include "app/app.c" diff --git a/src/wasm_app/wasm_app.gen.c b/src/wasm_app/wasm_app.gen.c index 85e6f9f..13e105c 100644 --- a/src/wasm_app/wasm_app.gen.c +++ b/src/wasm_app/wasm_app.gen.c @@ -1,4 +1,4 @@ -// automatically generated using: C:\dev\wasm\src/wasm_app/wasm_app.meta.c +// automatically generated using: D:\dev\wasm\src/wasm_app/wasm_app.meta.c gb f32 font_size = 30; gb f32 _font_size = 30; gb_read_only mt_tweak_t tweak_table[] = {