Error Handling and Debugging in C
Error handling is a critical aspect of any robust C program. C provides several mechanisms for error handling and debugging, including return codes, errno, perror(), strerror(), and debugging tools like GDB.
1. Error Codes and Return Values
In C, functions typically indicate success or failure through return values. A function may return 0 for success and a non-zero value (often -1) for failure. These return values can be checked to handle errors gracefully.
Example: Checking Return Values
#include <stdio.h>
int divide(int a, int b) {
if (b == 0) {
return -1; // Error: Division by zero
}
return a / b;
}
int main() {
int result = divide(10, 0);
if (result == -1) {
printf("Error: Division by zero\n");
} else {
printf("Result: %d\n", result);
}
return 0;
}Explanation:
- The
divide()function returns-1if the denominator is zero, signaling an error. - The error is handled by checking the return value in the
main()function.
Output:
Error: Division by zero2. errno, perror(), and strerror()
In addition to return values, C provides the errno variable, which stores error codes set by system calls and library functions when an error occurs. The perror() and strerror() functions are used to display human-readable error messages.
Using errno
errno is a global variable that stores the error code when a function encounters an error.
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main() {
FILE *file = fopen("non_existent_file.txt", "r");
if (file == NULL) {
// Print the error code and message
printf("Error code: %d\n", errno);
printf("Error message: %s\n", strerror(errno));
}
return 0;
}Explanation:
fopen()fails because the file does not exist, settingerrnoto the corresponding error code.strerror(errno)returns a human-readable string describing the error.
Output:
Error code: 2
Error message: No such file or directoryUsing perror()
perror() is a simpler way to print an error message directly based on errno.
#include <stdio.h>
int main() {
FILE *file = fopen("non_existent_file.txt", "r");
if (file == NULL) {
// Print the error message using perror
perror("File error");
}
return 0;
}Explanation:
perror()automatically prints an error message corresponding to the current value oferrno.
Output:
File error: No such file or directory3. Debugging with GDB
GDB (GNU Debugger) is a powerful tool for debugging C programs. It allows you to step through your code, inspect variables, set breakpoints, and more.
Basic GDB Commands
-
Compile with debugging symbols: Add the
-gflag when compiling.gcc -g program.c -o program -
Start GDB: Run GDB on your executable.
gdb ./program -
Set a breakpoint: Pause execution at a specific line.
(gdb) break main -
Run the program:
(gdb) run -
Step through the code: Use
nextto execute the next line of code.(gdb) next -
Inspect variables: Print the value of variables.
(gdb) print var_name -
Continue execution: Resume program execution.
(gdb) continue -
Quit GDB:
(gdb) quit
Example: Using GDB to Debug a Segmentation Fault
Consider the following buggy code:
#include <stdio.h>
int main() {
int *ptr = NULL;
*ptr = 10; // Dereferencing a null pointer (causes segmentation fault)
return 0;
}Debugging Steps:
-
Compile the code with debugging symbols:
gcc -g segfault.c -o segfault -
Run the program with GDB:
gdb ./segfault -
Set a breakpoint at
main():(gdb) break main -
Run the program:
(gdb) run -
Step through the code using
nextand identify the line causing the segmentation fault. -
Inspect the value of
ptrto see that it isNULL.
GDB Output Example:
Program received signal SIGSEGV, Segmentation fault.
0x00000000004004c7 in main () at segfault.c:6
6 *ptr = 10;
(gdb) print ptr
$1 = (int *) 0x0Explanation:
- GDB shows that the segmentation fault occurred at line 6 (
*ptr = 10). - Inspecting
ptrwithprint ptrreveals thatptrisNULL, which causes the crash.
4. Diagram for Error Handling and Debugging
5. Recap
- Error Codes and Return Values: Functions indicate success or failure with return values.
- errno: Stores error codes set by functions when errors occur.
- perror() and strerror(): Functions for printing human-readable error messages.
- GDB: A powerful tool for debugging C programs.
These tools and techniques provide a structured way to handle errors and debug issues in C programs, ensuring better code reliability and maintainability.