gpt4 book ai didi

c - 无法从可执行共享库中打印 float

转载 作者:IT王子 更新时间:2023-10-29 00:07:24 24 4
gpt4 key购买 nike

我正在开发一个共享库,它可以独立执行以打印它自己的版本号。

我定义了一个自定义入口点:

const char my_interp[] __attribute__((section(".interp"))) = "/lib64/ld-linux-x86-64.so.2";

void my_main() {
printf("VERSION: %d\n", 0);
_exit(0);
}

我用

编译
gcc -o list.os -c -g -Wall -fPIC list.c
gcc -o liblist.so -g -Wl,-e,my_main -shared list.os -lc

这段代码可以完美地编译运行

我的问题是当我将 printf 的参数更改为 float 或 double (%f 或 %lf)时。该库随后将编译,但在运行时出现段错误

有人有什么想法吗?

edit1:

这是出现段错误的代码:

const char my_interp[] __attribute__((section(".interp"))) = "/lib64/ld-linux-x86-64.so.2"; 

void my_main() {
printf("VERSION: %f\n", 0.1f);
_exit(0);
}

edit2:

其他环境细节:

uname -a

Linux mjolnir.site 3.1.10-1.16-desktop #1 SMP PREEMPT Wed Jun 27 05:21:40 UTC 2012 (d016078) x86_64 x86_64 x86_64 GNU/Linux

gcc --version

gcc (SUSE Linux) 4.6.2

/lib64/libc.so.6

针对 x86_64-suse-linux 配置。由 GNU CC 版本 4.6.2 编译。2012-03-30 在Linux 3.1.0系统上编译。

编辑 3:

出现段错误时/var/log/messages 中的输出:

8 月 11 日 08:27:45 mjolnir 内核:[10560.068741] liblist.so[11222] 一般保护 ip:7fc2b3cb2314 sp:7fff4f5c7de8 error:0 in libc-2.14.1.so[7fc2b3c63000+187000]

最佳答案

想通了。 :)

x86_64 上的浮点运算使用 xmm vector 寄存器。对这些的访问必须在 16 字节边界上对齐。这解释了为什么 32 位平台不受影响并且整数和字符打印有效。

我已经将我的代码编译为汇编:

gcc -W list.c -o list.S -shared -Wl,-e,my_main -S -fPIC

然后修改“my_main”函数以获得更多堆栈空间。

之前:

my_main:
.LFB6:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $.LC0, %eax
movsd .LC1(%rip), %xmm0
movq %rax, %rdi
movl $1, %eax
call printf
movl $0, %edi
call _exit
.cfi_endproc

之后:

my_main:
.LFB6:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
subq $8, %rsp ;;;;;;;;;;;;;;; ADDED THIS LINE
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $.LC0, %eax
movsd .LC1(%rip), %xmm0
movq %rax, %rdi
movl $1, %eax
call printf
movl $0, %edi
call _exit
.cfi_endproc

然后我通过以下方式编译了这个 .S 文件:

gcc list.S -o liblist.so -Wl,-e,my_main -shared

这解决了这个问题,但我会将这个线程转发到 GCC 和 GLIBC 邮件列表,因为它看起来像一个错误。

edit1:

根据 gcc irc 中的 noshadow,这是执行此操作的非标准方法。他说如果要使用 gcc -e 选项,要么手动初始化 C 运行时,要么不要使用 libc 函数。说得通。

关于c - 无法从可执行共享库中打印 float ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11912423/

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