作者: 守望,Linux应用开发者,目前在公众号【编程珠玑】 分享Linux/C/C++/数据结构与算法/工具等原创技术文章和学习资源
前言
最近要将整个项目的代码从原先的只支持32位变成同时支持32位和64位,这个过程中遇到一个很不容易定位的挂死问题,花了不少时间才定位解决,因此分享给大家。
32位和64位代码区别
在分享之前,需要了解一下32位和64位程序代码有何区别,它的主要区别体现在某些数据类型的占用字节大小的不同:
数据类型 | 32位 | 64位 |
---|---|---|
long | 4字节 | 8字节 |
unsigned long | 4字节 | 8字节 |
指针 | 4字节 | 8字节 |
size_t | 4字节 | 8字节 |
ssize_t | 4字节 | 8字节 |
这些是主要的差别。
那么为什么要切64位呢?原因也很简单,32位寻址范围有限,能使用的最大内存也是非常有限的,因此需要使其能够支持64位,这个过程需要修改编译工程,编译第三方库为64位,修改代码等等。当然这些都不是本文的重点,本文仅介绍遇到的这个典型的问题。
问题描述
由于项目本身涉及的系统比较复杂,因此简单分享一下定位过程,下一节将通过简洁的示例程序来说明。
问题现象:向服务器发送一条操作指令后直接挂死
分析解决过程简化为如下步骤:
查看日志以及coredump信息,初步定位挂死的位置
发现挂死在停止定时器的位置
32位程序正常,而64位异常,因此和32位与64位的差别有关
怀疑传入定时器数据有问题,编写小demo,排除传入数据问题
编译可调试版本,加入-g参数
跟踪调试,发现最终挂在了一个动态库中
设置gdb源