gpt4 book ai didi

c - x86-64 中返回指针的未声明函数导致无效指针扩展

转载 作者:太空宇宙 更新时间:2023-11-04 06:35:39 32 4
gpt4 key购买 nike

<分区>

我只花了半天时间来解决 x86-64 代码中的一个微妙崩溃,所以这对其他人来说是一个提醒 - 我没有在其他地方看到过这个问题。

如果您在没有正确声明的情况下使用 libc 函数,gcc 将假定它返回 int。例如。 setlocale() 被假定为 int setlocale(),在 EAX 中返回一个 32 位 int 值。

尝试通过隐式或显式转换将此返回值转换为指针,将强制通过符号扩展从 32 位转换为 64 位,即使被调用函数在 RAX 中返回了有效的 64 位指针值!例如

    char *p = setlocale(0, 0);      // bear with me for a second

被编译成

    1c: b8 00 00 00 00          mov    $0x0,%eax
21: e8 00 00 00 00 callq 26 <hard_locale+0x26>
26: 48 98 cltq ; <--- eax is expanded in rax

GCC 甚至试图告诉您:

    warning: initialization makes pointer from integer without a cast

如果您添加显式强制转换,警告将更改为,这表明了问题:

    warning: cast to pointer from integer of different size

如果运气好的话,什么都没有发生,但是如果恰好返回了一个很大的内存中up指针的值,那就乱七八糟了,如下:

    function returns in RAX: 0x07ffff7b9705e
cltq considers EAX with negative sign: 0xf7b9705e
now RAX is: 0xfffffffff7b9705e

并且您的指针无效。

修复和解决方案:

  • 始终使用正确的函数声明

  • -Wall -Werror 应该在 x86-64 编译器中默认打开。

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com