记录一次Aborted错误

记录一次Aborted错误的解决

问题现象

在搞一个VPN的连接代码测试,发现每次客户端断开连接都会导致VPN服务器崩掉,debug跟进服务端的代码里,发现是Free连接环境时发生了异常,从debug的代码看到的现象很奇怪,一会是在执行Free函数时报错,一会又跑到了打印日志时报错。

详细跟进代码发现,无论上层的函数是在哪里报错,下层都是跑到了glibc中的_int_free函数中,那结论就比较清晰了,是free时内存出错了,多半是内存溢出了。
gdb解析coredump的截图
报错的内容就是这个free(): invalid pointer,在VSCode的debug过程中看到的是“Fetal Error: Aborted”,由SIGABRT信号触发。

解决过程

在网上查了一圈free(): invalid pointer的解决方法,有两种可能的原因,一种是多次free,第二次就会失败,另一种是这部分内存被别的代码给改动了。

路线1

按照这个思路,我先是花2天时间把项目代码翻来覆去的看,找哪里做了多次free,最后实在是看不下去了,整个代码中的malloc和free搜索了个遍,都是没有问题的,感觉不一定是这个多次free的问题。

路线2

于是换个思路,看看是不是被别的代码改动了内存。在经常报错的那些地方一一加了断点,然后在对应的参数生成的时候也加上断点,一个一个对比生成时的位置和抛出异常时的位置内存是否有变化,然而依然没有进展。

路线3

此路不通,继续想其他的问题。
这里跟代码时跟不到glibc中的代码,因此根据需要从网上找glibc的源码看看。
首先确定自己使用的glibc是什么版本的,使用

ldd ./vpnserver

指令查看当前程序依赖的动态库,找到glibc对应的那个动态库对应的文件路径,将这个路径下的文件当可执行文件直接跑一下,得到如下的结果:

查找依赖动态库的版本

看来是使用的2.31版本的glibc,从网上搜索对应的代码,gdb中显示信息的最后一段数字就是对应代码中的行号,找到这里一看发现新的思路!glibc中申请内存时,除了原本想申请的内存,还会额外多申请一些内存,附在返回的数据指针对应的内存前面,然后在释放内存时,也会向前搜索一段距离,并对这段额外的数据做判断,如果判断失败,就会抛出异常。

glibc中free函数对应的预处理逻辑
这样就发现了问题,不是我申请的那部分内存被改动了,而是前面看不见的头数据被改动了,于是再次借助强大的VS,使用数据断点的方式对被改动的内存位置加断点。

VS的数据断点是在内存中某个内存地址添加监控,当被监控的内存发生改动时,进入断点,程序暂停。使用方式如下:

  1. 首先在某个地方打断点,让程序暂停下来。
  2. 接着点击“调试”->“新建断点”->“数据断点”,在弹出的界面输入想监控的内存地址。
    数据断点的位置

接下来就等待这个断点被触发就可以了,用这个方法最后成功找到了改动内存的罪魁祸首:gmssl库!好家伙,我说怎么看了多少代码都没用呢,原来不在VPN的代码里,在引用的库代码里,其实早就应该想到的。

总结

总结一下,C语言程序中的问题都不太好定位,逻辑问题可以靠debug解决,但是内存问题靠debug有时候真的完全没有头绪,还是抓紧拥抱RUST吧。

这次解决问题用到的技术栈和工具:
gdb调试
coredump文件
VSCode
Visual Studio 2022
glibc源码 [https://elixir.bootlin.com/glibc/glibc-2.31/source/malloc/malloc.c]

今天先记到这里吧,希望这个文章能帮助到其他被Aborted支配的人。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
"compilation aborted code 1" 是一个常见的 Fortran 编译错误,这通常表示编译器在构建您的代码时遇到了一个错误。这个错误可能有很多不同的原因,以下是一些可能引起这个错误的原因及其解决方法: 1. 代码中有语法错误:请检查您的代码是否存在语法错误,例如拼写错误、缺失的分号等。请确保您的代码符合 Fortran 的语法规则。 2. 缺失依赖项:如果您的代码引用了其他模块或库,但是这些模块或库没有正确地链接到您的代码中,就会出现 "compilation aborted code 1" 的错误。请确保您的代码正确地链接了所有必需的依赖项。 3. 编译器版本不兼容:某些 Fortran 编译器可能不兼容某些代码。请确保您的代码能够与您使用的编译器版本兼容。您可以尝试升级您的编译器或者更改编译器选项来解决这个问题。 4. 内存不足:如果您的代码需要大量的内存来编译,但是您的机器没有足够的内存,就会出现 "compilation aborted code 1" 的错误。请确保您的机器具有足够的内存来编译您的代码。 5. 其他错误:还有其他许多可能导致 "compilation aborted code 1" 的错误,例如文件系统错误、权限问题等。请检查您的编译日志以获取更多信息,并尝试解决任何其他错误。 希望这些信息能够帮助您解决问题。如果您仍然无法解决问题,请提供更多信息,以便我能够更好地帮助您。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值