diff --git a/man/manual.docbook b/man/manual.docbook index 072751ddd..e52b3b247 100644 --- a/man/manual.docbook +++ b/man/manual.docbook @@ -704,107 +704,176 @@ Checking test.c... Library configuration - Cppcheck has internal knowledge about how - standard C/C++ functions work. There is no internal knowledge about how - all libraries and environments work, and there can't be. - Cppcheck can be told how libraries and environments - work by using configuration files. + When external libraries are used, such as windows/posix/gtk/qt/etc, + Cppcheck doesn't know how the external functions + behave. Cppcheck then fails to detect various problems + such as leaks, buffer overflows, possible null pointer dereferences, etc. + But this can be fixed with configuration files. - The idea is that users will be able to download library - configuration files for all popular libraries and environments - here: + If you create a configuration file for a popular library, we would + appreciate if you upload it to us. - http://cppcheck.sourceforge.net/archive +
+ Memory/resource leaks - Ideally, all you need to do is choose and download the configuration - files you need. + Here is an example program: - The archive is not complete however. If you can't find the - configuration file you need in the archive, you can wait - maybe somebody - else will write it and share it. Or you can write your own configuration - file (and then it's possible to share your configuration file with - others). + void test() +{ + HPEN pen = CreatePen(PS_SOLID, 1, RGB(255,0,0)); +} - A minimal configuration file looks like this: + The code example above has a resource leak - + CreatePen() is a windows function that creates a pen. + However Cppcheck doesn't assume that return values from functions must + be freed. There is no error message: - <?xml version="1.0"?> + # cppcheck pen1.c +Checking pen1.c... + + If you provide a windows configuration file then + Cppcheck detects the bug: + + # cppcheck --library=windows.cfg pen1.c +Checking pen1.c... +[pen1.c:3]: (error) Resource leak: pen + + Here is a minimal windows.cfg file: + + <?xml version="1.0"?> <def> -</def> - - This configuration file is filled up with various options: - - <?xml version="1.0"?> -<def> - <memory> - <alloc>CreateFred</alloc> - <dealloc>CloseFred</dealloc> - - <use>AppendFred</use> - </memory> - - <memory> - <alloc init="false">AllocWilma</alloc> - <alloc init="true">CAllocWilma</alloc> - <dealloc>CloseWilma</dealloc> - </memory> - <resource> - <alloc>Lock</alloc> - <dealloc>Unlock</dealloc> + <alloc>CreatePen</alloc> + <dealloc>DeleteObject</dealloc> </resource> +</def> +
- <function name="IsEqual"> - <leak-ignore/> - </function> +
+ Uninitialized memory - <function name="AssignFred"> - <noreturn>false</noreturn> - <arg nr="1"> - <not-null/> - </arg> + Here is an example program: + + void test() +{ + char buffer1[1024]; + char buffer2[1024]; + CopyMemory(buffer1, buffer2, 1024); +} + + The bug here is that buffer2 is uninitialized. The second argument + for CopyMemory needs to be initialized. However + Cppcheck assumes that it is fine to pass + uninitialized variables to functions: + + # cppcheck uninit.c +Checking uninit.c... + + If you provide a windows configuration file then Cppcheck detects + the bug: + + # cppcheck --library=windows.cfg uninit.c +Checking uninit.c... +[uninit.c:5]: (error) Uninitialized variable: buffer2 + + Here is the minimal windows.cfg: + + <?xml version="1.0"?> +<def> + <function name="CopyMemory"> <arg nr="2"> <not-uninit/> </arg> - <arg nr="3"> - <strz/> - </arg> - <arg nr="4"> - <formatstr/> + </function> +</def> +
+ +
+ Null pointers + + Cppcheck assumes it's ok to pass NULL pointers to functions. Here + is an example program: + + void test() +{ + CopyMemory(NULL, NULL, 1024); +} + + The MSDN documentation is not clear if that is ok or not. But + let's assume it's bad. Cppcheck assumes that it's ok to pass NULL to + functions so no error is reported: + + # cppcheck null.c +Checking null.c... + + If you provide a windows configuration file then + Cppcheck detects the bug: + + cppcheck --library=windows.cfg null.c +Checking null.c... +[null.c:3]: (error) Null pointer dereference + + Here is a minimal windows.cfg file: + + <?xml version="1.0"?> +<def> + <function name="CopyMemory"> + <arg nr="1"> + <not-null/> </arg> </function> </def> - - In the <memory> and - <resource> the allocation and deallocation - functions are configured. Putting allocation and deallocation functions in - different <memory> and - <resource> blocks means they are mismatching - - you'll get a warning message if you allocate memory with - CreateFred and try to close it with - CloseWilma. - - The <use> and - <leak-ignore> elements are used to control the - leaks checking. If it should be ignored that a function is called, use - <leak-ignore>. If there is no leak whenever the - memory is passed to a function, use <use>. - - In the <function> block some useful info is - added about function behaviour. The <noreturn> - tells Cppcheck if the function is a no return function. - The <arg> is used to validate arguments. If it's - invalid to pass NULL, use <not-null>. If it's - invalid to pass uninitialized data, use - <not-uninit>. If the argument is a - zero-terminated string, use <strz>. If the - argument is a formatstring, use - <formatstr>. +
- Example: strcpy() + noreturn - The strcpy() was chosen in this example for demonstration purposes - because its behaviour is well-known. + Cppcheck doesn't assume that functions always return. Here is an + example code: + + void test(int x) +{ + int data, buffer[1024]; + if (x == 1) + data = 123; + else + ZeroMemory(buffer, sizeof(buffer)); + buffer[0] = data; // <- error: data is uninitialized if x is not 1 +} + + In theory, if ZeroMemory terminates the program + then there is no bug. Cppcheck therefore reports no error: + + # cppcheck noreturn.c +Checking noreturn.c... + + However if you use --check-library and + --enable=information you'll get this: + + # cppcheck --check-library --enable=information noreturn.c +Checking noreturn.c... +[noreturn.c:7]: (information) --check-library: Function ZeroMemory() should have <noreturn> configuration + + + If a proper windows.cfg is provided, the bug is + detected: + + # cppcheck --library=windows.cfg noreturn.c +Checking noreturn.c... +[noreturn.c:8]: (error) Uninitialized variable: data + + Here is a minimal windows.cfg file: + + <?xml version="1.0"?> +<def> + <function name="ZeroMemory"> + <noreturn>false</noreturn> + </function> +</def> +
+ +
+ Example configuration for strcpy() The proper configuration for the standard strcpy() function would be: @@ -821,20 +890,16 @@ Checking test.c... </arg> </function> - The <leak-ignore/> is optional and it - tells Cppcheck to ignore this function call in the leaks checking. - Passing allocated memory to this function won't mean it will be - deallocated. + The <leak-ignore/> tells Cppcheck to + ignore this function call in the leaks checking. Passing allocated + memory to this function won't mean it will be deallocated. - The <noreturn> is optional. But it's - recommended. + The <noreturn> tells Cppcheck if this + function returns or not. The first argument that the function takes is a pointer. It must - not be a null pointer, a uninitialized pointer nor a dead pointer. It - must point at some data, this data can be initialized but it is not - wrong if it isn't. Using <not-null> is correct. - Cppcheck will check by default that the pointer is - not uninitialized nor dead. + not be a null pointer, therefore <not-null> is + used. The second argument the function takes is a pointer. It must not be null. And it must point at initialized data. Using