| 1115 | | void GBK_dump_backtrace(FILE *out, GB_ERROR error) { |
| 1116 | | void *array[MAX_BACKTRACE]; |
| 1117 | | size_t size = backtrace(array, MAX_BACKTRACE); // get void*'s for all entries on the stack |
| 1118 | | |
| 1119 | | if (!out) out = stderr; |
| 1120 | | |
| 1121 | | // print out all the frames to out |
| 1122 | | fprintf(out, "\n-------------------- ARB-backtrace for '%s':\n", error); |
| 1123 | | backtrace_symbols_fd(array, size, fileno(out)); |
| 1124 | | if (size == MAX_BACKTRACE) fputs("[stack truncated to avoid deadlock]\n", out); |
| 1125 | | fputs("-------------------- End of backtrace\n", out); |
| 1126 | | fflush(out); |
| | 1116 | class BackTraceInfo { |
| | 1117 | void **array; |
| | 1118 | size_t size; |
| | 1119 | public: |
| | 1120 | BackTraceInfo(size_t skipFramesAtBottom) { |
| | 1121 | void *tmp[MAX_BACKTRACE]; |
| | 1122 | size = backtrace(tmp, MAX_BACKTRACE); |
| | 1123 | |
| | 1124 | size_t ssize = skipFramesAtBottom*sizeof(*array); |
| | 1125 | size_t msize = size*sizeof(*array) - ssize; |
| | 1126 | |
| | 1127 | gb_assert(msize>0); |
| | 1128 | |
| | 1129 | array = (void**)malloc(msize); |
| | 1130 | memcpy(array, tmp+skipFramesAtBottom, msize); |
| | 1131 | } |
| | 1132 | ~BackTraceInfo() { free(array); } |
| | 1133 | |
| | 1134 | void dump(FILE *out, GB_CSTR message) { |
| | 1135 | // print out all the frames to out |
| | 1136 | fprintf(out, "\n-------------------- ARB-backtrace '%s':\n", message); |
| | 1137 | backtrace_symbols_fd(array, size, fileno(out)); |
| | 1138 | if (size == MAX_BACKTRACE) fputs("[stack truncated to avoid deadlock]\n", out); |
| | 1139 | fputs("-------------------- End of backtrace\n", out); |
| | 1140 | fflush(out); |
| | 1141 | } |
| | 1142 | }; |
| | 1143 | |
| | 1144 | class BackTraceInfo *GBK_get_backtrace(size_t skipFramesAtBottom) { |
| | 1145 | return new BackTraceInfo(skipFramesAtBottom); |
| | 1146 | } |
| | 1147 | void GBK_dump_former_backtrace(class BackTraceInfo *trace, FILE *out, GB_CSTR message) { |
| | 1148 | trace->dump(out, message); |
| | 1149 | } |
| | 1150 | void GBK_free_backtrace(class BackTraceInfo *trace) { |
| | 1151 | delete trace; |
| | 1152 | } |
| | 1153 | |
| | 1154 | void GBK_dump_backtrace(FILE *out, GB_CSTR message) { |
| | 1155 | BackTraceInfo trace(0); |
| | 1156 | trace.dump(out ? out : stderr, message); |