• 【计算机系统基础1】gdb、gcc简易使用指南


    1. 基本实验工具的使用

    1.1GCC

    在IA-32+LINUX平台

    在IA-32+LINUX平台上,编译,调试和运行C语言

    • 为了把C语言源程序编译成IA-32机器指令,X86-64位计算机系统需要先运行下列命令:

      sudo apt-get install build-essential module-assistant
      sudo apt-get install gcc-multilib g++-multilib
      

    基本的GCC 命令

    • -E:翻译带 # 的文件,将头文件内容生成到源文件中。

    • -S:生成汇编文件。

    • -C:生成链接文件,就是组装的模块。

    image-20220527103628467

    • gcc -E hello.c -o hello.i
      gcc -S hello.i -o hello.s
      gcc -C hello.s -o hello.o
      gcc hello.o -o hello
      

    一些其他选项

    gcc -O0 -m32 -g hello.c -o hello
    
    • -O0: 不用编译优化
    • -m32:编译成 x86-32 位的指令
    • -g:带调试信息

    1.2objdump

    • 作用:反汇编二进制的目标文件
    objdump -S gdbtest.o > gdbtesto.txt
    objdump -S gdbtest > gdbtest.txt
    
    • -s:在反汇编后的内容中添加源代码

    image-20220527154011432

    image-20220527154159949

    1.3gdb

    启动gdb 调试工具

    启动gdb 调试工具,加载要被调试的可执行文件

    # 启动方式1:gdb [可执行文件名]
    gdb gdbtest
    # 启动方式2:1.gdb 2.file [可执行文件名]
    gdb
    file gdbtest
    # 查看源代码
    l
    

    设置断点

    # 在 main 函数的入口处设置断点
    break main # 或者 b main
    # 在源程序 gdbtest.c 的第 3 行处设置断点
    break gdbtest.c:3
    

    启动程序运行

    # 启动程序运行,程序会在断点处停下
    run # 或者 r 
    

    查看程序运行时的当前状态

    • 程序的当前断点位置

      eip 寄存器:保存一下条要执行的指令的地址

      # i r:显示所有寄存器的内容
      # i r eip: 只显示寄存器 eip 的内容,64位是rip
      i r eip
      
    • 通用寄存器内容

      i r eax ebx ecx edx #(或i r) 显示通用寄存器内容
      
    • 查看变量的地址

      p &a # 查看a的地址
      
    • 存储器单元内容

      x/8xb 0xffffd2bc 
      x/2xw 0xffffd2bc
      

      各部分含义解释:

      • image-20220527172650195

      • image-20220527172712212

      • image-20220527172732913

      • image-20220527172802817

      • image-20220527172814461

      语句含义:

      • image-20220527172854572
      • image-20220527173027977
    • 栈帧信息

      说明: IA-32用栈来支持过程的嵌套调用,过程的入口参数、返回地址,被保存寄存器的值、被调用过程中的非静态局部变量等都会被保存在栈中。
      栈帧:系统为每个执行的过程分配一个栈空间。

      类似于游泳池储物柜的申请和返还

      image-20220527173449423

      当前栈帧范围:

      i r esp ebp # esp栈顶指针、ebp 栈底指针
      

      当前栈帧字节数:

      y = R[ebp] - R[esp] + 4

      举例:

      image-20220527173839206

      显示当前栈帧内容:

      x/yxb $esp # y: R[ebp]-R[esp]+4的值, 栈帧起始地址是esp指向的单元地址;
      
      x/zxw $esp # z=y/4, 显示从esp指向的地址开始。
      

    继续执行下一条指令或语句

    si # 执行一条机器指令
    s  # 执行一条C语句
    

    退出

    quit
    

    ------------恢复内容结束------------

  • 相关阅读:
    ROS标定海康威视摄像头
    kafka消息中间件
    自学黑客(网络安全),一般人我劝你还是算了吧
    强大而灵活的python装饰器
    大一学生Web课程设计 美食主题网页制作(HTML+CSS+JavaScript)
    Java 7 生命周期结束
    大厂晋升指南:材料准备,PPT 写作和现场答辩
    【Spring Boot】Spring Boot 统一功能处理
    架构升级实践
    详细Ubuntu16~20TLS安装NVIDIA驱动教程
  • 原文地址:https://www.cnblogs.com/zyllee/p/16440055.html