当前位置: 首页 > news >正文

gcc的使用,调试工具gdb的使用

gcc编译

gcc编译可以分为四个步骤,预处理、编译、汇编、链接。

  • 预处理命令: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命令一些参数

  • 指定头文件目录
gcc -I./headfile hello.c -o hello.out
  • 编译时添加调试语句
    需要使用gdb调试代码时需要添加该参数
gcc hello.c -o a.out -g
  • 编译优化
    n取值范围是[0,3],n越大优化越多
gcc -On hello.c -o a.out
  • 显示所有警告信息
gcc -Wall hello.c -o a.out
  • 动态添加宏定义
    下面就是添加了一个名为OPEN的宏
gcc -D OPEN hello.c 

静态库和动态库

使用gcc -c main.c会生成一个main.o文件,查看该文件的elf文件头信息可以发现该文件的类型为可重定向目标文件,这类文件在链接之后会变为可执行文件。
在这里插入图片描述
在链接时使用静态库需要指明静态库的名称
例如我需要使用libm.a这个静态库(包括一些数学函数),就要使用以下命令,lib**.a对应-lxx

gcc -static -o main.out main.o -lm 

目前编译时会默认使用动态链接,动态链接是不会将动态库打包到二进制文件中的,静态链接会将静态库打包到二进制文件中,因此静态链接生成的可执行文件一般体积较大。动态库后缀为so,例如libm.so,静态库后缀为a,例如libm.a。

gdb调试程序

  • 在使用gdb调试程序时首先要保证文件是可调试的。在编译时添加-g参数。
gcc -o main.gdb main.c -g
  • 调试无参程序
gdb 可执行文件名 #进入gdb命令模式
(gdb) run  #运行程序 
  • 调试有参程序
gdb 可执行文件名 #进入gdb命令模式
(gdb) set name kunkun # 设置名为name的参数的值为kunkun
(gdb) run  #运行程序 
  • 调试core文件
    程序在运行时出现异常终止或者崩溃,操作系统会将程序当时的内存状态信息保存在core文件中,用于后续的排错,这个过程称为core dump。
ulimit -c # 检查是否可以生成core文件,返回值为0代表无法生成core文件,core文件中可能会保存一些私密信息,有泄露的风险
ulimit -c 10 # 开启生成core文件的功能,设置大小为10块( 一个块就是0.5kB)

对于有core文件生成的程序,使用以下命令调试得到错误出现的位置

gdb 可执行文件名 core文件名 
(gdb) bt #显示异常出现的位置

gdb中断点的使用

  • 查看已有的断点
info breakpoints
  • 添加断点
b n # 在第n行添加断点
b function_name # 在函数添加断点
break main_out.gdb:n if b==0 #在第n行如果b的值为0就添加一个断点
rbreak file:regex #根据正则表达式的规则设置断点,作用于符合正则表达式的函数名
tbreak file:n #在第n行设置临时断点,使用一次后删除
ignore breaknum times #设置跳过断点次数,breaknum:断点的序号,可以使用info breakpoints命令得到序号,times:跳过该断点的次数。
watch b #根据表达式值产生断点,当a变化时会打印a的变化数据
  • 禁用和启动断点
disbale/enable #禁用/启动所有断点
disable/enable breaknum #禁用/启动断点号为breaknum的断点
  • 删除断点
clear #删除当前行所有的breakpoints
clear linenum #删除linenum行的断点
clear functionname#删除函数上的断点
delete #删除所有的breapoints,watchpoints,catchpoints
delete breaknum #删除指定断点号的断点

gdb调试程序命令

  • run:执行程序,到断点中断。
  • c/continue:继续运行程序到下一个断点停止
  • n/next:运行下一条语句
  • p/print 变量名:打印变量
  • p/print *node@n:打印指针指向的数据, n代表长度,如果不加@n只会打印数组第一个数据。
  • set $index=0;print node[$index++]:按照索引打印数组
  • 按照指定格式打印数据(正斜杠+字母,例如/t代表二进制格式)
    在这里插入图片描述
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十六进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
c 按字符格式显示变量。
f 按浮点数格式显示变量。
http://www.lryc.cn/news/20482.html

相关文章:

  • Python变量的定义和使用
  • SSM框架-AOP概述、Spring事务
  • 一文搞定Android Vsync原理简析
  • 第八届蓝桥杯省赛 C++ B组 - K 倍区间
  • UDP与TCP协议
  • rosbag相关使用工具
  • 数据结构与算法—栈stack
  • 【学习笔记】[ARC150F] Constant Sum Subsequence
  • Node.js实现大文件断点续传—浅析
  • Spring Cloud Nacos源码讲解(九)- Nacos客户端本地缓存及故障转移
  • MySQL知识点小结
  • MySQL关于NULL值,常见的几个坑
  • OllyDbgqaqazazzAcxsaZ
  • Elasticsearch7.8.0版本进阶——自定义分析器
  • spring事务-创建代理对象
  • Linux 配置NFS与autofs自动挂载
  • 【编程入门】应用市场(Python版)
  • 异常信息记录入库
  • Spring Batch 高级篇-分区步骤
  • ES数据迁移_snapshot(不需要安装其他软件)
  • 【Vue3 第二十章】异步组件 代码分包 Suspense内置组件 顶层 await
  • 「媒体邀约」四川有哪些媒体,成都活动媒体邀约
  • @Autowired和@Resource的区别
  • Linux系列:glibc程序设计规范与内存管理思想
  • Redis 集群
  • EF 框架的简介、发展历史;ORM框架概念
  • 注解原理剖析与实战
  • 《STL源码剖析》理解之将类成员函数和for_each等算法结合
  • 如何构建应用标准化体系
  • 【RabbitMQ笔记03】消息队列RabbitMQ七种模式之WorkQueues工作队列模式