Наш CheckPointer инструмент может обнаружить это с помощью динамического анализа, наряду с множеством других ошибок доступа к памяти.Инструмент отслеживает все выделения, доступы и назначения, включающие явные или неявные указатели, и жалуется в самый ранний момент, когда такой доступ является недопустимым или неопределенным.
Сохранение примера кода OP как "глючного".c ", и запуск CheckPointer производит следующий вывод (некоторые строки удалены по педагогическим причинам):
C~GCC4 CheckPointer Version 1.2.1001
Copyright (C) 2011-2016 Semantic Designs, Inc; All Rights Reserved; SD Confidential Powered by DMS (R) Software Reengineering Toolkit
Parsing source file "E:/DMS/Domains/C/GCC4/Tools/CheckPointer/Example/Source/buggy.c" using encoding CP-1252 +CRLF $^J $^M $^e -1 +8 ...
Grouping top level declarations ...
Creating object meta data initializers ...
Normalizing syntax tree ...
Instrumenting syntax tree ...
Ungrouping top level declarations ...
Writing target file "E:/DMS/Domains/C/GCC4/Tools/CheckPointer/Example/Target/buggy.c" using encoding CP-1252 +CRLF $^J $^M $^e -1 +8 ...
*** Compiling sources with memory access checking code gcc.exe -I"e:\DMS\Domains\C\GCC4\Tools\CheckPointer" -I.\Target -obuggy.exe Target\buggy.c Target\check-pointer-data-initializers.c "e:\DMS\Domains\C\GCC4\Tools\CheckPointer\check-pointer.c" "e:\DMS\Domains\C\GCC4\Tools\CheckPointer\check-pointer-splay-tree.c" "e:\DMS\Domains\C\GCC4\Tools\CheckPointer\check-pointer-wrappers.c"
*** Executing instrumented application
*** Error: CWE-465 Pointer Issue (subcategory CWE-476, CWE-587, CWE-824, or CWE-825)
Dereference of dangling pointer.
in function: main, line: 8, file E:/DMS/Domains/C/GCC4/Tools/CheckPointer/Example/Source/buggy.c
Конкретный тип ошибки сообщается с использованием кодов, определенных стандартом Common Weakness Enumeration .
NIST предлагает тест "пыток" для ошибок Java и C, который называется Juliet .CheckPointer обнаружил 13257 ожидаемых ошибок доступа к памяти из 14 195 тестовых примеров Juliet, относящихся к языку C.908 тестовых случаев не были диагностированы, но они включают в себя те, которые содержат неопределенное поведение, не связанное с ошибками использования указателя (которые CheckPointer не предназначен для обнаружения), или ошибками использования указателя, которые не были обнаружены при фактическом выполнении (например, неинициализированная переменная содержала 0 вфактическое исполнение).[Мы изменили некоторые из этих примеров, чтобы фактическое выполнение не содержало 0 для таких переменных, а затем CheckPointer выдал сообщение об ошибке, как и ожидалось.]
CheckPointer работает с GCC и MSVisualStudio.
==============================================
@ nm сделалколичество комментариев к различным ответам в этой теме.Он выпустил своего рода задачу, в которой продемонстрировал, что valgrind не может найти ошибку в следующем коде, похожую на OP, но более глубоко вложенную:
#include <stdio.h>
void badidea(int**);
void worseidea(int**);
int main(void) {
int* p;
badidea(&p);
// printf("%d\n", *p); /* undefined behavior happens here: p points to x from badidea, which is now out of scope */
worseidea(&p);
return 0;
}
void worseidea(int **p) {
int x = 42;
printf("%d %d\n", **p, x); /* undefined behavior happens here: p points to x from badidea, which is now out of scope */
}
void badidea(int** p) {
int x = 5;
*p = &x;
}
Вот прогон Checkpointer, который диагностирует указательпроблема в коде nm:
C~GCC4 CheckPointer Version 1.2.1001
Copyright (C) 2011-2016 Semantic Designs, Inc; All Rights Reserved; SD Confidential
...
Parsing source file "C:/Users/idbaxter/AppData/Local/Temp/DMS/Domains/C/GCC4/Tools/CheckPointer/Example/Source/buggy.c" using encoding CP-1252 +CRLF $^J $^M $^e -1 +8 ...
...
Writing target file "C:/Users/idbaxter/AppData/Local/Temp/DMS/Domains/C/GCC4/Tools/CheckPointer/Example/Target/buggy.c" using encoding CP-1252 +CRLF $^J $^M $^e -1 +8 ...
*** Compiling sources with memory access checking code
gcc.exe -I"c:\DMS\Domains\C\GCC4\Tools\CheckPointer" -I.\Target -obuggy.exe Target\buggy.c Target\check-pointer-data-initializers.c "c:\DMS\Domains\C\GCC4\Tools\CheckPointer\check-
pointer.c" "c:\DMS\Domains\C\GCC4\Tools\CheckPointer\check-pointer-splay-tree.c" "c:\DMS\Domains\C\GCC4\Tools\CheckPointer\check-pointer-wrappers.c"
*** Executing instrumented application
*** Error: CWE-465 Pointer Issue (subcategory CWE-476, CWE-587, CWE-824, or CWE-825)
Dereference of dangling pointer.
in function: worseidea, line: 16, file C:/Users/idbaxter/AppData/Local/Temp/DMS/Domains/C/GCC4/Tools/CheckPointer/Example/Source/buggy.c
called in function: main, line: 10, file: C:/Users/idbaxter/AppData/Local/Temp/DMS/Domains/C/GCC4/Tools/CheckPointer/Example/Source/buggy.c