前言

之前程序是32位的,切到64位之后,一些隐藏的问题就暴露了。这不,一个由字节对齐导致的挂死问题就出来了。

字节对齐和64位

关于字节对齐,可参考《理一理字节对齐的那些事》,而之前也分享过另一个切64位之后出现的问题,有兴趣的可以查看《记64位地址截断引发的挂死问题》。

本文背景

本文出现的场景是,系统需要解析JSON文件,但是出现部分功能解析正常,部分挂死,并且32位程序正常,而64位程序挂死。鉴于原系统比较复杂,本文将会简化其过程,来看看到底是什么导致了挂死。
本文示例代码主要引自《一个超轻量级的JSON解析器》。

简化后示例代码

//来源:公众号【编程珠玑】
//https://www.yanbinghu.com
#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<string.h>
#pragma pack(1)
#include"cJSON.h"
#pragma pack()/*省略部分代码,完整代码可查看附录部分*/
int main(void)
{char *filename = "./test.json";cJSON *pJson = NULL;cJSON *pTemp = NULL;pJson = prepare_parse_json(filename);if(NULL == pJson){printf("parse json failed\n");return -1;}/*获取name值*/pTemp = cJSON_GetObjectItem(pJson,"name");printf("name is %s\n",pTemp->valuestring);/*获取site值*/pTemp = cJSON_GetObjectItem(pJson,"site");printf("site is %s\n",pTemp->valuestring);/*获取age值*/pTemp = cJSON_GetObjectItem(pJson,"age");printf("age is %d\n",pTemp->valueint);/*记得释放相关内存*/cJSON_Delete(pJson);pJson = NULL;return 0;
}

编译运行结果:

$ gcc -L. -o parseJson parseJson.c -lcjson
$ ./parseJson
Segmentation fault (core dumped)

在实际中我们通过GDB观察发现,在解析JSON内部查看JSON数据是完好的,但是调用完解析JSON之后,再去访问使用就不对了,并且我们发现,在不同的功能模块中,调用结果不一样,大部分模块调用并没有任何问题,而只有某个功能模块调用出现问题。

真相

到底是什么导致的呢?
问题的根源在于下面这几行代码:

#pragma pack(1)
#include"cJSON.h"
#pragma pack()

另外补充,cJSON结构体如下:

typedef struct cJSON {  //cJSON结构体struct cJSON*next,*prev;           /*后驱节点和前驱节点*/struct cJSON *child;                   /*孩子节点*/int type;                                     /* 键的类型*/char *valuestring;                       /*字符串值*/int valueint;                                /* 整数值*/double valuedouble;                    /* 浮点数值*/char *string;                               /* 键的名字*/
} cJSON;

#pragma指令说明了按一字节对齐,而cJSON的头文件也在其中,那么就会导致里面的cJSON结构体按照1字节对齐,最终其结构体大小为56个字节而已经编译好的cjson库可并非如此,因此对于64位程序,它还是按照8字节对齐,结构体大小为64字节,而对于32位程序,按照4字节和1字节对齐,都是36字节。

同一个结构体的大小竟然在不同的代码中大小不一样!

最终也就出现了我们遇到的情况,64位程序由于库中申请结构体内存大小与外部调用不一样,最终导致挂死,而32位程序解析JSON正常。

来源:公众号编程珠玑
博客:https://www.yanbinghu.com

总结

幸运的是,本文示例中能够很明显的能看到问题所在,但在实际项目中,如果头文件管理不规范,并且项目的产品多样,通过编译宏来隔开使用的头文件,就很难发现这样的问题。

思考

什么情况下需要1字节对齐呢?

附录

本文完整代码请查看字节对齐不慎引发的挂死问题的附录部分。

