410 likes | 423 Views
Finding Bugs with DevPartner Studio Error Detection. Philippe CHARMAN Polytech’Nice – Sophia. Installing DevPartner Studio. Official name: Micro Focus DevPartner Studio Launch the installer dpspe110000.exe It’s not necessary to install DevPartner System Comparison
E N D
Finding Bugs withDevPartner StudioError Detection Philippe CHARMAN Polytech’Nice – Sophia
Installing DevPartner Studio • Official name: Micro Focus DevPartner Studio • Launch the installer dpspe110000.exe • It’s not necessary to install DevPartner System Comparison • The trial license is valid during 10 days starting from the installation • 2 modes of analysis: • non-instrumented mode: ActiveCheck (default) • instrumented code: FinalCheck
ActiveCheck - Automatic Error Detection for Daily Use • ActiveCheck is used by default to find errors • Reported errors come from the program executable as well as the DLLs, third-party modules, and COM components used by the program • Errors can be found in programs for which you do not have source code; however it’s more efficient to understand what is going wrong when the source code is built with debug info • ActiveCheck does not require recompiling or relinking. It can be used during the daily development cycle.
Errors detected by ActiveCheck (non-instrumented mode) • Pointer and Leak Errors • Interface leak, memory leak, resource leak, etc. • Memory Errors • Dynamic memory overrun • Freed handle is still locked • Memory allocation conflict • etc • API and COM Errors • API failure - function failed • API failure - function not implemented • Invalid argument • etc
FinalCheck - Comprehensive Error Detection • FinalCheck instrument the source code by adding error detection code and then passes the intrumented source code back to the compiler • FinalCheck finds all the errors ActiveCheck finds but also complex or hidden program errors, including: • Memory leaks, including leaks created when reassigning or freeing memory • Memory overflows and initialization errors • Pointer errors, including errors created when assigning out-of-range pointers • Because FinalCheck searches for more errors and requires that you rebuild your program, using FinalCheck will lengthen your build times. Therefore, you should use FinalCheck only when you need comprehensive error checking at a key milestone in your program, such as a Beta release, feature complete, or final production.
Errors detected by FinalCheck (instrumented mode) • Pointer errors • Array index out of range • Assigning pointer out of range • etc • Leak errors • Memory leaked due to free • Memory leaked due to reassignment • etc • Memory errors • Reading overflows memory • Reading uninitialized memory • etc
First program hello.c #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { int i; size_t length; char *string1 = "Hello, World"; char *string2 = (char*)malloc(10); length = strlen(string2); for (i = 0; string1[i] != '\0'; i++) { string2[i] = string1[i]; } length = strlen(string2); printf("My message: %s", string2); return 0; }
Building & executing hello.c • Build hello.exe with these compiler and link options: cl -c hello.c link.exe hello.obj user32.lib or build by default: cl hello.c • Execute hello.exe and check the following message is displayed: My message: Hello, World
Execute hello.exe in DPS • Launch DevPartner Error Detection • Open hello.exe (File > Open) • Execute hello.exe within Error Detection • 3 ways to launch the execution: • Program > Start • F5 • Blue arrow in the tool bar • Check Don’t show this error dialog with Always • Click on Continue
Results found • Errors and memory leaks have been found
About the results • Symptom 1: Reported errors and memory leaks but we don’t see the code source • Solution: code must be built in debug mode • Sympton 2: Reported errors of code not from hello.cpp • Solution: restrict the modules to hello.exe only • Sympton 3: Missing errors not reported • Solution: build in instrumented mode (FinalCheck)
Code source not displayed • To enable the display of the code source, we have to build in debug mode • Build hello.exe in debug • For instance withthese compiler and link options: cl /Zi -c hello.c link.exe /debug hello.obj user32.lib • or likethis: cl /MTdhello.c
Examine only hello.exe • Program > Settings > Modules and Files
Building in instrumented mode • NMcl.exe isinstalled by default in C:\Program Files\Common Files\Micro Focus\NMShared or C:\Program Files (x86)\Common Files\Micro Focus\NMShared • Add this directory to your path • Relaunch the executionwithin DPS ErrorDetection • What do wesee ?
Fixing bugs of hello.c • Fix hello.c and check no more errors and memory leaks are reported
Still some errors are found • Right-click and select Filter • Click on OK • Do the same for all errors or memory leaks
The examplesex1.cpp .. ex11.cpp • For each example exn.cpp (n=1 .. 11) • Build and execute sample1.cpp in instrumented code, is by using NMcl instead of cl • Look at the results found by DPS Error Detection • Fix the bugs and check everything’s OK • When checking the bugs are fixed, the build can be done in non-instrumented code, ie by using cl
ex1.cpp void foo1(int *pi) { int j; *pi = j; } void main(intargc, char** argv) { int i=10, j; i = j; printf("i = %d\n", i); int k=10; foo1(&k); printf("k = %d\n", k); }
ex2.cpp typedefstructnode { structnode* next; int val; } Node; intfindLastNodeValue(Node* head) { while (head->next != NULL) { head = head->next; } return head->val; } void main(intargc, char** argv) { int i = findLastNodeValue(NULL); }
ex3.cpp void main(intargc, char** argv) { int *ipr = (int *) malloc(4 * sizeof(int)); int i, j; i = *(ipr - 1000); j = *(ipr + 1000); free(ipr); int *ipw = (int *) malloc(5 * sizeof(int)); *(ipw - 1000) = 0; *(ipw + 1000) = 0; free(ipw); }
ex4.cpp int* init_array(int *ptr, int new_size) { ptr = (int*) realloc(ptr, new_size*sizeof(int)); memset(ptr, 0, new_size*sizeof(int)); return ptr; } int* fill_fibonacci(int *fib, int size) { int i; init_array(fib, size); fib[1] = 1; for (i=2; i<size; i++) fib[i] = fib[i-1] + fib[i-2]; return fib; } void main(int argc, char** argv) { int *array = (int*)malloc(10); fill_fibonacci(array, 3); }
ex5.cpp char *append(const char* s1, const char *s2) { const int MAXSIZE = 128; char result[128]; int i=0, j=0; for (j=0; i<MAXSIZE-1 && j<strlen(s1); i++,j++) { result[i] = s1[j]; } for (j=0; i<MAXSIZE-1 && j<strlen(s2); i++,j++) { result[i] = s2[j]; } result[++i] = '\0'; return result; } void main(int argc, char** argv) { char *name = append("IBM ", append("Rational ", "Purify")); printf("%s\n", name); /* Expect BSR */ *name = '\0'; /* Expect BSW */ }
ex6.cpp void main(intargc, char** argv) { const char *name = "Life's a beach"; char *str = (char*) malloc(10); strncpy(str, name, 10); str[11] = '\0'; printf("%s\n", str); }
ex7.cpp int *pi; voidfoo() { pi = (int*) malloc(8*sizeof(int)); free(pi); } void main() { pi = (int*) malloc(4*sizeof(int)); foo(); pi[0] = 10; }
ex8.cpp int *plk = NULL; void main(intargc, char** argv) { plk = (int *) malloc(2 * sizeof(int)); plk++; }
ex9.cpp void main(intargc, char** argv) { int *pi = (int*) malloc(4 * sizeof(int)); delete pi; pi = new int[5]; delete pi; }
ex10.cpp void main(intargc, char** argv) { intfnh = 0; free(&fnh); int *fum = (int *) malloc(4 * sizeof(int)); free(fum+1); free(fum); free(fum); }
ex10.cpp void main(intargc, char** argv) { intfnh = 0; free(&fnh); int *fum = (int *) malloc(4 * sizeof(int)); free(fum+1); free(fum); free(fum); }