Hello,

I'm trying to catch segfaults, after reading lot of ressources online, i came up with this:

```D
import core.stdc.signal: SIGSEGV, SIGFPE, SIGILL, SIGABRT, signal;
import core.stdc.stdlib: free;
import core.stdc.string: strlen;
import core.sys.posix.unistd: STDERR_FILENO, readlink;
import core.sys.posix.signal: SIGUSR1;
import core.sys.posix.stdio: popen, pclose;
import core.sys.linux.execinfo: backtrace, backtrace_symbols;

import core.stdc.stdlib;
import core.stdc.stdio;
import core.stdc.string;


extern (C) void main()
{
    signal(SIGSEGV, &handler);
    signal(SIGUSR1, &handler);

    test();
}

void test()
{
    int* a;

    *a = 1;
}

extern (C) void handler(int sig) nothrow @nogc
{
    enum STACK_HIST = 6;
    void*[STACK_HIST] array;
    int size;

    string signal_string;
    switch (sig)
    {
    case SIGSEGV:
        signal_string = "SIGSEGV";
        break;
    case SIGFPE:
        signal_string = "SIGFPE";
        break;
    case SIGILL:
        signal_string = "SIGILL";
        break;
    case SIGABRT:
        signal_string = "SIGABRT";
        break;
    default:
        signal_string = "unknown";
        break;
    }

    import core.stdc.stdio : fprintf, stderr;

fprintf(stderr, "-------------------------------------------------------------------+\r\n"); fprintf(stderr, "Received signal %s (%d)\r\n", signal_string.ptr, sig); fprintf(stderr, "-------------------------------------------------------------------+\r\n");

    // get void*'s for all entries on the stack
    size = backtrace(&array[0], STACK_HIST);
    char** strings = backtrace_symbols(&array[0], size);

    enum BUF_SIZE = 1024;
    char[BUF_SIZE] syscom;
    char[BUF_SIZE] my_exe;
ulong path_size = readlink("/proc/self/exe", &my_exe[0], BUF_SIZE);
    my_exe[path_size] = 0;

    printf("executable: %s\n", &my_exe[0]);
    printf("backtrace: %i\n", size);

    for (auto i = 2; i < size; ++i)
    {
        auto line = strings[i];
        auto len = strlen(line);
        bool insideParenthesis;
        int startParenthesis;
        int endParenthesis;
        bool insideShit;
        int startShit;
        int endShit;
        for(int j = 0; j < len; j++)
        {
            // ()
            if (!insideParenthesis && line[j] == '(')
            {
                insideParenthesis = true;
                startParenthesis = j+1;
            }
            else if (insideParenthesis && line[j] == ')')
            {
                insideParenthesis = false;
                endParenthesis = j;
            }
            // []
            if (!insideShit && line[j] == '[')
            {
                insideShit = true;
                startShit = j+1;
            }
            else if (insideShit && line[j] == ']')
            {
                insideShit = false;
                endShit = j;
            }
        }

// printf("%.*s :: %.*s\n", (endParenthesis - startParenthesis), &line[startParenthesis], (endShit - startShit), &line[startShit]);
        // char[256] addr = 0;
// memcpy(addr.ptr, &line[startShit], (endShit-startShit));

sprintf(&syscom[0], "addr2line %s -e %s | ddemangle", array[i], &my_exe[0]);
        system(&syscom[0]);

        printf("  >%s\n", strings[i]);


//sprintf(&syscom[0], "addr2line %p -f -e %s | ddemangle", strings[i], &my_exe[0]);
        //system(&syscom[0]);
    }

    exit(-1);
}

```


The problem is when i compile with DMD i get:

```
??:0
```

When i compile it with GDC i get proper file + line


What does GDC do different than DMD?

Is there a way to get the same result as GDC with DMD?

Thanks

Reply via email to