2017-05-08 16 views
2

加載地址X的我正在通過未定義行爲消毒劑一些更新。消毒劑是生產的消息我不太明白:與空間不足的類型的對象Ÿ

kalyna.cpp:1326:61: runtime error: load of address 0x0000016262c0 with insufficient space for an object of type 'const uint32_t' 
0x0000016262c0: note: pointer points here 
20 8b c1 1f a9 f7 f9 5c 53 c4 cf d2 2f 3f 52 be 84 ed 96 1b b8 7a b2 85 e0 96 7d 5d 70 ee 06 07 
      ^

有問題的代碼試圖使緩存計時攻擊更難通過高速緩存行的範圍內接觸地址。 1326線與reinterpret_cast行:

// In KalynaTab namespace 
uint64_t S[4][256] = { 
    ... 
}; 
... 

// In library's namespace 
const int cacheLineSize = GetCacheLineSize(); 
volatile uint32_t _u = 0; 
uint32_t u = _u; 

for (unsigned int i=0; i<256; i+=cacheLineSize) 
    u &= *reinterpret_cast<const uint32_t*>(KalynaTab::S+i); 

爲什麼santizier聲稱一個uint32_t u沒有足夠的空間來容納一個uint32_t

或者,也許,我會正確地分析錯誤消息?那是什麼桑給瑞爾在抱怨?如果我不正確地解析它,那麼衛生潔具會抱怨什麼?


$ lsb_release -a 
LSB Version: :core-4.1-amd64:core-4.1-noarch 

$ gcc --version 
gcc (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1) 
+0

我懷疑它抱怨'*的reinterpret_cast <常量uint32_t的*>(KalynaTab :: S + I)'。 – cdhowie

+6

'KalynaTab :: S + i'是''i'th' uint64_t中[256]'您的4x256表的* *主導維度的陣列。換句話說,只要'i'>> = 4,你就超出範圍並調用*未定義的行爲*。這是一個指針算術的東西。 – WhozCraig

+0

謝謝@WhozCraig。我相信你是對的。但是這是否解釋了關於空間不足的錯誤信息?換句話說,不會產生不同的結果(如訪問越界)嗎? – jww

回答

2

標識符S不會轉換到你認爲它的類型的指針。其結果是,你的指針運算都是你扔方式出你的數據的範圍,並通過實例最佳顯示:

#include <iostream> 
#include <cstdint> 

uint64_t S[4][256]; 

int main() 
{ 
    std::cout << static_cast<void*>(S+0) << '\n'; 
    std::cout << static_cast<void*>(S+1) << '\n'; 
    std::cout << static_cast<void*>(S+2) << '\n'; 
    std::cout << static_cast<void*>(S+3) << '\n'; 
    std::cout << '\n'; 

    std::cout << static_cast<void*>(*S+0) << '\n'; 
    std::cout << static_cast<void*>(*S+1) << '\n'; 
    std::cout << static_cast<void*>(*S+2) << '\n'; 
    std::cout << static_cast<void*>(*S+3) << '\n'; 
} 

輸出(顯然依賴於平臺)

0x1000020b0 
0x1000028b0 
0x1000030b0 
0x1000038b0 

0x1000020b0 
0x1000020b8 
0x1000020c0 
0x1000020c8 

注第一個序列數字爲每個下一行0x800的步幅。這是有道理的,因爲每行都是由0x100的每個8字節的條目組成(uint64_t元素)。在指針運算中使用的指針的類型是uint64_t (*)[256]

現在請注意第二個序列,這射進僅S[0]的步幅。步幅是8個字節,每個插槽一個。在這個計算中轉換的指針的類型是uint64_t *

總之,你的指針算法是假設S皈依uint64_t*,而事實並非如此。像所有數組到指針的轉換一樣,它轉換爲指向第一個元素的指針,包括所述相同的類型。數組數組中的元素類型爲uint64_t[256],因此轉換後的指針類型爲uint64_t (*)[256]

+0

謝謝,你是對的。我的電線穿過了元素的大小。希望我已經學會了有關診斷的新知識,並且我將在未來認識到這些信息。 – jww

相關問題