tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] [patch] adding path resolution to #line directives


From: Raul Hernandez
Subject: [Tinycc-devel] [patch] adding path resolution to #line directives
Date: Thu, 5 May 2022 10:50:39 +0200

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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]