一、材料准备:
1、头文件:function.h
2、.c文件: function.c main.c
function.h: 一个简单的头文件,声明了函数func_a(),func_b()
#ifndef FUNCTION_H
#define FUNCTION_H
#include <stdio.h>
void func_a();
void func_b();
#endif
function.c: func_a(), func_b()的实现
#include "function.h"
void func_a()
{
printf("I am func a! step 1 \n");
printf("I am func a! step 2 \n");
printf("I am func a! step 3 \n");
}
void func_b()
{
printf("I am func b! step 1 \n");
printf("I am func b! step 2 \n");
printf("I am func b! step 3 \n");
}
main.c: 主函数调用func_a(), func_b()
#include "function.h"
int main(int argc, char *argv[])
{
func_a();
func_b();
return 0;
}
二、将function.c编译成一个动态链接库
敲命令:gcc -c function.c -fPIC --share -o libfunc.so //注意,这里没有写 -g 参数,为下文埋下一个伏笔
此时当前目录下面会生成libfunc.so文件
三、编译main.c文件
敲命令:gcc -o main main.c -g -lfunc -L ./ // 这里添加参数 -g
e.g 这里小小的说明一下,程序编译默认动态库搜索路径是/lib、/usr/lib,这里如果不用 -L参数(搜索非标准的库和头文件的路径)是无法编译成功的
四、gdb调试
敲命令: gdb main
按照我的习惯,在gdb里面设置断点,我喜欢用 b filename:line 的形式(如 b main.c:5),但此时只能显示非动态库里面的函数文件,动态库里只显示函数原型,试了一下用 函数原型:行号的方式设置断点,不好用。
正确的解决方法:
在编译动态链接库的时候添加 -g参数
--------------------------------------------------------------------------------------
敲命令:重新生成动态链接库并重新编译程序
gcc -c function.c -fPIC -g --share -o libfunc.so
gcc -o main main.c -g -lfunc -L ./
此时用gdb断点就可以显示动态库里面的文件了,在这里是function.c,就可以用 filename:line 的方式设置断点
-------------------------------------------------------------------------------------------------------------------------------------------------------------
最后在啰嗦一句,如果想检查动态库编译的时候有没有打上-g 参数有一个好办法:
敲命令:gdb libname.so //libname.so 指对应库的名字
如果提示信息显示 Reading symbols from libname.so ... done,表示编译的时候有带-g参数,反之则没有