| 93 | } |
| 94 | |
| 95 | fl::string ScopedTrace::dump() FL_NOEXCEPT { |
| 96 | auto& storage = getTraceStorage(); |
| 97 | fl::string result = "Stack trace (depth "; |
| 98 | |
| 99 | char depth_str[32]; |
| 100 | fl::sprintf(depth_str, "%zu", (size_t)storage.stackDepth); |
| 101 | result += depth_str; |
| 102 | result += "):\n"; |
| 103 | |
| 104 | if (storage.callStack.empty()) { |
| 105 | result += " <empty>\n"; |
| 106 | return result; |
| 107 | } |
| 108 | |
| 109 | // Show overflow warning if depth exceeds capacity |
| 110 | if (storage.stackDepth > FL_STACK_TRACE_MAX_DEPTH) { |
| 111 | result += " <WARNING: Stack overflow - showing last "; |
| 112 | char max_str[32]; |
| 113 | fl::sprintf(max_str, "%d", FL_STACK_TRACE_MAX_DEPTH); |
| 114 | result += max_str; |
| 115 | result += " of "; |
| 116 | result += depth_str; |
| 117 | result += " entries>\n"; |
| 118 | } |
| 119 | |
| 120 | // Dump all stored entries in format: functionName(lineNo) |
| 121 | for (fl::size i = 0; i < storage.callStack.size(); ++i) { |
| 122 | const auto& entry = storage.callStack[i]; |
| 123 | char line_buf[256]; |
| 124 | if (entry.line > 0) { |
| 125 | fl::sprintf(line_buf, " [%zu] %s(%d)\n", (size_t)i, entry.function, entry.line); |
| 126 | } else { |
| 127 | fl::sprintf(line_buf, " [%zu] %s\n", (size_t)i, entry.function); |
| 128 | } |
| 129 | result += line_buf; |
| 130 | } |
| 131 | |
| 132 | return result; |
| 133 | } |
| 134 | |
| 135 | void ScopedTrace::dump(fl::vector<TracePoint>* out) FL_NOEXCEPT { |
| 136 | if (!out) { |