The devil là tại các chi tiết, nhưng điều này có thể làm việc cho bạn:
Đầu tiên, có được Frama-C. Nếu bạn đang sử dụng Unix, phân phối của bạn có thể có một gói. Các gói phần mềm sẽ không được phiên bản cuối cùng nhưng nó có thể là đủ tốt và nó sẽ giúp bạn tiết kiệm một số thời gian nếu bạn cài đặt nó theo cách này.
Nói ví dụ của bạn là như dưới đây, chỉ nên lớn hơn nhiều mà nó không rõ ràng những gì là sai:
int add(int x, int y)
{
static int state;
int result = x + y + state; // I tested it once and it worked.
state++;
return result;
}
Loại một lệnh như:
frama-c -lib-entry -main add -deps ugly.c
Tùy chọn -lib-entry -main add
có nghĩa là "nhìn vào chức năng add
". Tùy chọn -deps
tính các phụ thuộc chức năng. Bạn sẽ tìm thấy những "phụ thuộc chức năng" trong nhật ký:
[from] Function add:
state FROM state; (and default:false)
\result FROM x; y; state; (and default:false)
này liệt kê các thực tế đầu vào kết quả của add
phụ thuộc vào, và thực tế quả tính toán từ các nguyên liệu đầu vào, bao gồm các biến tĩnh đọc từ và sửa đổi. Một biến tĩnh đã được khởi tạo đúng cách trước khi được sử dụng bình thường sẽ không xuất hiện như đầu vào, trừ khi máy phân tích không thể xác định rằng nó luôn được khởi tạo trước khi được đọc.
Nhật ký hiển thị state
làm phụ thuộc của \result
. Nếu bạn mong đợi kết quả trả về chỉ phụ thuộc vào các đối số (có nghĩa là hai cuộc gọi với cùng một đối số tạo ra cùng một kết quả), đó là một gợi ý có thể có điều gì sai ở đây, với biến số state
.
Một gợi ý khác được hiển thị trong các dòng trên là chức năng sửa đổi state
.
Điều này có thể hữu ích hay không. Tùy chọn có nghĩa là trình phân tích không cho rằng bất kỳ biến tĩnh không const nào đã giữ giá trị của nó tại thời điểm hàm phân tích được gọi, do đó có thể quá thiếu chính xác cho mã của bạn. Có những cách xung quanh đó, nhưng sau đó nó là vào bạn cho dù bạn muốn đánh bạc thời gian cần để tìm hiểu những cách này.
EDIT: đây là một ví dụ phức tạp hơn:
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;
}
On ví dụ này, lệnh cùng tạo ra kết quả:
[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
gì bạn nhìn thấy cho initialize_2
là một danh sách trống phụ thuộc, nghĩa là hàm gán không có gì. Tôi sẽ làm cho trường hợp này rõ ràng hơn bằng cách hiển thị một thông điệp rõ ràng hơn là một danh sách trống. Nếu bạn biết bất kỳ chức năng nào trong số các chức năng initialize_1
, initialize_2
hoặc add
có nghĩa vụ phải làm, bạn có thể so sánh kiến thức này với kết quả phân tích và thấy rằng có điều gì đó sai cho initialize_2
và add
.
EDIT SECOND: và bây giờ ví dụ của tôi cho thấy một cái gì đó kỳ lạ cho initialize_1
, vì vậy có lẽ tôi nên giải thích điều đó. Biến số state1
phụ thuộc vào p
theo nghĩa là p
được sử dụng để ghi vào state1
và nếu p
khác nhau, thì giá trị cuối cùng của state1
sẽ khác. Dưới đây là một ví dụ cuối cùng:
int t[10];
void initialize_index(int i)
{
t[i] = 1;
}
int main(int argc, char **argv)
{
initialize_index(argv[1][0]-'0');
}
Với lệnh frama-c -deps t.c
, sự phụ thuộc tính cho initialize_index
là:
[from] Function initialize_index:
t[0..9] FROM i (and SELF)
Điều này có nghĩa rằng mỗi người trong các tế bào phụ thuộc vào i
(nó có thể được sửa đổi nếu i
là chỉ mục của ô cụ thể đó). Mỗi ô cũng có thể giữ giá trị của nó (nếu i
cho biết một ô khác): điều này được biểu thị bằng số (and SELF)
đề cập trong phiên bản mới nhất và được biểu thị bằng một số ít (and default:true)
trong các phiên bản trước.
Câu hỏi thú vị, nhưng valgrind không có kiến thức về "địa phương" hoặc "tuyên bố". Tôi nghĩ rằng điều này phải được thực hiện bằng cách phân tích mã, không phải phân tích thực thi. – aschepler
chúng tôi sử dụng PC Lint, nhưng nó tạo ra rất nhiều cảnh báo để tìm các điểm nóng thực sự đôi khi giống như câu cá trong bóng tối. –