Any ways to get addr2line working with DMD? works fine with GDC
ryuukk_
ryuukk.dev at gmail.com
Tue Mar 21 22:27:58 UTC 2023
I found what was the issue!! https://stackoverflow.com/a/63856113
> The 0x55XXXXXXXXXX address you got is most likely the memory
> address of the function after the EXE is loaded from disk.
> addr2line only recognizes VMA addresses like the ones that you
> got from disassembling with objdump.
It now works, using the code that was provided in that answer!
Now i can catch segfaults and get a precise location in my code
without fuss!
Hopefully it is as easy with windows..
```D
extern (C) void main()
{
signal(SIGSEGV, &handler);
signal(SIGUSR1, &handler);
test();
}
void test()
{
int* a;
*a = 1;
}
```
```
-------------------------------------------------------------------+
Received signal SIGSEGV (11)
-------------------------------------------------------------------+
executable: /mnt/c/tmp/backtrace/app
backtrace: 6
/mnt/c/tmp/backtrace/app.d:25 void app.test()+0xe
/mnt/c/tmp/backtrace/app.d:19 main+0x2b
??:0 __libc_start_main+0xf3
??:? _start+0x2e
```
Here is the fullcode so far (needs cleanup and, selective imports
to keep track of what's really neded):
```D
import core.stdc.signal : SIGSEGV, SIGFPE, SIGILL, SIGABRT,
signal;
import core.stdc.stdlib : free, exit;
import core.stdc.string : strlen, memcpy;
import core.stdc.stdio : fprintf, stderr, printf, sprintf, fgets,
fclose, FILE;
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.sys.linux.dlfcn : dladdr, dladdr1, Dl_info,
RTLD_DL_LINKMAP;
import core.sys.linux.link : link_map;
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 MAX_DEPTH = 6;
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;
}
fprintf(stderr,
"-------------------------------------------------------------------+\r\n");
fprintf(stderr, "Received signal %s (%d)\r\n",
signal_string.ptr, sig);
fprintf(stderr,
"-------------------------------------------------------------------+\r\n");
void*[MAX_DEPTH] trace;
int stack_depth = backtrace(&trace[0], MAX_DEPTH);
char** strings = backtrace_symbols(&trace[0], stack_depth);
enum BUF_SIZE = 1024;
char[BUF_SIZE] syscom = 0;
char[BUF_SIZE] my_exe = 0;
char[BUF_SIZE] output = 0;
readlink("/proc/self/exe", &my_exe[0], BUF_SIZE);
printf("executable: %s\n", &my_exe[0]);
printf("backtrace: %i\n", stack_depth);
for (auto i = 2; i < stack_depth; ++i)
{
auto line = strings[i];
auto len = strlen(line);
bool insideParenthesis;
int startParenthesis;
int endParenthesis;
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;
}
}
auto addr = convert_to_vma(cast(size_t) trace[i]);
FILE* fp;
auto locLen = sprintf(&syscom[0], "addr2line -e %s %p |
ddemangle", &my_exe[0], addr);
fp = popen(&syscom[0], "r");
auto loc = fgets(&output[0], output.length, fp);
fclose(fp);
// printf("loc: %s\n", loc);
auto getLen = strlen(output.ptr);
char[256] func = 0;
memcpy(func.ptr, &line[startParenthesis], (endParenthesis
- startParenthesis));
sprintf(&syscom[0], "echo '%s' | ddemangle", func.ptr);
fp = popen(&syscom[0], "r");
output[getLen - 1] = ' '; // strip new line
auto locD = fgets(&output[getLen],
cast(int)(output.length - getLen), fp);
fclose(fp);
printf("%s", output.ptr);
}
exit(-1);
}
size_t convert_to_vma(size_t addr) nothrow @nogc
{
Dl_info info;
link_map* link_map;
dladdr1(cast(void*) addr, &info, cast(void**)&link_map,
RTLD_DL_LINKMAP);
return addr - link_map.l_addr;
}
```
More information about the Digitalmars-d-learn
mailing list