ScholarQuill logoScholarQuillUniversity Notes
  • Notes
  • Past Papers
  • Blogs
  • Todo
Login
ScholarQuill logoScholarQuillUniversity Notes
Login
NotesPast PapersBlogsTodo
More
SubjectsDiscussionCGPA CalculatorGPA CalculatorStudent PortalCourse Outline
About
About usPrivacy PolicyReportContact
Notes
Past Papers
Blogs
Todo
Analytics
    Current Subject
    🧩
    Computer Organization and Assembly Language
    COMP2118
    Progress0 / 35 topics
    Topics
    1. Introduction to Computer Systems2. Information is Bits + Context3. Programs are Translated by Other Programs4. Understanding Compilation Systems5. Processors Read and Interpret Instructions6. Caches Matter7. Storage Devices Form a Hierarchy8. The Operating System Manages the Hardware9. Systems Communicate Using Networks10. Representing and Manipulating Information11. Information Storage12. Integer Representations13. Integer Arithmetic14. Floating Point15. Machine-Level Representation of Programs16. A Historical Perspective17. Program Encodings18. Data Formats19. Accessing Information20. Arithmetic and Logical Operations21. Control22. Procedures23. Array Allocation and Access24. Heterogeneous Data Structures25. Understanding Pointers26. Using the GDB Debugger27. Out-of-Bounds Memory References and Buffer Overflow28. x86-64: Extending IA-32 to 64 Bits29. Machine-Level Representations of Floating-Point Programs30. Processor Architecture31. The Y86 Instruction Set Architecture32. Logic Design and the Hardware Control Language (HCL)33. Sequential Y86 Implementations34. General Principles of Pipelining35. Pipelined Y86 Implementations
    COMP2118›Using the GDB Debugger
    Computer Organization and Assembly LanguageTopic 26 of 35

    Using the GDB Debugger

    8 minread
    1,286words
    Intermediatelevel

    Using the GDB Debugger

    GDB (GNU Debugger) is a powerful tool used for debugging programs written in languages like C and C++. It allows developers to examine and manipulate the execution of a program, helping to identify and fix bugs, inspect variable values, trace function calls, and control program flow. GDB is a crucial tool for anyone working with assembly, C, or C++ in low-level programming and computer organization.

    In the context of Computer Organization and Assembly Language (COAL), GDB is essential for debugging assembly programs, especially when you need to inspect the contents of registers, step through assembly instructions, or track down issues with memory management.

    1. Basic Overview of GDB

    GDB lets you:

    • Run programs step by step.
    • Set breakpoints to pause execution at specific points.
    • Inspect and modify program variables.
    • Examine memory and registers.
    • Trace the call stack and function calls.
    • View assembly code and control execution flow.

    2. Starting GDB

    To start debugging a program with GDB, you need to first compile your program with debugging information enabled. This can be done by using the -g flag with the compiler (e.g., GCC for C programs). This flag includes debugging symbols that help GDB understand the structure of your program.

    For example, to compile a C program:

    gcc -g program.c -o program
    

    Then, you can start GDB with the following command:

    gdb ./program
    

    This launches GDB and loads your program, allowing you to interact with it via GDB commands.

    3. Basic GDB Commands

    Once you're inside GDB, there are several useful commands for interacting with your program. Let’s look at some of the most commonly used commands.

    A. Running the Program

    • To start running the program in GDB, use the run command:
      (gdb) run
      
      This will start executing your program from the beginning. If your program takes arguments, you can pass them after the run command:
      (gdb) run arg1 arg2
      

    B. Setting Breakpoints

    • Breakpoints allow you to pause the execution of the program at specific locations, such as a function or a particular line of code. To set a breakpoint at a function:
      (gdb) break function_name
      
    • To set a breakpoint at a specific line number:
      (gdb) break filename.c:line_number
      
      For example:
      (gdb) break main.c:25
      
    • You can also list all current breakpoints:
      (gdb) info breakpoints
      

    C. Stepping Through the Program

    • Once a breakpoint is hit, you can step through your program line by line.
      • Step: Executes the current line of code and steps into function calls.
        (gdb) step
        
      • Next: Executes the current line but steps over function calls (i.e., does not enter functions).
        (gdb) next
        

    D. Inspecting Variables and Registers

    • To examine the value of a variable:

      (gdb) print variable_name
      

      For example:

      (gdb) print x
      
    • To examine a register (important for assembly language programs):

      (gdb) info registers
      

      This command will display the contents of all registers (e.g., eax, ebx, etc.).

    • If you want to print a specific register:

      (gdb) print $eax
      

    E. Examining Memory

    You can examine memory directly in GDB using the x command. For example, to examine 4 bytes of memory at a specific address:

    (gdb) x/4xb 0xaddress
    
    • x tells GDB to examine memory.
    • 4 means you want to inspect 4 units.
    • x means examining the memory as bytes (you can use other formats like h for halfwords, w for words).
    • 0xaddress is the memory address you want to examine.

    F. Modifying Variables

    You can modify the value of a variable during debugging using the set command. For example, to set the variable x to 10:

    (gdb) set variable x = 10
    

    If you want to change the value of a register, use:

    (gdb) set $eax = 42
    

    G. Continuing Execution

    Once you have hit a breakpoint and inspected or modified values, you can continue the execution of the program with:

    (gdb) continue
    

    H. Exiting GDB

    To exit GDB when you are done debugging, use:

    (gdb) quit
    

    4. Advanced GDB Features

    A. Disassembling Code

    When debugging assembly programs, you can disassemble your code in GDB to view the corresponding assembly instructions. To disassemble the current function:

    (gdb) disassemble
    

    To disassemble a specific function:

    (gdb) disassemble function_name
    

    B. Backtrace (Stack Trace)

    If your program crashes or you want to trace the call stack to see how you arrived at a particular point in the program, use the backtrace or bt command:

    (gdb) backtrace
    

    This will show the sequence of function calls that led to the current location, which is especially helpful in debugging segmentation faults or crashes.

    C. Watchpoints

    Watchpoints are like breakpoints, but they pause the program whenever a specific variable changes. To set a watchpoint:

    (gdb) watch variable_name
    

    For example:

    (gdb) watch x
    

    This will stop the program whenever the variable x is modified.

    5. Using GDB for Assembly Debugging

    When debugging assembly programs, GDB is especially powerful because it allows you to step through assembly instructions and inspect the contents of registers.

    • Disassembling: Use disassemble to view the assembly instructions.
    • Inspect Registers: Use info registers to check the contents of registers like eax, ebx, etc.
    • Stepping Through Assembly: Use stepi or nexti to step through the program one instruction at a time. This is very useful when debugging assembly-level code to identify where things go wrong.
      (gdb) stepi  ; Step by one instruction
      (gdb) nexti  ; Step over one instruction
      

    6. Setting Up GDB for Assembly Code

    When working with Assembly Language, GDB can be incredibly useful to inspect how your Assembly instructions are executing, check the values in registers, and monitor how memory is being accessed.

    Example 1: Debugging a Simple Assembly Program

    Let's say you have a simple Assembly program in x86 architecture that adds two numbers:

    section .data
        num1 db 10
        num2 db 20
    
    section .text
        global _start
    
    _start:
        ; Load values into registers
        MOV AL, [num1]    ; Load num1 into AL
        ADD AL, [num2]    ; Add num2 to AL
        MOV [num1], AL    ; Store the result back into num1
    
        ; Exit the program
        MOV EAX, 1        ; SYS_exit system call
        MOV EBX, 0        ; Exit status
        INT 0x80          ; Invoke system call
    

    Step-by-Step Debugging with GDB

    1. Assemble the Code:

      Assemble the program and create an executable.

      nasm -f elf32 my_program.asm -o my_program.o
      ld -m elf_i386 -s -o my_program my_program.o
      
    2. Start GDB: Open the program with GDB.

      gdb ./my_program
      
    3. Set Breakpoints: Set a breakpoint at the entry point, or at specific lines in the code (e.g., before the ADD instruction).

      (gdb) break _start
      
    4. Run the Program: Start running the program inside GDB.

      (gdb) run
      
    5. Inspect Registers: Once the breakpoint is hit, you can inspect the CPU registers to see the state of the program.

      (gdb) info registers
      

      This will show you the values of all the registers, including EAX, which stores the result of the addition.

    6. Step Through the Code: Use the next or step commands to execute the instructions one by one and observe the behavior.

      (gdb) step
      
    7. Print Variable Values: You can also print values stored in memory (such as the result in num1).

      (gdb) print $al      # Print the value in the AL register
      (gdb) print num1     # Print the value at the memory address of num1
      
    8. Continue Execution: If you're satisfied with the current state, you can resume execution.

      (gdb) continue
      
    9. Exit GDB: Once you've finished debugging, you can exit GDB.

      (gdb) quit
      

    7. Conclusion

    GDB is an invaluable tool for debugging assembly language programs, C programs, and other low-level code. By using GDB, you can inspect and modify registers, step through assembly instructions, examine memory, set breakpoints, and even modify variables during execution. Whether you're debugging simple logic errors or complex memory issues, GDB offers the necessary functionality to analyze and fix bugs in your code efficiently.

    Previous topic 25
    Understanding Pointers
    Next topic 27
    Out-of-Bounds Memory References and Buffer Overflow

    Past Papers

    Open this section to load past papers

    Click on Show Past Papers to see past papers.
    On This Page
      Reading Stats
      Est. reading time8 min
      Word count1,286
      Code examples0
      DifficultyIntermediate