X86_64平台下strtoul诡异问题,都是#include惹的祸?

在CentOS5.4环境中,使用gcc4.1.2编译器时,作者遇到了一个奇怪的问题:调用strtoul函数解析特定字符串时,得到的结果并非预期值。通过深入探究发现,未包含<stdlib.h>头文件会导致编译器内部处理错误,进而影响函数的行为。加入该头文件后,问题得以解决。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

环境CentOS 5.4 X86_64 gcc version 4.1.2 20080704 (Red Hat 4.1.2-46)
碰到一个strtoul的诡异问题,简化出来就是这个程序

#include <stdio.h>

int main(){
char *a = "4297757104";
unsigned long int l = strtoul(a, NULL, 0);
printf("%lu\n", l);
return 0;
}

结果输出2789808而非4297757104。查了半天手册也没发现什么不对的,发现手册中有#include <stdlib.h> ,加上去居然就对了。百思不解,原来编译也能通过,为什么加个头文件就导致程序行为改变了?

之前也听说过GCC对某些函数会做内部特殊处理。既然程序行为改变,二进制级别上肯定就有区别。先用objdump -T long 将动态链接的函数导出一看,都一样。干脆直接objdum -S long> long.s 把程序反汇编,然后diff查看,结果发现没有加include的版本,多了cltq 这么条指令
40050b: e8 e8 fe ff ff callq 4003f8 <strtoul@plt>
400510: 48 98 cltq
就是罪魁祸首了。这条指令是将eax寄存器的值符号扩展到rax。
4297757104的二进制是100000000001010101001000110110000,其中低32位截取下来是00000000001010101001000110110000,然后符号扩展到64位,只要将高32位补0即可。换算下来,刚好就是2789808。也就是说,这条指令把rax高32位的数据给清掉了。

教训:还是那两句老话
1)编译时一定要加上 -Wall,加上之后就会报一个 warning: implicit declaration of function 'strtoul'。否则,怎么死的都不知道。
2)不要忽略任何warning
不过,这个warning对于我等新手来说,很容易无视,也很难明白其中含义
/opt/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/6.3.1/../../../../arm-linux-gnueabihf/bin/ld: Dwarf Error: found dwarf version '5', this reader only handles version 2, 3 and 4 information. ./gpio/source/lib/libgpiod.a(libgpiod_la-core.o): In function `gpiod_chip_open': core.c:(.text+0x60): undefined reference to `__lstat64_time64' core.c:(.text+0x82): undefined reference to `__stat64_time64' /opt/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/6.3.1/../../../../arm-linux-gnueabihf/bin/ld: Dwarf Error: found dwarf version '256', this reader only handles version 2, 3 and 4 information. core.c:(.text+0x1c6): undefined reference to `__ioctl_time64' ./gpio/source/lib/libgpiod.a(libgpiod_la-core.o): In function `gpiod_line_update': core.c:(.text+0x2ea): undefined reference to `__ioctl_time64' ./gpio/source/lib/libgpiod.a(libgpiod_la-core.o): In function `line_request_values': core.c:(.text+0x504): undefined reference to `__ioctl_time64' /opt/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/6.3.1/../../../../arm-linux-gnueabihf/bin/ld: Dwarf Error: found dwarf version '5', this reader only handles version 2, 3 and 4 information. ./gpio/source/lib/libgpiod.a(libgpiod_la-core.o): In function `line_request_event_single': core.c:(.text+0x6e0): undefined reference to `__ioctl_time64' ./gpio/source/lib/libgpiod.a(libgpiod_la-core.o): In function `gpiod_line_get_value_bulk': core.c:(.text+0x942): undefined reference to `__ioctl_time64' /opt/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/6.3.1/../../../../arm-linux-gnueabihf/bin/ld: Dwarf Error: found dwarf version '55303', this reader only handles version 2, 3 and 4 information. ./gpio/source/lib/libgpiod.a(libgpiod_la-core.o):core.c:(.text+0x968): more undefined references to `__ioctl_time64' follow /opt/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/6.3.1/../../../../arm-linux-gnueabihf/bin/ld: Dwarf Error: found dwarf version '6656', this reader only handles version 2, 3 and 4 information. ./gpio/source/lib/libgpiod.a(libgpiod_la-core.o): In function `gpiod_line_event_wait_bulk': core.c:(.text+0xf30): undefined reference to `__ppoll64' /opt/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/6.3.1/../../../../arm-linux-gnueabihf/bin/ld: Dwarf Error: found dwarf version '5', this reader only handles version 2, 3 and 4 information. ./gpio/source/lib/libgpiod.a(libgpiod_la-helpers.o): In function `gpiod_chip_open_lookup': helpers.c:(.text+0x178): undefined reference to `__isoc23_strtoul' collect2: 错误: ld 返回 1 make: *** [Makefile:63:build/bin/demo] 错误 1
06-02
/opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/7.5.0/../../../../arm-linux-gnueabihf/bin/ld: Dwarf Error: found dwarf version '5', this reader only handles version 2, 3 and 4 information. ./gpio/source/lib/libgpiod.a(libgpiod_la-core.o): In function `gpiod_chip_open': core.c:(.text+0x60): undefined reference to `__lstat64_time64' core.c:(.text+0x82): undefined reference to `__stat64_time64' /opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/7.5.0/../../../../arm-linux-gnueabihf/bin/ld: Dwarf Error: found dwarf version '256', this reader only handles version 2, 3 and 4 information. core.c:(.text+0x1c6): undefined reference to `__ioctl_time64' ./gpio/source/lib/libgpiod.a(libgpiod_la-core.o): In function `gpiod_line_update': core.c:(.text+0x2ea): undefined reference to `__ioctl_time64' ./gpio/source/lib/libgpiod.a(libgpiod_la-core.o): In function `line_request_values': core.c:(.text+0x504): undefined reference to `__ioctl_time64' /opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/7.5.0/../../../../arm-linux-gnueabihf/bin/ld: Dwarf Error: found dwarf version '5', this reader only handles version 2, 3 and 4 information. ./gpio/source/lib/libgpiod.a(libgpiod_la-core.o): In function `line_request_event_single': core.c:(.text+0x6e0): undefined reference to `__ioctl_time64' ./gpio/source/lib/libgpiod.a(libgpiod_la-core.o): In function `gpiod_line_get_value_bulk': core.c:(.text+0x942): undefined reference to `__ioctl_time64' /opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/7.5.0/../../../../arm-linux-gnueabihf/bin/ld: Dwarf Error: found dwarf version '55303', this reader only handles version 2, 3 and 4 information. ./gpio/source/lib/libgpiod.a(libgpiod_la-core.o):core.c:(.text+0x968): more undefined references to `__ioctl_time64' follow /opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/7.5.0/../../../../arm-linux-gnueabihf/bin/ld: Dwarf Error: found dwarf version '6656', this reader only handles version 2, 3 and 4 information. ./gpio/source/lib/libgpiod.a(libgpiod_la-core.o): In function `gpiod_line_event_wait_bulk': core.c:(.text+0xf30): undefined reference to `__ppoll64' /opt/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/7.5.0/../../../../arm-linux-gnueabihf/bin/ld: Dwarf Error: found dwarf version '5', this reader only handles version 2, 3 and 4 information. ./gpio/source/lib/libgpiod.a(libgpiod_la-helpers.o): In function `gpiod_chip_open_lookup': helpers.c:(.text+0x178): undefined reference to `__isoc23_strtoul' collect2: 错误: ld 返回 1 make: *** [Makefile:63:build/bin/demo] 错误 1 sed@sed-VMware-Virtual-Platform:~/gui/linux$
最新发布
06-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值