Gitlib Gitlib
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)

Ravior

以梦为马,莫负韶华
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)
  • PHP

  • Golang

  • Python

  • Javascript

  • 其他语言

    • Smali语法学习
    • Lua语法总结
    • C语言学习·编译过程
      • 编译参数
      • 静态库
        • 创建静态库
        • 使用静态库
        • 优缺点
      • 动态库
        • 创建动态库
        • 使用动态库
        • 优缺点
        • GDB调试
      • 生成调试程序
      • 查看代码
      • 设置断点
      • 执行程序
      • 单步调试
      • 查看变量
      • 追踪变量
      • 多进程调试
      • makefile
        • 普通版
        • 自动变量
        • makefile函数
        • 静态模型
  • 编程语言
  • 其他语言
Ravior
2015-10-01
目录

C语言学习·编译过程

# 预处理器 cpp, 展开通文件, 宏替换, 去掉注释
gcc -E hello.c -o hello.i
# 编译器 gcc, c文件 -> 汇编文件
gcc -S hello.i -o hello.s
# 汇编器 as, 汇编文件 -> 二进制文件
gcc -c hello.s -o hello.o
# 链接器 ld, 将函数库中的代码组合到目标文件中
gcc hello.o -o hello
1
2
3
4
5
6
7
8

# 编译参数

  • 指定宏
#include <iostream>
int main() {
#ifdef DEBUG
    std::cout << "hello world\n";
#endif
    return 0;
}Copy to clipboardErrorCopied
1
2
3
4
5
6
7
gcc sum.c -o sum -D DEGUBCopy to clipboardErrorCopied
1
  • 输出警告信息
gcc sum.c -o sum -WallCopy to clipboardErrorCopied
1
  • 优化代码
# 优化等级分为o1、 o2、 o3
gcc sum.c -o sum -o3 Copy to clipboardErrorCopied
1
2
  • 生成调试信息
gcc sum.c -o sum -g
1

# 静态库

# 创建静态库

// include/head.h 
#ifndef HEAD_H
#define HEAD_H
int sum(int, int);
int mul(int, int);
#endifCopy to clipboardErrorCopied
1
2
3
4
5
6
// ./sum.c
#include "head.h"
int sum(int a, int b) {
    return a + b;
}
// ./mul.c
#include "head.h"
int mul(int a, int b) {
    return a * b;
}Copy to clipboardErrorCopied
1
2
3
4
5
6
7
8
9
10

生成.o文件

gcc -c *.c -I includeCopy to clipboardErrorCopied
1

打包静态库

ar rcs lib/libtest.a *.oCopy to clipboardErrorCopied
1

# 使用静态库

// ./main.c
#include "head.h"
#include "stdio.h"
int main()
{
    int a = sum(2, 4);
    int b = mul(2, 4);
    printf("%d %d\n", a, b);
    return 0;
}Copy to clipboardErrorCopied
1
2
3
4
5
6
7
8
9
10

使用静态库编译文件

gcc main.c lib/libtest.a -I include -o main
gcc main.c -I include -L lib -l test -o mainCopy to clipboardErrorCopied
1
2

查看查看文件中符号

nm mainCopy to clipboardErrorCopied
1

# 优缺点

静态库在使用的时候,会根据程序中用的到函数,将对应函数所在的.o打包到程序中。

  • 发布程序的时候,不需要提供对应的库。
  • 加载库的速度快

将这些库打包到可执行文件中同时也会造成:

  • 可执行程序的体积大
  • 库发生改变,需要重新编译程序

# 动态库

# 创建动态库

生成与位置无关的目标文件

gcc -fPIC -c *.c -I includeCopy to clipboardErrorCopied
1

打包动态库**.so**

gcc -shared -o lib/libtest.so *.o -I includeCopy to clipboardErrorCopied
1

# 使用动态库

gcc main.c lib/libtest.so -I include -o main
gcc main.c -L lib -l test -I include -o mainCopy to clipboardErrorCopied
1
2

在使用第二种方法,执行可执行文件时,会出现找不到路径的问题,这是因为动态库在加载的时候,需要动态链接器进行加载,可以适应ldd命令查看可执行程序需要的动态库。

动态链接器在加载库的时候,根据环境变量中的目录惊进行查找,可以添加自己的目录到环境变量中。

动态库的搜索路径的顺序

  • 编译目标代码时指定的动态库搜索路径
  • 环境变量LD_LIBRARY_PATH指定的动态库搜索路径
  • 配置文件/etc/ld.so.conf中指定的动态库搜索路径
  • 默认的动态库搜索路径/lib和/usr/lib

添加到LD_LIBRARY_PATH,这种方法是临时的。

export LD_LIBRARY_PATH=./lib:$LD_LIBRARY_PATHCopy to clipboardErrorCopied
1

可以将命令写到bash配置文件里面,这样每次加载shell之前,都会配置目录。

vim ~/.bashrc
export LD_LIBRARY_PATH=./lib:$LD_LIBRARY_PATHCopy to clipboardErrorCopied
1
2

另外也可以配置ld.so.conf。

sudo vim /etc/ld.so.conf
/home/user/linux/lib
sudo ldconfig -vCopy to clipboardErrorCopied
1
2
3

