2016-11-15 81 views
1

我試圖調試一塊彙編程序(x86 64-bit),並根據gdb信息,它使用下面的指令時崩潰:程序正常,但沒有崩潰,Valgrind的

xorpd 0x1770(%rip),%xmm12  # 0x40337c <S_0x403230> 

然而,似乎對我來說,內存0x40337c是完全正常的:

(gdb) x /10x 0x40337c 
0x40337c <S_0x403230>: 0x00000000  0x80000000  0x00000000  0x00000000 
0x40338c <S_0x403240>: 0xf149f2ca  0x00000000  0x746e7973  0x203a7861 
0x40339c <S_0x403248+8>:  0x206d626c  0x6d69743c 

另一個有線的是,這段代碼崩潰每次當我在命令行中運行它,以及裏面gdb。但是,當我在valgrind中調試它時,它不會崩潰!

☁ src [master] ⚡ valgrind ./a.out 20 reference.dat 0 1 100_100_130_cf_a.of 
==18329== Memcheck, a memory error detector 
==18329== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. 
==18329== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info 
==18329== Command: ./a.out 20 reference.dat 0 1 100_100_130_cf_a.of 
==18329== 
MAIN_printInfo: 
    grid size  : 100 x 100 x 130 = 1.30 * 10^6 Cells 
    nTimeSteps  : 20 
    result file : reference.dat 
    action   : nothing 
    simulation type: channel flow 
    obstacle file : 100_100_130_cf_a.of 

LBM_showGridStatistics: 
    nObstacleCells: 498440 nAccelCells:  0 nFluidCells: 801560 
    minRho: 1.0000 maxRho: 1.0000 mass: 1.300000e+06 
minU: 0.000000e+00 maxU: 0.000000e+00 

LBM_showGridStatistics: 
    nObstacleCells: 498440 nAccelCells:  0 nFluidCells: 801560 
    minRho: 1.0000 maxRho: 1.0431 mass: 1.300963e+06 
    minU: 0.000000e+00 maxU: 1.272361e-02 

==18329== 
==18329== HEAP SUMMARY: 
    ==18329==  in use at exit: 0 bytes in 0 blocks 
==18329== total heap usage: 4 allocs, 4 frees, 428,801,136 bytes allocated 
==18329== 
==18329== All heap blocks were freed -- no leaks are possible 
==18329== 
==18329== For counts of detected and suppressed errors, rerun with: -v 
==18329== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 

我上傳了二進制代碼here供您參考,如果您有興趣。彙編程序實際上是由二進制重寫器生成的,我曾經能夠生成無錯代碼。所以我相信這可能不是一個難以調試的指針解引用問題,應該是非常容易修復的東西。但是,我真的不知道哪裏出了問題,並且在gdb調試中看起來非常正常(x/10x 0x40337

因此,這裏是我的問題,

  1. 給出的調試信息(x/10x 0x40337c),其中可能出問題?

  2. 爲什麼二進制代碼不會在valgrind中崩潰?

回答

3

Valgrind runs your code on a simulated x86 CPU。顯然它不模擬對齊檢查。


對SSE指令的128位和更大內存操作數始終需要自然對齊。 (例如,對於這種16B負載的16B邊界)。例外是MOVUPS_mm_loadu_ps)(和MOVUPD/MOVDQU)。

0x40337c不是16B對齊,只有4B。 (所以你使用它與XORPD是很奇怪的,因爲我期望至少8B對齊double)。

AVX指令正好相反:默認值不需要對齊,但VMOVAPS確實需要對齊。

+0

謝謝彼得。現在我知道更好..你有什麼想法,應該如何解決這個問題?由於該指針('S_0x403230')引用'.rodata'節中的某個位置,因此可能會強制'.rodata'節的16b對齊會起作用? – computereasy

+0

如果我在1.5年前正確記得,當我使用這個二進制重寫器並且在上面完全相同的一段代碼上工作時,我應該以某種方式在生成的彙編代碼中進行一些對齊,但我不記得詳細信息了..我會試圖弄清楚。謝謝! – computereasy

+0

@computereasy:是的,做任何你需要做的事情,以便你的向量常量是對齊的,而不是改變你的程序使用未對齊的加載到tmp寄存器中。這聽起來像是你的重寫軟件中的一個錯誤,如果它不能保留部分指定的對齊。你可以用'readelf -S foo.o'來看。 '.rodata'部分應該是文本段的一部分,通常至少16B對齊。 'S_0x403230'聽起來像原來的地址是對齊的,因爲最後一個十六進制數字是0. –

相關問題