gcc编译,静态/动态库,gdb调试命令,makefie操作

1.gcc编译

在这里插入图片描述
在这里插入图片描述
gcc -文件名
系统会自动对编译文件进行命名为a.out
命令:gcc hello.c -o hello1 -g
用于调试gdb使用
命令:gcc hello.c -D HELLO
用于编译时定义宏
#ifdef
#define HI 20
#endif
在这里插入图片描述

2.静态库/动态库

静态库:对时间要求较高,对空间要求较低
动态库:对时间要求较低,对空间要求较高
在这里插入图片描述
在这里插入图片描述

静态库制作:
-o只是起到重命名的作用
1.将.c文件生成.o文件
gcc -c add.c -o add.o
2.ar rcs lib库名.a add.o sub.o

静态库使用:
链接时需要增加进去
gcc test.c lib库名.a -o test//顺序不能错
在这里插入图片描述
gcc test.c 静态库.a -o test.out -I 目录下文件名
//既要做静态库还要做头文件.h
在这里插入图片描述
在这里插入图片描述

2.使用gcc -shared 制作动态库
gcc -shared -o lib库名.so add.o sub.o div.o
4.执行程序,./a.out出错!!!
原因:
动态链接器:工作于程序运行阶段,工作时需要提供动态库所在目录位置
通过环境变量:export LD_LIBRARY_PATH=动态库路径
./a.out 成功!!!
解决方法:
(1)临时生效: 由于环境变量是伴随着进程生效的,一旦进程关闭,即环境变量失效
(2) 永久生效:需要改变 ~/.bashrc目录
改完需要运行配置文件,使其生效。
source .bashrc
. .bashrc
(3)拷贝自定义动态库到 /lib(标准c库)
(4)修改配置文件 在这里插入图片描述在这里插入图片描述
在这里插入图片描述
ldd a.out:查看当前执行文件所引用的所有动态库
数据段合并:

在这里插入图片描述

3.gdb调试

gdb用于调试代码的逻辑错误,不检查语法错误

K:用于跳转到man系统函数
*/# :用于跳转到自定义函数

3.1gdb调试过程以及命令:

(1)gcc gdbtest.c -o gdbtest.out -g生成包含调试信息的文件
(2)运行 gcc gdbtest.out
(3)list回车或者l回车
(4)依次l显示全程序
(5)设置断点 break/b -行数 执行 run/r 运行到断点所在位置
(6)next/n step/s 单步或者下一步执行
如果下一步是函数:n是越过函数 s是进入函数
注意了,如果函数是库函数或第三方提供的函数,用s也是进不去的,因
为没有源代码,如果是您自定义的函数,只要有源码就可以进去。
这时候可以使用 until 行号调到对应位置
(6.1)使用finish 可以结束当前函数调用,返回函数调用点,可以结束库函 也可以结束自己定义的函数
(7)print/p 显示变量的值
(8)continue 程序运行到断点后续指令,如果没有断点,运行到结束
(9)quit:t退出gdb当前调试

3.2其他gdb调试命令:

(1)段错误:直接run 即会显示错误行位置
(2)start:gdb进来后 直接 start 程序会从程序第一行执行。然后n往后执行
(3)set args: 设置输入参数 int main(int argc,char * argv[])
(4)info b:查看断点信息
(5)run 字符串1,字符串2…设置main函数命令行参数
(6) b 20 if i=5 :条件断点,设置断点位置为i==5
(7)ptype j :查看变量的类型 例如:type =int
(8)变量有作用域的,main函数的变量在函数中不能访问
(9)bt :查看栈帧的列表,不同的函数为不同的栈帧
(10)frame 1:根据栈帧编号切换到相应的栈帧,栈帧和函数调用一一对应
(11)diaplay:一直跟踪变量i,j,k的值,即:display i
显示跟踪i,j,k的值

4 gdb调试-多进程,多线程,运行中的程序

4.1运行中的程序

(1)利用bt 可以查看函数调用栈
(2)利用gdb -p 进程号可以调试正在运行中的程序

4.2多线程调试

(1)调试父进程:set follow-fork-mode parent(缺省),默认子进程运行,父进程等待调试
(2)调试子进程:set follow-fork-mode child,设置后,子进程等待调试,父进程跑起来运行
(3)设置调试模式:set detach-on-fork offf
(4)查看调试进程,info inferiors,配合(3)一起使用
(5)切换当前调试进程:inferior 进程 id
在这里插入图片描述

4.3多进程调试

  1. 查看当前运行的轻量级进程:ps -aL |grep 进程名
  2. 查看主进程和新进程的关系:pstree -p 主线程id
    在这里插入图片描述
  3. info b查看断点信息
  4. info pthreads:查看当前有多少线程
    在这里插入图片描述
  5. thread ID 切换到线程ID
  6. 只运行当前线程 set scheduler-locking on,其他线程挂起
  7. 线程全部运行,set scheduler-locking off
  8. 指定某线程执行某gdb命令:thread apply 线程id cmd
    thread apply all cmd
    多线程调试代码示例
#include<pthread.h>
#include<stdio.h>
#include<unistd.h>

void* pth1_main(void* arg);
void* pth2_main(void* arg);
int i=0;
int j=0;
int main()
{  
   pthread_t pthid1,pthid2;
   if(pthread_create(&pthid1,NULL,pth1_main,(void*)0)!=0)
   {  
      printf("pthread1_create fail\n");
      return -1;
   }
   if(pthread_create(&pthid2,NULL,pth2_main,(void*)0)!=0)
   {  
      printf("pthread2_create fail\n");
      return -1;
   }
   printf("111\n");
   pthread_join(pthid1,NULL);
   printf("222\n");
   pthread_join(pthid2,NULL);
   return 0;
}
void* pth1_main(void* arg)
{
    for( ;i<100;i++)
    {
          printf("i=%d\n",i);
          sleep(1);
    }
    pthread_exit(NULL);
}
void* pth2_main(void* arg)
{
    for(;j<100;j++)
    {
          printf("j=%d\n",j);
          sleep(1);
    }
    pthread_exit(NULL);

}

5.makefile操作

5.1 一个规则:

    目标:依赖条件
          (一个tab缩进命令)命令
    1.目标时间必须晚于依赖条件的时间,否则更新目录
     all:指定makefile的终极目标

5.2 2个函数

src= ( w i l d c a r d . / ∗ . c ) : 匹 配 当 前 目 录 下 所 有 . c 的 文 件 , 将 文 件 名 组 成 列 表 赋 值 给 变 量 s r c o b j = (wildcard ./*.c):匹配当前目录下所有.c的文件,将文件名组成列表赋值给变量 src obj= (wildcard./.c):.csrcobj=(patsubst %.c,%.o,$(src)):将参数3中,包含参数1的部分 ,替换为参数2
make clean:
-rm -rf $(obj) a.out
删除a.out和obj变量
make clean -n:模拟删除下一步,看是否删除正确
make clean:删除clean行的命令

5.3 3个变量

$@:在规则命令中,表示规则中的目标
$^:在规则的命令中,表示所有依赖条件
$<:在规则的命令中,表示第一个依赖条件
模式规则
伪目标:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alex1_Code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值