2014-12-04 100 views
8

考慮下面的代碼(用於演示目的):VS可能會警告可能的堆棧溢出異常嗎?

#include <iostream> 

int main() 
{ 
    char pixels[4][1280][720]; // Big enough to cause a stack overflow on my machine 
    for (unsigned int i = 0; i < 4; i++) 
    { 
     for (unsigned int j = 0; j < 1280; j++) 
     { 
      for (unsigned int k = 0; k < 720; k++) 
      { 
       pixels[i][j][k] = i + j + k; 
      } 
     } 
    } 

    std::cout << pixels[2][640][360]; 
    return 0; 
} 

據對this question解答,最大堆棧大小是由Visual Studio設置。

我正確地假設它可以警告用戶有關潛在堆棧溢出? (我自己試過,沒有得到警告)

PS:我問的唯一原因是因爲我看到很多關於SO的問題,可以通過這樣的警告來預防(是的,我不知道每個人SO用戶使用VS)。

+4

評估複雜的代碼以準確地知道它將如何執行而不執行它是聖盃之一。不要期待你的希望。 – 2014-12-04 18:06:42

+1

你的意思是類似於GCC'-Wstack-usage = 1234'嗎? – Fanael 2014-12-04 18:08:08

+2

@Fanael我的意思是如果數組的大小以字節爲單位大於堆棧限制,此時堆棧溢出將發生。所以它可能會對此提出警告。是的,似乎是這樣。 – Borgleader 2014-12-04 18:09:47

回答

11

它已經這樣做,在有可用的/analyze標誌的版本:

C:\>cl /EHsc /analyze stack.cpp 
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x64 
Copyright (C) Microsoft Corporation. All rights reserved. 

stack.cpp 
c:\stack.cpp(3) : warning C6262: Function uses '3686412' bytes of stack: exceeds /analyze:stacksize '16384'. Consider moving some data to heap. 

prefast工具隨DDK/WDK產生了類似的警告。

當然,這是一個非常簡單的靜態檢查(如果函數的堆棧使用率高於某個閾值)。它不會嘗試檢測遞歸調用或通過調用鏈來增加總靜態使用量。

+0

是否僅在$ 2,000版本中提供分析? – 2014-12-05 00:43:32

+3

我相信以前的版本是這種情況,但從2013年起[所有版本都有](http://blogs.msdn.com/b/hkamel/archive/2013/10/24/visual-studio-2013 -static碼分析縱深 - 什麼 - 和 - how.aspx時)。 – 2014-12-05 00:44:42

6

編譯器可以給予警告的幾乎所有的,但在這種情況下,這將是非常困難的編譯器給一個真正有意義的警告

特別是,堆棧大小直到鏈接時間才被真正選中。編譯器在鏈接器之前運行,所以它基本上不可能知道在運行鏈接器時可能選擇的堆棧大小。因此,如果編譯器發出警告,最好能做的就是假設將選擇一些「合理」的堆棧大小,並將警告基於違反該警告。

一個足夠智能的鏈接器可能大概會發出這樣的警告,但它需要相當多的智能。特別是,通過鏈接看到它的時候,堆棧分配看起來像(機器代碼表示):

sub esp, 123456 ; or sub rsp, 123456 in 64-bit code. 

鏈接器必須找到每個堆棧指針是被操縱的地方,並檢查涉及的數量的大小以有意義地發出警告。要做到這一點,基本上必須弄清楚什麼是代碼和什麼是數據,並反彙編和檢查代碼(但不是數據,這些數據可能會反彙編爲無意義的代碼)。這可能都是可能的,但可能有點不重要,當然也不在連接器通常所做或所用的各種事物的範圍之內。

+0

我不知道是否有一個編譯器選項,會警告當一個函數使用過量的堆棧。由於我通常在內聯的幾個級別使編譯器決定在堆棧上放置1000個SIMD值時經常吹動堆棧。 – Mysticial 2014-12-04 19:51:38

+0

看起來像這樣:http://msdn.microsoft.com/en-us/library/7yhee2f0.aspx – Mysticial 2014-12-04 19:59:34

+0

@Mysticial:正如Andrew Medico指出的那樣,'/ analyze'標誌基本上符合我的第二段提示:選擇一個「合理」的大小,並警告你,如果超過。大小默認爲16K,但您可以根據需要將其設置爲其他大小,例如:'/ analyze:stacksize 65535',這顯然會尋找64K。 – 2014-12-04 20:02:06