20 #define COLOUR_ADDR eColourRed
21 #define COLOUR_SYMBOL eColourBlue
22 #define COLOUR_INDEX eColourCyan
23 #define COLOUR_RECURSE eColourYellow
24 #define COLOUR_LINE eColourWhite
26 static const char *
const kUnknownSymbol =
"<unknown>";
104 #define IS_COLLAPSED_RANGE(it) ((it).repeat != 0)
126 static unsigned match_sequence(
133 size_t seq_len = scan_start - seq_start;
140 for (
size_t i = scan_start; i < ent_len; i++)
163 collapsed->
first = (unsigned)(scan_start);
164 collapsed->
last = (unsigned)(scan_start + seq_len - 1);
165 collapsed->
repeat = (unsigned)(count);
166 return (
unsigned)(count * seq_len);
177 for (
unsigned i = start + 1; i < len; i++)
180 CTASSERTF(frame != NULL,
"entry at %u is NULL", i);
185 unsigned count = match_sequence(frames, i, start, collapsed);
188 if (count != 0)
return count;
199 collapsed->
first = start;
200 collapsed->
last = start;
210 for (
unsigned i = 0; i < len; i++)
213 unsigned count = collapse_frame(frames, i, &collapsed);
215 CTASSERTF(count > 0,
"count of 0 at %u", i);
240 #define PTR_TEXT_LEN (2 + 2 * sizeof(void*))
248 for (
size_t i = range.
first; i <= range.
last; i++)
251 CTASSERTF(entry != NULL,
"entry at %zu is NULL", i);
254 largest =
CT_MAX(width, largest);
276 for (
size_t i = 0; i < len; i++)
279 CTASSERTF(range != NULL,
"entry at %zu is NULL", i);
294 largest =
CT_MAX(width, largest);
304 static const char *get_file_path(
backtrace_t *pass,
const char *file)
327 const char *file = get_file_path(pass, entry->
file);
338 .heading_style = config.header,
339 .zero_indexed_lines = config.
config & eBtZeroIndexedLines,
361 const char *where = fmt_entry_location(pass, entry);
373 static char *fmt_index(
backtrace_t *pass,
size_t index)
386 char *
idx = fmt_index(pass, index);
395 size_t largest = get_longest_symbol(pass->
entries, collapsed);
397 char *
idx = fmt_index(pass, index);
401 for (
size_t i = collapsed.
first; i <= collapsed.
last; i++)
404 CTASSERTF(entry != NULL,
"entry at %zu is NULL", i);
406 char *it = fmt_entry(pass, largest, entry);
416 print_frame_sequence(pass, index, collapsed);
420 const entry_t *entry = get_collapsed_entry(pass, collapsed);
421 print_single_frame(pass, index, entry);
443 .entries = report->
frames,
445 .index_align = align,
447 .arena = options.
arena,
450 const char *source_path =
fmt.project_source_path;
454 if (source_path[len - 1] !=
'/' && source_path[len - 1] !=
'\\')
459 for (
size_t i = 0; i < frame_count; i++)
462 CTASSERTF(frame != NULL,
"collapsed at %zu is NULL", i);
466 if (symbol_align.
count > 0)
468 symbol_align.
count -= 1;
474 size_t remaining = frame_count - i;
475 symbol_align = get_largest_collapsed_symbol(report->
frames, frame, remaining);
480 print_collapsed(&pass, i, *frame);
490 report->
arena = arena;
498 static void read_stacktrace_frame(
bt_address_t frame,
void *user)
508 bt_read(read_stacktrace_frame, report);
#define IS_COLLAPSED_RANGE(it)
STA_DECL char * colour_format(format_context_t context, colour_t idx, const char *fmt,...)
#define STA_DECL
sal2 annotation on function implementations to copy annotations from the declaration
uint_least64_t bt_address_t
an address of a symbol
#define BT_PRI_ADDRESS
format specifier for bt_address_t
CT_BACKTRACE_API bt_resolve_t bt_resolve_symbol(bt_address_t frame, bt_symbol_t *symbol)
resolve a frame to a symbol
bt_resolve_t
how much of a frame was reconstructed
CT_BACKTRACE_API void bt_read(bt_trace_t callback, void *user)
get a backtrace from the current location using a callback
@ eResolveLine
the line number was found
@ eResolveName
the symbol name was found
@ eResolveFile
the file path was found
CT_CONSTFN CT_BASE_API text_t text_make(STA_READS(length) char *text, size_t length)
create a new owning text array text must be a valid string at least length bytes long
CT_NODISCARD CT_PUREFN CT_BASE_API size_t ctu_strlen(const char *str)
get the length of a string not including the null terminator equivalent to strlen but with safety che...
STA_RET_STRING colour_t idx
STA_RET_STRING CT_FORMAT_API char * colour_text(format_context_t context, colour_t idx, const char *text)
add colour to a string
CT_IO_API size_t io_printf(io_t *io, STA_FORMAT_STRING const char *fmt,...)
printf to an io object
#define ARENA_IDENTIFY(ptr, name, parent, arena)
rename and reparent a pointer in a custom allocator
CT_NODISCARD CT_ARENA_API char * arena_strndup(STA_READS(len) const char *str, size_t len, arena_t *arena)
allocate a copy of a string with a maximum length from a custom allocator
#define ARENA_MALLOC(size, name, parent, arena)
allocate memory from a custom allocator
#define CTASSERT(expr)
assert a condition, prints the condition as a message
#define CTASSERTF(expr,...)
assert a condition with a message and optional format arguments
CT_NODISCARD STA_FORMAT_STRING const char * fmt
CT_NODISCARD CT_PUREFN CT_STD_API bool str_startswith(const char *str, const char *prefix)
see if a string starts with a prefix
CT_STD_API void * typevec_push(typevec_t *vec, const void *src)
push a value onto the vector
CT_NODISCARD CT_PUREFN CT_STD_API size_t typevec_len(const typevec_t *vec)
get the length of a vector
CT_NODISCARD CT_PUREFN CT_STD_API void * typevec_data(const typevec_t *vec)
get a pointer to the underlying data
CT_NODISCARD CT_STD_API typevec_t * typevec_new(size_t width, size_t len, arena_t *arena)
create a new typed vector on the heap
CT_NODISCARD CT_PUREFN CT_STD_API void * typevec_offset(const typevec_t *vec, size_t index)
get a pointer to the value at the given index
STA_DECL char * str_format(arena_t *arena, const char *fmt,...)
size_t index_align
the alignment of the frame index numbers
format_context_t format_context
format context
fmt_backtrace_t options
the user provided options
size_t symbol_align
the current alignment of the symbol names
size_t source_root_len
the length of the source root
a backtrace report context
typevec_t * frames
all entries
arena_t * arena
memory pool
text_t name
a buffer to hold the name
text_t path
a buffer to hold the path to the file
source_line_t line
the line number
a single possibly collapsed frame this is a span covering (first, last) * repeat frames
unsigned repeat
how many times this sequence repeats
unsigned first
index of the first frame in this sequence
unsigned last
index of the last frame in this sequence
char * symbol
the symbol name
bt_resolve_t info
what symbol info has been resolved by the backend?
size_t line
the line number
bt_address_t address
the address of the frame
printing options for a stacktrace
print_options_t options
basic print options
const char * project_source_path
path to the root of the projects source directory if this is set then paths that are under this direc...
fmt_backtrace_options_t config
configuration flags
arena_t * arena
temporary arena
a formatting context when using colours
size_t length
the number of characters in the text
A vector with a fixed type size.
a location inside a scanner locations are inclusive and 0-based
ctu_line_t first_line
the first line of the location