aboutsummaryrefslogtreecommitdiff
path: root/tinycc/lib/bt-log.c
diff options
context:
space:
mode:
authorUneven Prankster <unevenprankster@protonmail.com>2023-07-12 13:22:29 -0300
committerUneven Prankster <unevenprankster@protonmail.com>2023-07-12 13:22:29 -0300
commitfa2bdd711212ba6b7a94a20971e8bfa281e73296 (patch)
tree6713b3c0379507d49558287b71dd360ce188a2f0 /tinycc/lib/bt-log.c
lol
Diffstat (limited to 'tinycc/lib/bt-log.c')
-rw-r--r--tinycc/lib/bt-log.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/tinycc/lib/bt-log.c b/tinycc/lib/bt-log.c
new file mode 100644
index 0000000..8f7a4db
--- /dev/null
+++ b/tinycc/lib/bt-log.c
@@ -0,0 +1,47 @@
+/* ------------------------------------------------------------- */
+/* function to get a stack backtrace on demand with a message */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+int (*__rt_error)(void*, void*, const char *, va_list);
+
+#ifdef _WIN32
+# define DLL_EXPORT __declspec(dllexport)
+#else
+# define DLL_EXPORT
+#endif
+
+/* Needed when using ...libtcc1-usegcc=yes in lib/Makefile */
+#if (defined(__GNUC__) && (__GNUC__ >= 6)) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wframe-address"
+#endif
+
+DLL_EXPORT int tcc_backtrace(const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ if (__rt_error) {
+ void *fp = __builtin_frame_address(1);
+ void *ip = __builtin_return_address(0);
+ va_start(ap, fmt);
+ ret = __rt_error(fp, ip, fmt, ap);
+ va_end(ap);
+ } else {
+ const char *p;
+ if (fmt[0] == '^' && (p = strchr(fmt + 1, fmt[0])))
+ fmt = p + 1;
+ va_start(ap, fmt);
+ ret = vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ fprintf(stderr, "\n"), fflush(stderr);
+ }
+ return ret;
+}
+
+#if (defined(__GNUC__) && (__GNUC__ >= 6)) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif