![]() |
Reverse memory lookup
In C/C++, it's trivial to map from a variable name (either scalar or pointer+offset) to the memory location. Is there a way (or tool) allowing one to find which variable / function / allocated-memory-block a given address maps to? I am trying to localize a valgrind (specifically the DRD thread-analysis tool) error, and valgrind is only giving the address in question, no associated name:
[i]Conflicting store by thread 3 at 0x10041fc00 size 4[/i] |
[QUOTE=ewmayer;315747]In C/C++, it's trivial to map from a variable name (either scalar or pointer+offset) to the memory location. Is there a way (or tool) allowing one to find which variable / function / allocated-memory-block a given address maps to? I am trying to localize a valgrind (specifically the DRD thread-analysis tool) error, and valgrind is only giving the address in question, no associated name:
[i]Conflicting store by thread 3 at 0x10041fc00 size 4[/i][/QUOTE] Did you compile with -g and no optimizations? |
[QUOTE=rogue;315749]Did you compile with -g and no optimizations?[/QUOTE]
Yes - I used [i]-Wall -g3 -ggdb[/i] . |
[QUOTE=ewmayer;315747]In C/C++, it's trivial to map from a variable name (either scalar or pointer+offset) to the memory location. Is there a way (or tool) allowing one to find which variable / function / allocated-memory-block a given address maps to? I am trying to localize a valgrind (specifically the DRD thread-analysis tool) error, and valgrind is only giving the address in question, no associated name:
[I]Conflicting store by thread 3 at 0x10041fc00 size 4[/I][/QUOTE] For what's it's worth, I use the nm command (with -v option to sort by value) for variables and functions. Of course that won't help for dynamically allocated memory. |
[QUOTE=ldesnogu;315779]For what's it's worth, I use the nm command (with -v option to sort by value) for variables and functions. Of course that won't help for dynamically allocated memory.[/QUOTE]
Thanks, Laurent - that is worth quite a lot, as it's just what I needed: I had already added debug-printing of dynamically allocated memory blocks, and saw that the addresses flagged by valgrind/DRD were falling outside those address ranges, so I figured it was local storage of some kind. With the binutils "nm -v" dump, I see immediately that I had not been sufficiently careful to get rid of all remaining static variables (except for those of the read-only variety) from my || implementation of the code in question. Fixing that gets rid of most of the "Conflicting store" error messages ... ah, looks like I also need to add a bit of mutex magic to some routines, to make sure the local-array storage (which I use for SSE register-data constants and register spill management here) gets initialized by the master thread before any of the other threads try to read it. DRD looks like it's going to be a very handy tool to have around. |
OK, another multithreaded-code-debug issue: I am getting a divide-by-zero exception in a newly-put-together pthreaded worker-function routine. My source code has no explicit DIVs, so it appears the DIV is resulting from thread-management code. Valgrind DRD indicates the following may be the cause:
[I] ==1595== Use of uninitialised value of size 8 ==1595== at 0x10017D633: cy_process_chunk (in ./Mlucas_sse2) ==1595== by 0x10025A1C2: worker_thr_routine (in ./Mlucas_sse2) ==1595== by 0x100373FD5: _pthread_start (in /usr/lib/libSystem.B.dylib) ==1595== by 0x100373E88: thread_start (in /usr/lib/libSystem.B.dylib) [/I] In trying to localize the error, I first looked for the first of the above addresses in the output of "nm -v" run on the binary - no match. Then I re-ran under gdb (note the binary is compiled unoptimized with -g), which catches the exception, and reveals the DIV (boldfaced) within a disassembly dump: [I] [CODE](gdb) disass Dump of assembler code for function worker_thr_routine: 0x0000000100259fe0 <worker_thr_routine+0>: push %rbp 0x0000000100259fe1 <worker_thr_routine+1>: mov %rsp,%rbp 0x0000000100259fe4 <worker_thr_routine+4>: push %r15 0x0000000100259fe6 <worker_thr_routine+6>: push %r14 0x0000000100259fe8 <worker_thr_routine+8>: push %r13 0x0000000100259fea <worker_thr_routine+10>: push %r12 0x0000000100259fec <worker_thr_routine+12>: push %rbx 0x0000000100259fed <worker_thr_routine+13>: sub $0x58,%rsp 0x0000000100259ff1 <worker_thr_routine+17>: mov %rdi,-0x58(%rbp) 0x0000000100259ff5 <worker_thr_routine+21>: mov (%rdi),%r15d 0x0000000100259ff8 <worker_thr_routine+24>: mov 0x8(%rdi),%rbx 0x0000000100259ffc <worker_thr_routine+28>: callq 0x10029f3fc <dyld_stub_mach_thread_self> 0x000000010025a001 <worker_thr_routine+33>: mov %eax,%r12d 0x000000010025a004 <worker_thr_routine+36>: movl $0x0,-0x40(%rbp) 0x000000010025a00b <worker_thr_routine+43>: lea -0x40(%rbp),%rdx 0x000000010025a00f <worker_thr_routine+47>: mov $0x1,%ecx 0x000000010025a014 <worker_thr_routine+52>: mov $0x1,%esi 0x000000010025a019 <worker_thr_routine+57>: mov %eax,%edi 0x000000010025a01b <worker_thr_routine+59>: callq 0x10029f4f2 <dyld_stub_thread_policy_set> 0x000000010025a020 <worker_thr_routine+64>: test %eax,%eax 0x000000010025a022 <worker_thr_routine+66>: jne 0x10025a445 <worker_thr_routine+1125> 0x000000010025a028 <worker_thr_routine+72>: movzwl 0x4a(%rbx),%eax 0x000000010025a02c <worker_thr_routine+76>: mov %r15d,%edx 0x000000010025a02f <worker_thr_routine+79>: mov %eax,%ecx 0x000000010025a031 <worker_thr_routine+81>: mov %r15d,%eax 0x000000010025a034 <worker_thr_routine+84>: sar $0x1f,%edx 0x000000010025a037 <worker_thr_routine+87>: idiv %ecx 0x000000010025a039 <worker_thr_routine+89>: mov %edx,-0x50(%rbp) 0x000000010025a03c <worker_thr_routine+92>: lea -0x50(%rbp),%rdx 0x000000010025a040 <worker_thr_routine+96>: mov $0x1,%ecx 0x000000010025a045 <worker_thr_routine+101>: mov $0x1,%esi ...[/CODE][/I] I need to figure out which variable or array element is the argument to the IDIV which is causing the problem. Suggestions welcome. |
Found the problem: By playing with various things - adding some sanity spot-checks of key parts of thread-local-memory, testing things with various #threads starting with the "this had better work" value of 1, etc, I determined that some of the bookkeeping I added for the SSE2 register-spill/fill portion of the thread-local memory store was getting corrupted ... apparently the div-by-zero in the pthread-lib thread management code was a side effect of the resulting memory corruption.
Thanks to jasonp for some comparative threadpool-code checking - that didn't tell e what the problem was, but gave some clues as to what it likely was not. |
| All times are UTC. The time now is 02:22. |
Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.