logo头像
Snippet 博客主题

踩坑汇总

前言

年纪大了,发现曾经踩过的坑老是健忘,简单记录下,做个汇总专栏,持续更新~

此栏开始于:2023-11-21 10:57:55


1. 调式时断点不命中

常见两种情况:

  1. 当前断点代码是独立编译成动态库被主程序加载使用,这种情况断点不命中基本是:
    • 主程序没有加载这个dll
    • 加载了这个dll,但是失败了。一般是内部错误,如内部所依赖的其它库不存在,如果内部是动态加载其它库,那就很隐蔽了,工具还查不到依赖关系。
  2. 祖传方式,就是格式化下代码,或随便加点注释。

2. 项目Debug正常但Release会崩溃

同一份代码,debug和release表现不一样,很有可能是它们的依赖库属性配置的问题,如把debug版的依赖库配到了release下,混用是可能出现不稳定、崩溃问题的。

这个问题基本就是检测它们的属性,附加依赖项这些配置,一般是这个原因。

如下,就是release版,却添加的带d的debug依赖:


3. 把静态库编译链接到动态库中

这个事情网上有总结一个表格,很到位:

总结是两点:

  1. 动态库和静态库都要是加了shared -fPIC选项编译出来的。
  2. 注意静态库要紧跟动态库的后面,这个位置也有遵守。

如果你不这么干,要么编译失败,要么使用时静态库接口未定义。


4. msvc编译时报“Error C1902:程序数据库管理器不匹配”错误

解决办法:

mspdbcore.dll(C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE目录下) 和 mspdbsrv.exe(C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE目录下)拷贝到C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin目录下。

什么原因造成的暂不清楚!


5. 某台机器编译的一个库,放另一台机器运行崩溃

一般是由于这两台机器CPU型号不一致,或版本有差异。

遇到过的一个坑是,运行报非法指令(核心已转储),原因是在某台机器上编译出的依赖库cmake脚本,用了-mavx -mfma cpu指令,而另一台机器的cpu不支持这两个选项。删掉这两个指令重新编译动态库解决。


6. vscode用cmake编译c++项目时提示一堆 “注意:包含文件” 的问题

  1. 先删除配置、重新配置。

  1. 换成vs自己的编译器构建试一下,最后会报错,不用管。

  1. 再重复1,清理再配置。然后2还原为"cmake.generator": "Ninja Multi-Config",再build就没问题了。(至于原理还不清楚,很神奇!!!)

7. TCP服务端解包,数据很容易出现异常

考虑了粘包问题后,如果还有异常,大概率是多线程资源抢占问题了,常见的服务端对每个客户端连接都会开一个线程单独处理,而上层解包又是一个公共接口,这时,如果存在公共资源,一定注意加锁


8. 程序随机崩溃,断点调试每次错误值还不一样

这一般是指针访问到非法内存导致的,如申请了一块固定大小的内存空间,在这上面做操作时,没有考虑到内存越界访问的情况。


9. double类型计算误差问题

double类型数据的乘除计算是和编译器和优化等级有关系的,不过主要是优化等级有关,不同编译器,如msvc与g++它们在同一优化等级O2时,结果到15~17位都还是完全一致的。

10. dll中引入一个C语言三方库后加载失败或导出函数获取不到

时间:2024/03/13 11:08

场景:
我用C++创建了一个动态库工程,导出一些自定义的数学函数给其它项目使用,这都没问题。不过,最近引入了一个新成员,需要加一个傅里叶算法,我使用的是开源fftw3库,它是C语言实现,正常配置好包含头文件/库文件后,重新编译。别人使用时发现我这个dll加载失败或导出的数学函数获取不到(0x000000)。

解决:

  1. 首先怀疑是依赖库问题,用Dependencies查看了都存在,没问题。
  2. 后面查看dll里导出函数名称被混淆了才意识到,这是常见的C与C++混编问题,需要加 extern "C"

总结:
如果是C语言代码一定记得加 extern "C" {xxx} 圈起来,因为默认C++编译后,函数名称会被混淆。