Cannot access Memory at address function parameter passing issue

时光总嘲笑我的痴心妄想 提交于 2019-12-24 17:14:23

问题


In my main() function I have a local variable:

datastruct pdw_frame;

I fill it with data and pass it to two functions that are on adjacent lines in main(), e.g.

datastruct_to_pdw(&pdw_frame, 0, &pdw); /* ok */
hash_streams = get_streams(&pdw_frame, &result_frame); /* not ok */

whilst stepping into datastruct_to_pdw() with gdb I can look at the 1st function parameter no problem, e.g.

(gdb) p *pdw_frame

returns a description of the struct

however, when stepping into the 2nd function and trying to do the same, I get:

Cannot access memory at address 0xcccccccd

I cannot understand why I can dereference the pointer from the 1st function parameter but not the 2nd

The functions in point are contained in a shared library that I call from main(). The functions are defined in different files and their prototypes are in different header files. I have checked my Makefile to ensure they are all getting built. Inspection of the shared lib confirms that both functions are present, e.g.

nm mylib.so

000251a1 T datastruct_to_pdw
00027348 T get_streams

How can one function call work and not the other?

Function prototypes are:

void datastruct_to_pdw(const datastruct *const pulse_data, size_t i, Pdw *pdw);
stream_t* get_streams(datastruct *pdw_frame, resultstruct *result_frame);

The debug version of my shared library has the following compiler flags set:

DEBUG_CFLAGS := -fPIC -g -Wall -DDEBUG=1

with these settings I get no warnings when building from the Makefile

Stepping through the code, checking the value of pdw_frame as I go gives:

In main() prior to call to datastruct_to_pdw():

(gdb) p pdw_frame
$2 = {ptoa = 0x8051e98, prf = 0x804e008, ppw = 0x804ff50, pamp = 0x8053de0, pbr = 0x8055d28, n = 1000, truth = 0x8057c70}

(gdb) p &pdw_frame
$5 = (datastruct *) 0xbfffe9e0

stepping into datastruct_to_pdw():

(gdb) p pulse_data
$4 = (const datastruct * const) 0xbfffe9e0

(gdb) p *pulse_data
$3 = {ptoa = 0x8051e98, prf = 0x804e008, ppw = 0x804ff50, pamp = 0x8053de0, pbr = 0x8055d28, n = 1000, truth = 0x8057c70}

return from datastruct_to_pdw() back in main():

(gdb) p pdw_frame
$9 = {ptoa = 0x8051e98, prf = 0x804e008, ppw = 0x804ff50, pamp = 0x8053de0, pbr = 0x8055d28, n = 1000, truth = 0x8057c70}

(gdb) p &pdw_frame
$8 = (datastruct *) 0xbfffe9e0

stepping into get_streams():

(gdb) p pdw_frame
$10 = (datastruct *) 0x40c24f80 (why is this different to &pdw_frame in main()?)

(gdb) p *pdw_frame
Cannot access memory at address 0x40c24f80 (why??)

return from get_streams() back in main():

(gdb) p pdw_frame
$13 = {ptoa = 0x8051e98, prf = 0x804e008, ppw = 0x804ff50, pamp = 0x8053de0, pbr = 0x8055d28, n = 1000, truth = 0x8057c70}

(gdb) p &pdw_frame
$14 = (datastruct *) 0xbfffe9e0

Note I thought perhaps the fact that I was using the same name for both the local variable, pdw_frame (of type datastruct), in main() and parameter name in the get_streams() function (of type datastruct*) may be causing a problem so I tried renaming the 1st parameter of get_streams() to something completely different but this made no difference to the error

running the program through valgrind doesn't seem to suggest any problems (I think), e.g.:

valgrind --tool=memcheck --leak-check=full --show-reachable=yes <my_program>