查看可执行文件依赖的动态库

ldd appCopy to clipboardErrorCopied
1

# 优缺点

动态库只是在内存地址的共享库中标记,在程序运行时才加载。

  • 可执行程序体积小
  • 动态库更新,不需要重新编译
  • 发布程序需要将库提供给用户
  • 动态库没有打包应用程序中,加载速度相对慢

# GDB调试

全称 功能
list l 显示多行源代码
break b 设置断点
delete d 删除断点
info i 描述程序的状态
run r 开始运行程序
display disp 跟踪查看某个变量,每次停下来都显示它的值
undisplay 停止追踪
step s 执行下一条语句,如果该语句为函数调用,则进入函数执行其中的第一条语句
finish 跳出本次函数
next n 执行下一条语句,如果该语句为函数调用,不会进入函数内部执行(即不会一步步地调试函数内部语句)
print p 打印内部变量值
ptype 打印变量类型
continue c 继续程序的运行,直到遇到下一个断点
u 跳出本次循环
set var name=v 设置变量的值
start st 开始执行程序,在main函数的第一条语句前面停下来
file 装入需要调试的程序
kill k 终止正在调试的程序
watch 监视变量值的变化
backtrace bt 产看函数调用信息(堆栈)
frame f 查看栈帧
quit q 退出GDB环境

# 生成调试程序

gcc *.c -o app -gCopy to clipboardErrorCopied
1

# 查看代码

l main.c:mainCopy to clipboardErrorCopied
1

# 设置断点

  • 设置断点
b 22
b 15 if i == 15Copy to clipboardErrorCopied
1
2
  • 查看断点
i bCopy to clipboardErrorCopied
1
  • 删除断点
d 1
d 1-5Copy to clipboardErrorCopied
1
2

# 执行程序

  • 开始
startCopy to clipboardErrorCopied
1
  • 单步
nCopy to clipboardErrorCopied
1
  • 下个断点
cCopy to clipboardErrorCopied
1

# 单步调试

  • 进入函数内部
sCopy to clipboardErrorCopied
1
  • 跳出本次循环
uCopy to clipboardErrorCopied
1
  • 退出函数
finishCopy to clipboardErrorCopied
1

# 查看变量

  • 查看变量的值
p varCopy to clipboardErrorCopied
1
  • 查看变量类型
ptype varCopy to clipboardErrorCopied
1
  • 设置变量的值
set var i=10Copy to clipboardErrorCopied
1

# 追踪变量

  • 追踪变量
display i
display jCopy to clipboardErrorCopied
1
2
  • 查看追踪的变量
i displayCopy to clipboardErrorCopied
1
  • 删除追踪的变量
undisplay 1 # 对应变量的编号Copy to clipboardErrorCopied
1

# 多进程调试

在fork之前设置mode。

  • set follow-fork-mode child,跟踪子进程
  • set follow-fork-mode parent 跟踪父进程

# makefile

# 普通版

app: main.o sum.o sub.o
     gcc main.o sum.o sub.o -o app
main.o: main.c
    gcc -c main.c
sum.o: sum.c
    gcc -c sum.c
sub.o: sub.c
    gcc -c sub.cCopy to clipboardErrorCopied
1
2
3
4
5
6
7
8

# 自动变量

$@: 规则中的目标
$<: 规则中的第一个依赖
$^: 规则中的所有依赖Copy to clipboardErrorCopied
1
2
3
obj = main.o sum.o sub.o
target = app
# makefile系统变量
CC = gcc
$(target):$(obj)
$(CC) $(obj) -o $(target)
%.o: %.c
$(CC) -c $< -o $@Copy to clipboardErrorCopied
1
2
3
4
5
6
7
8

# makefile函数

target = app
# 得到所有.c文件
src = $(wildcard ./*.c)
# 将.c替换为.o
obj = $(patsubst ./%.c, ./%.o, $(src))
CC = gcc
$(target): $(obj)
    $(CC) $(obj) -o $(target)
%.o: %.c
    $(CC) -c $< -o $@
# 声明伪目标
.PHONY:clean
clean:
    rm $(obj) $(target)Copy to clipboardErrorCopied
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 静态模型

c194a9eg(objects)中获取, "%.o"表示以".o"结尾的目标, 即foo.o bar.o, 依赖模式就是把"%.o"中的"%"拿来加上".c"

objects = foo.o bar.o
all: $(objects)
$(objects): %.o: %.c
    $(CC) -c $(CFLAGS) &< -o $@Copy to clipboardErrorCopied
1
2
3
4

等价于

foo.o : foo.c
$(CC) -c $(CFLAGS) foo.c -o foo.o
bar.o : bar.c
$(CC) -c $(CFLAGS) bar.c -o bar.oCopy to clipboardErrorCopied
1
2
3
4
#C
上次更新: 2022/12/02, 22:04:34
Lua语法总结

← Lua语法总结

最近更新
01
常用游戏反外挂技术总结
11-27
02
Golang开发实践万字总结
11-11
03
Redis万字总结
10-30
更多文章>
Theme by Vdoing | Copyright © 2011-2022 Ravior | 粤ICP备17060229号-3 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式