一个arm平台C++工程段md5错误的排查
Posted 李迟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个arm平台C++工程段md5错误的排查相关的知识,希望对你有一定的参考价值。
某 arm 工控机在试点测试时发现某数据文件无法下载。经几天时间,解决了问题,虽然没有很难的技术问题,但过程还是值得记录的。
起因
最近(几个月之前),收到反馈,某 arm 工控机在试点测试时发现某数据文件无法下载。经查,是 md5 源码文件的宏定义没有使用正确造成的,改正问题即解决。
排查及解决
问题定位
搭建模拟环境,复现问题。经测的确存在问题。查看日志发现文件的 md5 和记录的值不一致,因此无法成功下载。
保持环境相同,改用 x86 版本程序,能下载成功。
对比两者 md5 模块代码,完全一样(注:此处不应一样)。
添加调试代码,在函数内部输出 md5 值,同时在命令行中使用md5sum
确认实际值。经测,只要是 arm 平台,下载的 md5 与命令行的结果不同。
后面,发现 md5 模块代码与 github这个仓库 较相近(最原始出版找不到),但在头文件global.h
对一些类型做了些宏定义的修改。
github 仓库代码:
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
/* UINT2 defines a two byte word */
typedef unsigned short int UINT2;
/* UINT4 defines a four byte word */
typedef unsigned long int UINT4;
工程代码:
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
/* UINT2 defines a two byte word */
typedef unsigned short int UINT2;
/* UINT4 defines a four byte word */
#if defined __amd64
typedef unsigned int UINT4;
#else
typedef unsigned long int UINT4;
#endif
问题出在UINT4
的长度上,个人认为github 仓库的代码没有考虑到系统位数,在 32 位系统上,使用unsigned long int
无问题,但 64 位须用unsigned int
,在移植时,没有考虑到这个地方,因此在 arm 64 位系统上,UINT4
就变大了,因此计算的 md5 值就不正确。
解决方法
定义如下即可:
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
/* UINT2 defines a two byte word */
typedef unsigned short int UINT2;
/* UINT4 defines a four byte word */
#if defined __amd64 || defined __aarch64__
typedef unsigned int UINT4;
#else
typedef unsigned long int UINT4;
#endif
小结
个人认为,系统位数和系统类型还是分开对待比较好。比如 x86 和 arm 是系统类型,x86 有 64 位和 32 位,arm 也有 64 位和 32 位。对于需区分数值类型的,可以用标准的uint32_t
一类关键字,能避免系统位数带来的问题。
附:
不同系统执行gcc -E -dM - </dev/null
的输出结果如下
重要的:
#define __unix__ 1
#define unix 1
#define __unix 1
#define __linux 1
#define __linux__ 1
#define linux 1
#define __INT32_MAX__ 2147483647
#define __gnu_linux__ 1
#define __GNUC__ 4
64位 arm:
#define __SIZEOF_LONG_DOUBLE__ 16
#define __SIZEOF_SIZE_T__ 8
#define __INTPTR_TYPE__ long int
#define __UINT16_TYPE__ short unsigned int
#define __SIZE_TYPE__ long unsigned int
#define __SIZEOF_LONG_LONG__ 8
#define __UINT64_C(c) c ## UL
#define __INT16_MAX__ 32767
#define __UINT64_MAX__ 18446744073709551615UL
#define __aarch64__ 1
#define __AARCH64EL__ 1
32位x86:
#define i386 1
#define __SIZEOF_SIZE_T__ 4
#define __INTPTR_TYPE__ int
#define __UINT16_TYPE__ short unsigned int
#define __SIZE_TYPE__ unsigned int
#define __UINT32_TYPE__ unsigned int
#define __SIZEOF_LONG_LONG__ 8
#define __INT8_MAX__ 127
#define __UINT8_MAX__ 255
#define __INT16_MAX__ 32767
#define __UINT16_MAX__ 65535
#define __INT32_MAX__ 2147483647
#define __UINT32_MAX__ 4294967295U
#define __INT64_MAX__ 9223372036854775807L
#define __UINT64_MAX__ 18446744073709551615UL
64位 x86:
#define __x86_64 1
#define __amd64 1
#define __SIZEOF_SIZE_T__ 8
#define __INTPTR_TYPE__ long int
#define __UINT16_TYPE__ short unsigned int
#define __SIZE_TYPE__ long unsigned int
#define __UINT32_TYPE__ unsigned int
#define __SIZEOF_LONG_LONG__ 8
以上是关于一个arm平台C++工程段md5错误的排查的主要内容,如果未能解决你的问题,请参考以下文章