DEBUGGING TECHNIQUES: --------------------- -> Delta Debugging: ++++++++++++++++ It is a technique like binary search, where we can decrease the section under analysis to find bugs. Like, we can use multiple breakpoints to the program and see where the program faces issue and when it faces. It could face the issue before some breakpoint could be reached or after some breakpoints are encountered. This way we can reduce our search space and section of analysis. -> Assertion: ++++++++++ assert(): It check if the assumption which is passed as an argument is true. If it isn't, the program will Abort and core dumped. This is for runtime check and the program is part of C library. To use it we need #include statement in C++ program. static_assert(): It check the assumption at compile time and throw compilation error if the assertion fails. This is helpful where we can evaluate variable as constant expression using constexpr keywords, which could help in static assertion failure. -> Investigating Code by Calling functions within GDB: +++++++++++++++++++++++++++++++++++++++++++++++++++ * We can call a function from GDB when haven't reached the point where we execute the function. We can do function call from GDB itself. We can use... Command: (gdb)call ( .... ) -> Attaching the Debugger to a Running Process: ++++++++++++++++++++++++++++++++++++++++++++ To attach a running to process to a gdb. Command: $gdb -p We can get the process id using below command: $ps aux | grep To Detach a process and let it run, we can use command: (gdb)detach -> Core Dumped -- and how to look at those files. ++++++++++++++++++++++++++++++++++++++++++++++ When the program crashes and it throws a message: $Segmentation fault(core dumped) This means that the accessing illegal memory location and the particular message in parenthesis means that the kernel took the snapshot of the VAS of the program and saved it in a "core" file. However, this "core" file is only allowed to be generated when the system is configured to allow this operation. To check if the core file is allowed to be generated or not we can use... Command: $ulimit -a This -a flag display all the limits of the system like size of core file allowed to be generated, maximum size of the file allowed, etc. To particularly see the core file size that is allowed, we can use... Command: $ulimit -c If it display 0, then core file is now allowed to be generated. In order to allow the core files to be generated, we need to set the allowed core file size, by using following command: Command: $ulimit -c Here, if : unlimited, then there is no restriction in the allowed core file size which will be generated. It will generate the core file, but now in order to get the core file we a utility tool called "systemd-coredump" Install it using package manager. To know about the core dump that occured, we can use command of this utility. $coredumpctl It will display all the core dump that has occured till now To display some further detail and location of the coredump that is being store we can use command: Command: $coredumpctl dump Note: The core dump file generated is a snapshot of the memory when the program crashed. We can open the coredump file with gdb using $coredumpctl gdb However, with core dump, we cannot move the execution of the program as it is not running, we can only inspect the state of the program when it faced the issue. In order to generate core file in the same directory as where the executable is present we need to do some configuration. After that when the core file is generated in the same directory as where the executable is present. We can run the core file with executable with debug symbol by running the below command: Command: $gdb ./ -> Core Dumped - gcore for running process: ++++++++++++++++++++++++++++++++++++++++ To generatea core file for running process. We can use gcore, to use it: Command: $gcore Run the generated core file with executable with debug symbols To load the generated core file to gdb use command: $gdb -c Note that since core file alone won't show the functions and symbols,etc. Load the file with executable compiled with debug symbols. -> Examining Memory in GDB (also hex): +++++++++++++++++++++++++++++++++++ To examine the data structure using examine command. we can use command: Command; (gdb)x & We get the output in format as shown below:
: x/nfu * n -> The repeat count is a decimal integer, the default is 1. It specifies how much memory (counting by units u) to display. If a negative number is specified, memory is examined backward from addr. * f -> The display format is one of the formats used by print('x', 'd', 'u', 'o', 't', 'a', 'c', 'f', 's'), 'i'(for machine instructions) and 'm'(for displaying messages). The default is 'x'(hexadecimal) initially. The default changes each time you use either x or print. * u -> The unit size is any of b Bytes. h Halfwords (two bytes). w Words (four bytes). This is the initial default. g Giant words (eight bytes)