编译运行错误排查方法

编译时头文件找不到

  • 编译flags -v,显示所有头文件搜索路径
  • 宏是否打开
  • 编译flags是否指定了-I路径
  • 头文件中加#error "xxxx",如果该头文件被编译到,则会报错

编译时符号找不到

  • 源文件/头文件是否被编译进去了
  • 该符号是否是extern的
  • 用c++编译,是否加了extern "C"
  • 是否有宏没有打开
  • 是否存在头文件交叉包含

编译时库找不到

  • 链接flags -v, 显示所有库搜索路径
  • 链接flags是否指定了-L路径
  • -L路径下是否存在该库
  • 默认的动态库搜索路径 /lib, /usr/lib, /usr/local/lib等是否存在该库
  • 库是否和当前工具链不一致

运行时库找不到

运行时库搜索路径顺序

  1. 链接时,-Wl,-rpath=first_path:second_path指定的动态库搜索路径
  2. 环境变量LD_LIBRARY_PATH指定的动态库搜索路径
  3. 配置文件/etc/ld.so.conf中指定的动态库搜索路径
  4. 默认的动态库搜索路径/lib, /usr/lib

运行时库搜索路径查看

  • ldd program_name (ldd是个shell脚本)
ldd ./exe_json 
    linux-vdso.so.1 =>  (0x00007ffdfd3ed000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f2441ae6000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f24417dd000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2441413000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f2441d03000)
  • strace -e trace=open program_name

(部分嵌入式linux系统编译固件时,没有开这个功能)

strace -e trace=open ./exe_json 
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
+++ exited with 0 +++

不同工具链适配时符号找不到

  • 不同工具链对某些符号的定义用宏控制
eg:struct sockaddr_in结构体需要开启的宏
- linux PC: -D_GNU_SOURCE
- linux rk3308: -D_POSIX_C_SOURCE=200112L -D_DEFAULT_SOURCE

不同工具链编译出的程序运行出错

  • 大小端
  • 32位/64位
  • -O2优化导致的错误(比如网络通信时mbedtls报加解密错误),改成-O0

参考

猜你喜欢

转载自www.cnblogs.com/pukaifei/p/11280270.html