Any ways to get addr2line working with DMD? works fine with GDC

ryuukk_ ryuukk.dev at gmail.com
Thu Mar 16 22:07:04 UTC 2023


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


More information about the Digitalmars-d-learn mailing list