2013-12-17 23 views
1

在我main()功能我有一個局部變量:不能在地址功能參數訪問存儲器傳遞的問題

datastruct pdw_frame; 

我寫些數據,並把它傳遞給兩個函數在鄰近線main(),例如

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

而步入datastruct_to_pdw()gdb我可以看看第一個功能參數沒有問題,例如

(gdb) p *pdw_frame 

返回結構的描述

但是,步入第二個功能時,試圖做同樣的,我得到:

Cannot access memory at address 0xcccccccd 

我不明白爲什麼我可以取消引用來自第一個函數參數但不是第二個指針

point中的函數包含在我從main()調用的共享庫中。這些函數是在不同的文件中定義的,它們的原型位於不同的頭文件中。我已經檢查了我的Makefile,以確保它們全部建成。檢查共享庫確認兩個功能都存在,例如,

nm mylib.so 

000251a1 T datastruct_to_pdw 
00027348 T get_streams 

一個函數如何能夠調用工作而不是另一個?

函數原型:

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的值,因爲我去了:

在main()之前調用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 

步入datastruct_to_pdw():從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} 

回報()回在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 

步入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??) 

從get_streams()返回回在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 

注意我想也許是我用的是同名字的局部變量,pdw_frame(的datastruct型),其實在main()和在(的datastruct*型)get_streams()函數參數的名稱可能會引起問題,所以我嘗試的get_streams()的第一個參數重命名爲完全不同的東西,但是本作的錯誤

通過Valgrind的運行程序沒有區別似乎並不提出任何問題S(我認爲),例如:

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 

我還要補充一點,當我運行我的單元測試套件,編譯和鏈接到一個可執行文件,而不是通過一個共享庫,我沒有訪問功能任何這類問題。

只是增加了一個新功能:

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

稱之爲從main()這樣的:

dummy_utility(42);  

步入它使用gdb並獲得:

(gdb) p n 
$4 = 1086476160 

必須採摘建立一箇舊的庫,但當我搜索共享庫,例如

$ locate libProgram_dbg.so(_dbg版本有調試符號和無優化)

我得到了我的build/linux/debug目錄的單個文件,該文件是爲我所期望的,當我看到共享庫出現的時間戳它表明它有剛被重建!我真的很困惑..

以下是運行信息輸出在gdb寄存器:

之前調用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 

上步入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 

通過dummy_utility(),企圖加強從main()返回,gdb告訴我:

Cannot find bounds of current function 

運行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) 

如預期共享庫的位置..

+0

信息太少,但是:儘可能多地啓用警告,並確保編譯器沒有任何嚴重的標記。確保所有代碼都是重新構建的。 – unwind

+2

'get_streams'的原型原型 – egur

+0

根據要求添加了一些更多信息。 – bph

回答

1

我遇到了在Mac上類似的問題。 我安裝了gdb-apple,然後能夠在python中加載的共享庫中設置斷點/檢查變量。