魔鬼在細節,但是這可能會爲你工作:
首先,得到Frama-C。如果你使用的是Unix,你的發行版可能會有一個包。該軟件包不會是最後一個版本,但它可能足夠好,如果以這種方式安裝它,它會爲您節省一些時間。
說你的例子如下,只有這麼多的大,這不是明顯的什麼是錯的:
int add(int x, int y)
{
static int state;
int result = x + y + state; // I tested it once and it worked.
state++;
return result;
}
類型像這樣的命令:
frama-c -lib-entry -main add -deps ugly.c
選項-lib-entry -main add
表示「看功能add
」。選項-deps
計算函數依賴關係。你會在日誌中找到這些「函數依賴」:
[from] Function add:
state FROM state; (and default:false)
\result FROM x; y; state; (and default:false)
此列出實際投入add
結果依賴的對象,從這些輸入計算出的實際輸出,包括讀取靜態變量並修改。在使用之前正確初始化的靜態變量通常不會作爲輸入出現,除非分析器在讀取之前無法確定它始終被初始化。
該日誌顯示state
作爲\result
的依賴關係。如果您期望返回的結果僅依賴於參數(意味着具有相同參數的兩個調用會產生相同的結果),則此變量可能存在錯誤,其變量爲state
。
上述行中顯示的另一個提示是該功能修改了state
。
這可能有幫助。選項意味着分析器不會假定任何非常量靜態變量在調用分析函數時保留了它的值,因此對於您的代碼可能太不精確。有辦法可以解決這個問題,但是你是否想要花時間學習這些方法取決於你。
編輯:這是一個比較複雜的例子:
void initialize_1(int *p)
{
*p = 0;
}
void initialize_2(int *p)
{
*p; // I made a mistake here.
}
int add(int x, int y)
{
static int state1;
static int state2;
initialize_1(&state1);
initialize_2(&state2);
// This is safe because I have initialized state1 and state2:
int result = x + y + state1 + state2;
state1++;
state2++;
return result;
}
在這個例子中,相同的命令產生的結果:
[from] Function initialize_1:
state1 FROM p
[from] Function initialize_2:
[from] Function add:
state1 FROM \nothing
state2 FROM state2
\result FROM x; y; state2
你所看到的initialize_2
是依賴一個空列表,意味着該功能不分配任何東西。我會通過顯示一個明確的消息而不僅僅是一個空的列表來使這個例子更加清晰。如果您知道initialize_1
,initialize_2
或或add
應該執行的任何功能,則可以將此先驗知識與分析結果進行比較,並看到initialize_2
和add
有什麼錯誤。
第二次編輯:現在我的例子顯示initialize_1
奇怪的東西,所以也許我應該解釋一下。變量state1
取決於p
,因爲p
用於寫入state1
,並且如果p
已經不同,則最終值state1
本應不同。下面是最後一個例子:
int t[10];
void initialize_index(int i)
{
t[i] = 1;
}
int main(int argc, char **argv)
{
initialize_index(argv[1][0]-'0');
}
隨着命令frama-c -deps t.c
,計算了initialize_index
的依賴關係是:
[from] Function initialize_index:
t[0..9] FROM i (and SELF)
這意味着每個單元的取決於i
如果i
是(它可被修改該特定小區的索引)。每個小區還可以保持它的價值(如果i
表示另一個單元格):這表明,在最新版本的(and SELF)
提及並表明與以前的版本更加晦澀(and default:true)
。
有趣的問題,但valgrind不知道「本地」或「宣佈」。我認爲這必須通過代碼分析來完成,而不是可執行分析。 – aschepler
我們使用PC Lint,但它產生了很多警告的地獄,所以找到真正的熱點有時像在黑暗中釣魚。 –