==12371== 
==12371== HEAP SUMMARY:
==12371==     in use at exit: 1,880 bytes in 1 blocks
==12371==   total heap usage: 35,810 allocs, 35,809 frees, 102,124,128 bytes allocated
==12371== 
==12371== 1,880 bytes in 1 blocks are still reachable in loss record 1 of 1
==12371==    at 0x402A2FB: calloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==12371==    by 0x41D048B: monstartup (gmon.c:134)
==12371==    by 0x8049F60: __gmon_start__ (in /home/ben/projects/glamdring/RESTRICTED/core_harness/build/linux/release/GlamdringHarness_rel)
==12371==    by 0x40D45A9: ??? (in /lib/i386-linux-gnu/librt-2.17.so)
==12371== 
==12371== LEAK SUMMARY:
==12371==    definitely lost: 0 bytes in 0 blocks
==12371==    indirectly lost: 0 bytes in 0 blocks
==12371==      possibly lost: 0 bytes in 0 blocks
==12371==    still reachable: 1,880 bytes in 1 blocks
==12371==         suppressed: 0 bytes in 0 blocks
==12371== 
==12371== For counts of detected and suppressed errors, rerun with: -v
==12371== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Profiling timer expired

I should also add that when i run my unit-test suite which compiles and links to a single executable rather than accessing the functions through a shared library I don't have any problems of this kind.

Just added a new function:

void dummy_utility(int n)
{
    printf("Hello World!");
    return;
}

called it from main() like this:

dummy_utility(42);    

stepped into it using gdb and got:

(gdb) p n
$4 = 1086476160

it must be picking up an old lib but when i search for the shared lib, e.g.

$ locate libProgram_dbg.so (_dbg version has debugging symbols and no optimisation)

I get a single file in my build/linux/debug dir which is as i would expect, when I look at the timestamp of the shared lib there it shows it has just been rebuilt! I am really confused..

Here is the output from running info registers in gdb:

just before call to dummy_utility():

(gdb) info registers
eax            0xc  12
ecx            0x0  0
edx            0xbfffe454   -1073748908
ebx            0x11 17
esp            0xbfffe8c0   0xbfffe8c0
ebp            0xbfffec78   0xbfffec78
esi            0x8053dd0    134561232
edi            0x1f38   7992
eip            0x8049d82    0x8049d82 <main+3884>
eflags         0x286    [ PF SF IF ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0  0
gs             0x33 51

on stepping into dummy_utility():

(gdb) info registers
eax            0xbfffea98   -1073747304
ecx            0x0  0
edx            0x2a 42
ebx            0xb7fd9000   -1208119296
esp            0xbfffe8b8   0xbfffe8b8
ebp            0xbfffe8d0   0xbfffe8d0
esi            0x8053dd0    134561232
edi            0x1f38   7992
eip            0xb7fc22cc   0xb7fc22cc <dummy_utility+18>
eflags         0x296    [ PF AF SF IF ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0  0
gs             0x33 51

stepping through dummy_utility() in an attempt to return from main(), gdb tells me:

Cannot find bounds of current function

running ldd ProgramHarness_dbg gives:

linux-gate.so.1 =>  (0xb76e7000)
libGlamdring_dbg.so => /home/ben/projects/core/build/linux/debug/libProgram_dbg.so (0xb76a4000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xb7646000)
librt.so.1 => /lib/i386-linux-gnu/librt.so.1 (0xb763c000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7489000)
/lib/ld-linux.so.2 (0xb76e8000)
libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 (0xb746e000)

The location of the shared lib is as expected..


回答1:


For anybody experiencing weird behaviour when running gdb under emacs/linux

If you recently upgraded to emacs 24 understand that gdb is broken and that you need to now use gud-gdb

for more details follow:

Emacs gdb not running

gud-gdb emacs 24 not working




回答2:


I ran into a similar problem on mac. I installed gdb-apple, and was then able to set breakpoints / inspect variables in a shared library that was loaded inside of python.



来源:https://stackoverflow.com/questions/20633968/cannot-access-memory-at-address-function-parameter-passing-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!