Hi, list.
Over at vlang/v, we use #line directives to map line
numbers in the generated C to the respective locations in the
original code in backtraces, etc.
The code we generate looks something like this:
#line 29
"../../../../../../home/spaceface/git/v/v/vlib/builtin/builtin.c.v"
void
panic_debug(void) {
#line
53
"../../../../../../home/spaceface/git/v/v/vlib/builtin/builtin.c.v"
tcc_backtrace("Backtrace");
}
#line 1
"../../../../../../home/spaceface/git/v/v/test.v"
void
main__inner(void) {
#line
1 "../../../../../../home/spaceface/git/v/v/test.v"
panic_debug();
}
#line 2
"../../../../../../home/spaceface/git/v/v/test.v"
void
main__outer(void) {
#line
2 "../../../../../../home/spaceface/git/v/v/test.v"
main__inner();
}
#line 3
"../../../../../../home/spaceface/git/v/v/test.v"
int
main(void) {
#line
3 "../../../../../../home/spaceface/git/v/v/test.v"
main__outer();
return 0;
}
Other C compilers collapse the `../`s in the #line
paths, but TCC does not, so currently the backtraces it produces
look like this:
/tmp/v_1000/../../../../../../home/spaceface/git/v/v/vlib/builtin/builtin.c.v:53:
at panic_debug: Backtrace
/tmp/v_1000/../../../../../../home/spaceface/git/v/v/test.v:1:
by main__inner
/tmp/v_1000/../../../../../../home/spaceface/git/v/v/test.v:2:
by main__outer
/tmp/v_1000/../../../../../../home/spaceface/git/v/v/test.v:3:
by main
I decided to try and fix this, and came up with the
following patch:
diff
--git a/tccpp.c b/tccpp.c
index
2ff5d5e..47ac859 100644
---
a/tccpp.c
+++
b/tccpp.c
@@
-1797,7 +1797,7 @@ ST_FUNC void preprocess(int is_bof)
{
TCCState *s1 = tcc_state;
int
i, c, n, saved_parse_flags;
- char
buf[1024], *q;
+ char
buf[1024], *q, *last_slash;
Sym
*s;
saved_parse_flags = parse_flags;
@@
-2042,6 +2042,22 @@ include_done:
pstrcpy(buf, sizeof buf, file->true_filename);
*tcc_basename(buf) = 0;
pstrcat(buf, sizeof buf, (char *)tokc.str.data);
+
// collapse relative `../`s
+
while ((q = strstr(buf, "../")) != NULL) {
+
(q == buf) ? (*q = '\0') : (*(q-1) = '\0');
+
last_slash = strrchr(buf, '/');
+
if (last_slash == NULL) {
+
memmove(buf, q + 2, strlen(q + 2) + 1);
+
} else {
+
memmove(last_slash + 1, q + 2, strlen(q + 2) +
1);
+
}
+
}
+
// collapse `foo//bar` to `foo/bar`
+
c = strlen(buf);
+
while((q = strstr(buf, "//")) != NULL) {
+
memmove(q, q+1, c - (q - buf));
+
c--;
+
}
tcc_debug_putfile(s1, buf);
} else if (parse_flags & PARSE_FLAG_ASM_FILE)
break;
With it, that same backtrace now looks like this:
/home/spaceface/git/v/v/vlib/builtin/builtin.c.v:53: at
panic_debug: Backtrace
/home/spaceface/git/v/v/test.v:1: by main__inner
/home/spaceface/git/v/v/test.v:2: by main__outer
/home/spaceface/git/v/v/test.v:3: by main
Would you be willing to merge something this?
We’ve also added a function that returns the
backtrace as a char**
rather than printing it out, and modified the backtrace
functions to replace e.g. main__foo with main.foo in
symbol names, but I presume these patches won’t be as useful
outside of V.
Raul
_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel