在我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)
如預期共享庫的位置..
信息太少,但是:儘可能多地啓用警告,並確保編譯器沒有任何嚴重的標記。確保所有代碼都是重新構建的。 – unwind
'get_streams'的原型原型 – egur
根據要求添加了一些更多信息。 – bph