Print bound region when bound checking error occurs
[tinycc.git] / lib / bt-log.c
blobace51170da39883cb288d4fa16b5a2ee19fa1906
1 /* ------------------------------------------------------------- */
2 /* function to get a stack backtrace on demand with a message */
4 #include <stdarg.h>
5 #include <stdio.h>
6 #include <string.h>
7 #undef __attribute__
9 #ifdef _WIN32
10 # define DLL_EXPORT __declspec(dllexport)
11 #else
12 # define DLL_EXPORT
13 #endif
15 /* Needed when using ...libtcc1-usegcc=yes in lib/Makefile */
16 #if (defined(__GNUC__) && (__GNUC__ >= 6)) || defined(__clang__)
17 #pragma GCC diagnostic push
18 #pragma GCC diagnostic ignored "-Wframe-address"
19 #endif
21 typedef struct rt_frame {
22 void *ip, *fp, *sp;
23 } rt_frame;
25 __attribute__((weak))
26 int _tcc_backtrace(rt_frame *f, const char *fmt, va_list ap);
28 DLL_EXPORT int tcc_backtrace(const char *fmt, ...)
30 va_list ap;
31 int ret;
33 if (_tcc_backtrace) {
34 rt_frame f;
35 f.fp = __builtin_frame_address(1);
36 f.ip = __builtin_return_address(0);
37 va_start(ap, fmt);
38 ret = _tcc_backtrace(&f, fmt, ap);
39 va_end(ap);
40 } else {
41 const char *p, *nl = "\n";
42 if (fmt[0] == '^' && (p = strchr(fmt + 1, fmt[0])))
43 fmt = p + 1;
44 if (fmt[0] == '\001')
45 ++fmt, nl = "";
46 va_start(ap, fmt);
47 ret = vfprintf(stderr, fmt, ap);
48 va_end(ap);
49 fprintf(stderr, "%s", nl), fflush(stderr);
51 return ret;
54 #if (defined(__GNUC__) && (__GNUC__ >= 6)) || defined(__clang__)
55 #pragma GCC diagnostic pop
56 #endif