本文介绍了无法在地址功能参数传递问题上访问内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 在我的 main()函数中,我有一个局部变量: datastruct pdw_frame; 我用数据填充它并将它传递给两个函数,它们在 main(),例如 datastruct_to_pdw(& pdw_frame,0,& pdw) ; / * ok * / hash_streams = get_streams(& pdw_frame,& result_frame); / *不行* / 同时进入 datastruct_to_pdw() with gdb 我可以看看第一个函数参数没有问题,例如 返回结构的描述 然而,当进入第二个函数并试图做同样的事情时,我得到: 无法访问地址为0xcccccccd的内存 我无法理解为什么我可以从第1位函数参数,但不是第二个 point中的函数包含在我从main()调用的共享库中。这些函数是在不同的文件中定义的,它们的原型位于不同的头文件中。我已经检查过我的 Makefile ,以确保它们全部建成。检查共享库确认两个函数都存在,例如 nm mylib.so 000251a1 T datastruct_to_pdw 00027348 T get_streams 函数如何调用工作而不是其他函数? / b> 函数原型是: pre $ void datastruct_to_pdw(const datastruct * const pulse_data ,size_t i,Pdw * pdw); stream_t * get_streams(datastruct * pdw_frame,resultstruct * result_frame); 我的共享库的调试版本具有以下编译器标志集: DEBUG_CFLAGS:= -fPIC -g -Wall -DDEBUG = 1 使用这些设置时,从Makefile构建时不会收到任何警告 单步执行代码,检查pdw_frame的值, : 在调用datastruct_to_pdw()之前的main()中: (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 步入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 = 0x8057c 70} 从main()返回datastruct_to_pdw(): (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 步入get_streams(): $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ 10 =(datastruct *)0x40c24f80(为什么这与main()中的& pdw_frame不同?) (gdb)p * pdw_frame 无法访问地址0x40c24f80处的内存(为什么? ) 从get_streams()返回到main(): (gdb)p pdw_frame $ 13 = {ptoa = 0x8051e98,prf = 0x804e008,ppw = 0x804ff50,pamp = 0x8053de0,pbr = 0x8055d28,n = 1000 ,真实= 0x8057c70} (gdb)p& pdw_frame $ 14 =(datastruct *)0xbfffe9e0 注意我想也许是事实在我为局部变量 pdw_frame (类型 datastruct )使用相同的名称时,在 datastruct * get_streams()函数中的$ c> main() $ c>)可能会导致一个问题,所以我尝试将 get_streams()的第一个参数重命名为完全不同的内容,但这对错误没有任何影响 通过valgrind运行程序似乎没有提出任何问题(我认为),例如: valgrind --tool = memcheck --leak-check = full --show-reachable = yes< my_program> == 12371 == == 12371 == HEAP SUMMARY: == 12371 ==在退出时使用:1,880字节在1块 == 12371 ==总堆使用率:35,810个分配,35,809个释放,102,124,128个字节分配 == 12371 == == 12371 == 1个块中的1,880个字节仍然可以在1 $ b的损失记录1中访问$ b == 12371 == at 0x402A2FB:calloc(在/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) == 12371 == by 0x41D048B:monstartup(gmon.c:134) == 12371 == by 0x8049F60:__gmon_start__(在/ home / ben / projects / glamdring / RESTRICTED / core_harness / build / linux / release / GlamdringHarness_rel) == 12371 == by 0x40D45A9:??? (在/lib/i386-linux-gnu/librt-2.17.so) == 12371 == == 12371 == LEAK概要: == 12371 ==绝对丢失: 0字节0块 == 12371 ==间接丢失:0字节0块 == 12371 ==可能丢失:0块0字节 == 12371 ==仍可到达:1个块中的1,880个字节 == 12371 ==被抑制:0个块中的0个字节 == 12371 == == 12371 ==对于检测到并抑制的错误的计数,重新运行:-v == 12371 ==错误摘要:0错误来自0个上下文(被抑制:0从0)分析定时器过期 我还应该补充一点,当我运行我的单元测试套件时,它编译并链接到单个可执行文件,而不是通过共享库访问函数,所以我没有任何问题 刚添加了一个新函数: void dummy_utility(int n) { printf(Hello World!); return; 从> main()像这样: dummy_utility(42); 使用 gdb 进入它并得到: (gdb)pn $ 4 = 1086476160 它必须在拾取一个旧的库,但是当我搜索共享库时,例如 $ locate libProgram_dbg.so (_dbg版本有调试符号并且没有优化) 我在 build / linux / debug dir就像我期望的那样,当我查看共享库的时间戳时,它显示它刚刚被重建!我真的很困惑。 以下是gdb中运行info寄存器的输出: 至 dummy_utility(): (gdb)信息寄存器 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 步入 dummy_utility(): $ b $ pre $ g $ c $(gdb)信息寄存器 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 GT; eflags 0x296 [PF AF SF IF] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 单步执行 dummy_utility()试图从 main(), gdb 返回告诉我: 找不到当前函数的边界 运行 ldd ProgramHarness_dbg 给出: 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) 共享lib是预期的。解决方案 对于运行 gdb 在emacs / linux下 如果您最近升级到emacs 24了解 gdb 已损坏,那么您现在需要使用 gud-gdb 获取更多详情: Emacs gdb没有运行 gud-gdb emacs 24无法正常工作 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_framereturns a description of the structhowever, when stepping into the 2nd function and trying to do the same, I get:Cannot access memory at address 0xcccccccdI cannot understand why I can dereference the pointer from the 1st function parameter but not the 2ndThe 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.so000251a1 T datastruct_to_pdw00027348 T get_streamsHow 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=1with these settings I get no warnings when building from the MakefileStepping 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 *) 0xbfffe9e0stepping 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 *) 0xbfffe9e0stepping into get_streams():(gdb) p pdw_frame$10 = (datastruct *) 0x40c24f80 (why is this different to &pdw_frame in main()?)(gdb) p *pdw_frameCannot 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 *) 0xbfffe9e0Note 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 errorrunning 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 expiredI 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 = 1086476160it 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 registerseax 0xc 12ecx 0x0 0edx 0xbfffe454 -1073748908ebx 0x11 17esp 0xbfffe8c0 0xbfffe8c0ebp 0xbfffec78 0xbfffec78esi 0x8053dd0 134561232edi 0x1f38 7992eip 0x8049d82 0x8049d82 <main+3884>eflags 0x286 [ PF SF IF ]cs 0x73 115ss 0x7b 123ds 0x7b 123es 0x7b 123fs 0x0 0gs 0x33 51on stepping into dummy_utility():(gdb) info registerseax 0xbfffea98 -1073747304ecx 0x0 0edx 0x2a 42ebx 0xb7fd9000 -1208119296esp 0xbfffe8b8 0xbfffe8b8ebp 0xbfffe8d0 0xbfffe8d0esi 0x8053dd0 134561232edi 0x1f38 7992eip 0xb7fc22cc 0xb7fc22cc <dummy_utility+18>eflags 0x296 [ PF AF SF IF ]cs 0x73 115ss 0x7b 123ds 0x7b 123es 0x7b 123fs 0x0 0gs 0x33 51stepping through dummy_utility() in an attempt to return from main(), gdb tells me:Cannot find bounds of current functionrunning 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.. 解决方案 For anybody experiencing weird behaviour when running gdb under emacs/linuxIf you recently upgraded to emacs 24 understand that gdb is broken and that you need to now use gud-gdbfor more details follow:Emacs gdb not runninggud-gdb emacs 24 not working 这篇关于无法在地址功能参数传递问题上访问内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-20 17:33