微信公众号【编程珠玑】:专注但不限于分享计算机编程基础,Linux,C语言,C++,数据结构与算法,工具,资源等编程相关[原创]技术文章。
[外链图片转存失败(img-xAsfbVfI-1565271810384)(https://github.com/yanbinghu/BlogImages/raw/master/blog/qrcode.jpg)]

字节对齐不慎引发的挂死问题相关推荐

  1. 对齐方式有那些_字节对齐不慎引发的挂死问题

    前言 之前程序是32位的,切到64位之后,一些隐藏的问题就暴露了.这不,一个由字节对齐导致的挂死问题就出来了. 字节对齐和64位 关于字节对齐,可参考<理一理字节对齐的那些事>,而之前也分 ...

  2. c# 结构体 4字节对齐_【专题4:平时遇到的问题】 之 【3.由结构体字节对齐引发的通信故障】...

    希望本是无所谓有,无所谓无的,这正如脚下的路,其实地上本没有路,走的人多了,也便成了路....原创不易,文章会持续更新,感谢您的关注 1.问题由来 MCU给上位机发送的一帧数据中,总是多一个字节,调试 ...

  3. 面试题--特别是字节对齐

    来源:http://www.cnblogs.com/Braveliu/archive/2013/01/04/2844757.html [1]设置或者清除某位. 示例代码如下: 1 #include&l ...

  4. 一次挂死(hang)的处理过程及经验

    前言: CPU占用率低,内存还有许多空余,但网站无法响应,这就是网站挂死,通常也叫做hang.这种情况对于我这样既是CEO,又是CTO,还兼职扫地洗碗的个人站长来说根本就是家常便饭.以下是一次处理ha ...

  5. 整数边界对齐方式_嵌入式基础——字节对齐

    字节对齐 一.内存访问对齐规则 从高级语言的视角看,内存访问是是字节为单位的. 但是从CPU角度看,内存访问粒度与指令有关,比如1字节访问,2字节访问,4字节访问,8字节访问等. 如果在编程过程中不注 ...

  6. i2c- sda挂死分析

    I2C是由Philips公司发明的一种串行数据通信协议,仅使用两根信号线:SerialClock(简称SCL)和SerialData(简称SDA).I2C是总线结构,1个Master,1个或多个Sla ...

  7. 一文了解结构体字节对齐

    结构体字节对齐详解 表述如有不正确的地方,欢迎批评指正. C++/C 常见的基本数据类型: bool short (short int) int long (long int) long long ( ...

  8. 理一理字节对齐的那些事

    前言 字节对齐是我们初学C语言就会接触到的一个概念,但是到底什么是字节对齐?对齐准则又是什么?为什么要字节对齐呢?字节对齐对我们编程有什么启示?本文将简单理一理字节对齐的那些事. 什么是字节对齐 计算 ...

  9. c如何通过偏移量取出文件中的字节_理一理C语言字节对齐的那些事

    作者:守望,Linux应用开发者,目前在公众号[编程珠玑] 分享Linux/C/C++/数据结构与算法/工具等原创技术文章和学习资源. 前言 字节对齐是我们初学C语言就会接触到的一个概念,但是到底什么 ...

最新文章

  1. Web应用开发技术-CSS
  2. mysql scrapy 重复数据_mysql数据库如何处理重复数据?
  3. php+redis+设置前缀,spring使用Redis自定义前缀后缀名(去掉SimpleKey []+自定义)
  4. IE9预览版已全面支持HTML5标准
  5. [转]Ogre:Hardwarebuffer
  6. 湖南工程学院计算机网期末考试,湖南工程学院__操作系统期末试卷试题
  7. 龙芯源码编译mysql_龙芯服务器安装总结
  8. 2022年起重机司机(限桥式起重机)报名考试及起重机司机(限桥式起重机)考试资料
  9. 破解Excel工作表密码
  10. 大数据可视化陈为智慧树_大数据可视化智慧树答案
  11. 大型交易系统之高并发
  12. 安泰:线束测试仪如何快速判断汽车线束的故障情况
  13. java策略模式实战
  14. EfficientDet论文解读
  15. discuz 模板中使用php,Discuz! 中实现不同版块使用不同的模板文件
  16. css动画定义,css3的动画(animation)属性的详解(附代码)
  17. 阿朱看中国企业信息化发展方向
  18. 【shell】shell脚本的文本替换工具-tr
  19. google play store的app数据分析
  20. 安纳西(武汉)全铝智能家居 实力厂家 高端品牌

热门文章

  1. iPhone手机关掉这3个设置,不仅省电,而且手机还不会出现卡顿
  2. QECon上海站|蚂蚁测试用例智能生成技术架构与实践
  3. combox 绑定数据
  4. Java 面试就业指导,100 % 提高面试成功率!
  5. 操作系统自旋锁和互斥锁的实现原理
  6. UDP和TCP网络编程
  7. readlink()函数读取符号结果不一致问题
  8. antlr4 实战 idea
  9. 酸了,大厂程序员凡尔赛的一天…
  10. centOS镜像 + Wmwar虚拟机+Xshell + git实现一键部署服务器(详细)