CS201 Lecture 2 GDB, The C Library RAOUL RIVAS PORTLAND STATE UNIVERSITY
Announcements 2
Multidimensional Dynamically Allocated Arrays Direct access support. Same as Multidimensional Static Arrays No direct allocation support Declare a single dimension array of pointers (Rows) For each row allocate an array (Columns) Char** array Char* 0x100 0x123 0x230 0x510 X Y Z A B C D E F G H I What s the value of array[1][2]? 3
Multidimensional Dynamically Allocated Arrays char** array; int i; Char** Char* array = (char**)malloc(sizeof(char*)*4); for(i=0; i < 4; i++){ array[i] = (char*)malloc(sizeof(char)*3); } array 0x100 0x123 0x230 0x510 X Y Z A B C D E F G H I array[2][0]= D ; for(i=0; i < 4; i++) { free (array[i]); } free(array); 4
Alternate Method Store the data in a single dimension array Flatten array into a single dimension Compute offsets during access Can t use multiple subscripts X Y Z A B C D E F G H I array X Y Z A B C D E F G H I 0 11 array = (char*)malloc(sizeof(char*)*4*3); idx=2*3+1; array[idx]= E ; free(array); 5
GDB Overview Inspect program execution and state at any point in time. Set breakpoints Read variable, dump stack Useful to find a wide range of bugs Must compile the program to include Symbols Use the g or ggdb flag If possible use O0 to disable optimizations 6
GDB Interactive Shell GDB is based on an interactive shell The shell prompt symbol is (gdb) History of past command TAB for autocompletion Integrated help Call the help command followed by the name of the command you need info about (gdb) help mycommand 7
Using GDB You can specify the program to load in the command line gdb myprogram Or you can load the program using the file command in the gdb prompt (gdb) (gdb) file myprogram To run your program use the run command (gdb) run If your code crashes you will see additional crash information 8
How to debug a program Debugging is a lot like fishing Stop execution at possible suspecting points or functions Look for the values of each variable until you can determine the problem Step through specific functions or loops to find any problems in your code 9
Breakpoints Breakpoints stop execution of a program at a specific point Use the break command Stop at a specific line in a source file (gdb) break file5.c:67 Stop at line 67 of file5.c Stop at a specific function (gdb) break my_func Stop at function my_func() After setting a breakpoint start your program using the run command 10
Navigating the Code GDB stops the execution of your program at a breakpoint GDB command prompt will appear To step through the code use the step command (gdb) step Executes one instruction and stops. If the line is a function it will step into your function Visual Studio calls this Step Into To execute an entire function as if it was a single instruction use the command next (gdb) next Visual Studio calls this Step Over For assembly use stepi and nexti! 11
Next vs. Step Next int main() { int val=5, result; } res=factorial(val); printf( %d\n, result); return 0; Step int factorial(int n) { int i, retv=1; } for(i=1; i<= n; i++) { retv*= 1; } return retv; 12
Printing a variable To print a variable use the command print (gdb) print myvar GDB can print variables members of structures (gdb) print mystruct.myvar Dereference pointer (gdb) print *myptr Support self-referential structures (gdb) print mylist->next->next 13
Watchpoint A watchpoint is similar to a breakpoint, except that it stops the execution when the value of a variable change No associated position in the code Variable is the stopping trigger Use the watch command to set a watchpoint on a variable (gdb) watch myvar Pause execution when the variable myvar changes int main() { int val=5, result; result= val + 1; val= 25; } When GDB stops if we set a Watchpoint on variable val? Val=25 14
Conditional Breakpoints Stop in a breakpoint only if certain condition is met Good to debug array or loop boundaries Cases where code fails with certain values Use the following syntax: (gdb) break breakpoint if condition Example (gdb) break file1:6 if i > ARRAYSIZE Stop at line 6 of file1 if i > ARRAYSIZE 15
Debugging in Windows GDB is the most popular debugger in Linux In Windows you can use WinDBG or the more user friendly Visual Studio Debugger Breakpoints, Watchpoints, Conditional Breakpoints Windows keeps Symbols in separate Program Database Files (PDB) PDB files must be loaded into WinDbg to produce any meaningful information A PDB file is specific to a particular build! 16
The C Library Standard library available across all C compilers Part of ANSI C Many implementations Microsoft C Runtime Library GNU C library Provides many services File Access Read and write to console String Manipulation Mathematical functions Time and Date functions Divided into modules Include header file with definitions before you can use them #include <header.h> 17
Back to Hello, world #include <stdio.h> Include stdio.h header file (so we can use printf) main() { printf( hello, world ); } 18
String Manipulation Assumes all strings are C-Strings char arrays with NULL character at the end ( \0 ) strlen(char *s1) Returns the number of character in the string not including the NULL character strncpy(char *dest, char *src, int n) Copies at most n characters of src on top of dest strncmp(char *s1, char *s2, int n) Compares up to n characters of s1 with s2 Returns 0 if s1== s2. Returns less than 0 if s1 < s2. Returns more than 0 if s1 > s2 strncat(char* s1, char *s2, int n) Appends up to n characters of s2 at the end of s1 19
String Manipulation #include <stdio.h> #include <string.h> int main () { char str1[]= "To be or not to be"; char str2[40]; char str3[6]; /* copy to sized buffer */ strncpy ( str2, str1, sizeof(str2) ); /* partial copy (only 5 chars): */ strncpy ( str3, str2, 5 ); /* null character manually added */ str3[5] = '\0'; Is the manually added NULL necessary? Why? } return 0; 20
File I/O FILE *fopen(const char *filename, const char *mode); Opens/Creates a file for read or write. Returns a pointer to a FILE structure Mode: r - Read, w - Write, a - Append, b - Binary mode int fclose(file *a_file); Close the file ASCII Read/Write fprintf(), fscanf(), fgets() Usually read one line at a time Good for Text, CSV files and files with line breaks Binary Read/Write Write of data in binary format Read/Write M-blocks of N-bytes at a time Use fwrite() and fread() 21
Console I/O Console I/O is like reading from a file. You can use the same file functions just specify stdin and stdout as the file pointers stdin stdout There are some specific functions for stdin and stdout are provided in the C library Most used function for console writing is printf Sometimes the File and Console versions have different behaviors or parameters fgets() does not behave the same a gets() Data read from the file/console must be validated fscanf() and scanf() are subject to many attacks fgets() is the safest way to read from the file/console Parse the string afterwards and convert to the specific types 22
String to Numbers Various functions based on the type strtol, strtoll, stroul, etc long int strtol (const char* str, char** endptr, int base); Parses a number inside a string and outputs it as a long str contains the string to parse endptr is an optional return value to the remaining of the string after the number base is the Base of the number (hex, octal, decimal, etc). Use zero for autodetect based on the format. int main () { char str1[]= 16734893 ; long number; } number=strtol(str1, NULL, 10); return 0; 23
Numbers to Strings Use sprint to create a string with the format you need sprintf(char* str, char *format, ) str contains the destination string. Make sure is pre-allocated to the maximum possible length. Limits.h contains macros with the largest and smallest number supported for each type. log 10 (MaxNum) + 1, not counting the sign Format is the format string used by the printf family of functions printf, fprintf, sprint int main () { char str1[12]; int number= 16734893; } sprintf(str1, %d, number); return 0; 24
Assertions Assertions are runtime checks placed on a program that are only checked during development They are ignored for production code. We define the macro NDEBUG to indicate that our code is production code #define NDEBUG An Assertion must be true at the time of its execution or the program will stop. To check an assertion we call the assert() function assert(condition); Do not use assertions to catch user or runtime errors 25
Assertions int main() { int str1[] = {1,2,3,4,5} int str2[3]; } assert(sizeof(str1) == sizeof(str2)); memcpy(str2, str1, sizeof(str1)); Not a user or runtime error Assert Fails and memcpy never executes 26
Summary Dynamically allocated multidimensional arrays are usually declared as an array of pointers to one dimension arrays GDB is the GNU Debugger. Inspect variables, breakpoints, watchpoints, step by step execution The C library is a standard ANSI library String Manipulations, File Access, Console I/O, Memory Allocation 27