在 Ubuntu 22.04 中链接自定义构建的 glibc-2.31 后出现段错误

问题描述 投票:0回答:1

我正在尝试研究内存分配器在不同版本的 glibc 中的行为。我在 WSL 中使用 x86-64 Ubuntu 22.04 LTS。

构建 glibc-2.31

我使用来自

configure
目录的
build
命令从源代码构建了 glibc-2.31:

$ /home/<username>/glibc-src/glibc-2.31/configure --prefix=/home/<username>/glibc-2.31 --disable-werror --enable-kernel=3.2 --host=x86_64-linux-gnu --build=x86_64-linux-gnu CC=gcc CXX=g++

gcc和g++版本都是11.4.0。我不确定这是否重要,但 glibc-2.35 已经安装在默认位置。

我还修改了源代码中的

Makefile
support/Makefile
以解决构建时的链接器错误,但我怀疑这会导致段错误。

Makefile

577 #ifeq (,$(CXX))
578 #LINKS_DSO_PROGRAM = links-dso-program-c
579 #else
580 #LINKS_DSO_PROGRAM = links-dso-program
581 #endif
582 LINKS_DSO_PROGRAM = links-dso-program-c
support/Makefile

191 #ifeq (,$(CXX))
192 #LINKS_DSO_PROGRAM = links-dso-program-c
193 #else
194 #LINKS_DSO_PROGRAM = links-dso-program
195 #LDLIBS-links-dso-program = -lstdc++ -lgcc -lgcc_s $(libunwind)
196 #endif
197 LINKS_DSO_PROGRAM = links-dso-program-c

运行

make
会成功构建,然后我运行
make install
将二进制文件安装在
/home/<username>/glibc-2.31

在 Ubuntu 20.04 上:可能值得注意的是,保留 glibc 源中的原始

Makefile
support/Makefile
,而不进行上面所示的修改,不会产生链接器错误。我在 Ubuntu 20.04 Docker 容器中尝试过这个。

使用自定义 glibc 导致的段错误

在 Ubuntu 22.04 上使用默认系统 glibc 编译并运行 C 程序工作正常。但是,将 C 程序链接到 Ubuntu 22.04 中构建的自定义 glibc 并使用构建中的动态链接器会导致段错误。

// test.c
int main()
{
    return 0;
}
$ gcc -o test test.c -L/home/<username>/glibc-2.31/lib -Wl,-rpath=/home/<username>/glibc-2.31/lib -Wl,-dynamic-linker=/home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
$ ldd test
        linux-vdso.so.1 (0x00007ffede365000)
        libc.so.6 => /home/<username>/glibc-2.31/lib/libc.so.6 (0x00007f906d23b000)
        /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007f906d403000)
$ ./test
Segmentation fault

GDB 显示段错误发生在

.text
链接器的
ld-linux-x86-64.so.2
段内:

gef➤  context
[ Legend: Modified register | Code | Heap | Stack | String ]
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── registers ────
$rax   : 0x00007fffffffdec0  →  0x0000002000000000
$rbx   : 0x00007fffffffdee0  →  0x00007ffff7ff413a  →  "LINUX_2.6"
$rcx   : 0x00007ffff7ffeae8  →  0x00007ffff7ffea10  →  0x00007ffff7ffe778  →  0x00007ffff7ffe750  →  0x00007ffff7fcf000  →  0x00010102464c457f
$rdx   : 0x00007fffffffdeb0  →  0x00007fffffffdec0  →  0x0000002000000000
$rsp   : 0x00007fffffffdde8  →  0x00007fffffffdee0  →  0x00007ffff7ff413a  →  "LINUX_2.6"
$rbp   : 0x00007fffffffdeb0  →  0x00007fffffffdec0  →  0x0000002000000000
$rsi   : 0x00007ffff7ffe750  →  0x00007ffff7fcf000  →  0x00010102464c457f
$rdi   : 0x00007ffff7ff4144  →  "__vdso_clock_gettime"
$rip   : 0x00007ffff7fdc204  →  <_dl_lookup_symbol_x+20> mov %fs:0x10, %rax
$r8    : 0x00007fffffffdee0  →  0x00007ffff7ff413a  →  "LINUX_2.6"
$r9    : 0x0
$r10   : 0x6ffffe35
$r11   : 0x70000022
$r12   : 0x00007ffff7ff4144  →  "__vdso_clock_gettime"
$r13   : 0x00007ffff7ffe750  →  0x00007ffff7fcf000  →  0x00010102464c457f
$r14   : 0x0
$r15   : 0x00007ffff7ffe1a0  →  0x0000555555554000  →   jg 0x555555554047
$eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x33 $ss: 0x2b $ds: 0x00 $es: 0x00 $fs: 0x00 $gs: 0x00
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x00007fffffffdde8│+0x0000: 0x00007fffffffdee0  →  0x00007ffff7ff413a  →  "LINUX_2.6"    ← $rsp
0x00007fffffffddf0│+0x0008: 0x00007fffffffe020  →  0x00007ffff7fd34c0  →  <dl_main+0> endbr64
0x00007fffffffddf8│+0x0010: 0x00007fffffffdeb0  →  0x00007fffffffdec0  →  0x0000002000000000
0x00007fffffffde00│+0x0018: 0x00007ffff7ffe750  →  0x00007ffff7fcf000  →  0x00010102464c457f
0x00007fffffffde08│+0x0020: 0x0000000000000000
0x00007fffffffde10│+0x0028: 0x00007ffff7ffe1a0  →  0x0000555555554000  →   jg 0x555555554047
0x00007fffffffde18│+0x0030: 0x00007ffff7fd452e  →  <dl_main+4206> mov -0x170(%rbp), %rdx
0x00007fffffffde20│+0x0038: 0x0000000000000000
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:x86:64 ────
   0x7ffff7fdc1ff <_dl_lookup_symbol_x+15> push   %rbp
   0x7ffff7fdc200 <_dl_lookup_symbol_x+16> mov    %rdx, %rbp
   0x7ffff7fdc203 <_dl_lookup_symbol_x+19> push   %rbx
 → 0x7ffff7fdc204 <_dl_lookup_symbol_x+20> mov    %fs:0x10, %rax
   0x7ffff7fdc20d <_dl_lookup_symbol_x+29> sub    $0xa8, %rsp
   0x7ffff7fdc214 <_dl_lookup_symbol_x+36> mov    %rsi, 0x10(%rsp)
   0x7ffff7fdc219 <_dl_lookup_symbol_x+41> mov    %rcx, 0x20(%rsp)
   0x7ffff7fdc21e <_dl_lookup_symbol_x+46> mov    %r8, 0x8(%rsp)
   0x7ffff7fdc223 <_dl_lookup_symbol_x+51> mov    %r9d, 0x1c(%rsp)
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── source:dl-lookup.c+646 ────
    641    /* Make sure nobody can unload the object while we are at it.  */
    642    if (__glibc_unlikely (flags & DL_LOOKUP_GSCOPE_LOCK))
    643      {
    644        /* We can't just call __rtld_lock_lock_recursive (GL(dl_load_lock))
    645          here, that can result in ABBA deadlock.  */
 →  646        THREAD_GSCOPE_RESET_FLAG ();
    647        __rtld_lock_lock_recursive (GL(dl_load_lock));
    648        /* While MAP value won't change, after THREAD_GSCOPE_RESET_FLAG ()
    649          it can e.g. point to unallocated memory.  So avoid the optimizer
    650          treating the above read from MAP->l_serial as ensurance it
    651          can safely dereference it.  */
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "test", stopped 0x7ffff7fdc204 in _dl_lookup_symbol_x (), reason: SIGSEGV
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0x7ffff7fdc204 → _dl_lookup_symbol_x(undef_name=0x7ffff7ff4144 "__vdso_clock_gettime", undef_map=0x7ffff7ffe750, ref=0x7fffffffdeb0, symbol_scope=0x7ffff7ffeae8, version=0x7fffffffdee0, type_class=0x0, flags=0x0, skip_map=0x0)
[#1] 0x7ffff7fd452e → dl_vdso_vsym(name=0x7ffff7ff4144 "__vdso_clock_gettime")
[#2] 0x7ffff7fd452e → setup_vdso_pointers()
[#3] 0x7ffff7fd452e → dl_main(phdr=<optimized out>, phnum=<optimized out>, user_entry=<optimized out>, auxv=<optimized out>)
[#4] 0x7ffff7febbab → _dl_sysdep_start(start_argptr=0x7fffffffe170, dl_main=0x7ffff7fd34c0 <dl_main>)
[#5] 0x7ffff7fd2fe8 → _dl_start_final(arg=0x7fffffffe170)
[#6] 0x7ffff7fd2fe8 → _dl_start(arg=0x7fffffffe170)
[#7] 0x7ffff7fd2108 → _start()
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤
gef➤  i file
Symbols from "/home/<username>/test/test".
Native process:
        Using the running image of child process 11178.
        While running this, GDB does not access memory from...
Local exec file:
        `/home/<username>/test/test', file type elf64-x86-64.
        Entry point: 0x555555555040
        0x0000555555554318 - 0x0000555555554349 is .interp
        0x0000555555554350 - 0x0000555555554380 is .note.gnu.property
        0x0000555555554380 - 0x00005555555543a4 is .note.gnu.build-id
        0x00005555555543a4 - 0x00005555555543c4 is .note.ABI-tag
        0x00005555555543c8 - 0x00005555555543ec is .gnu.hash
        0x00005555555543f0 - 0x0000555555554480 is .dynsym
        0x0000555555554480 - 0x0000555555554519 is .dynstr
        0x000055555555451a - 0x0000555555554526 is .gnu.version
        0x0000555555554528 - 0x0000555555554548 is .gnu.version_r
        0x0000555555554548 - 0x0000555555554608 is .rela.dyn
        0x0000555555555000 - 0x000055555555501b is .init
        0x0000555555555020 - 0x0000555555555030 is .plt
        0x0000555555555030 - 0x0000555555555040 is .plt.got
        0x0000555555555040 - 0x0000555555555138 is .text
        0x0000555555555138 - 0x0000555555555145 is .fini
        0x0000555555556000 - 0x0000555555556004 is .rodata
        0x0000555555556004 - 0x0000555555556030 is .eh_frame_hdr
        0x0000555555556030 - 0x00005555555560c4 is .eh_frame
        0x0000555555557de0 - 0x0000555555557de8 is .init_array
        0x0000555555557de8 - 0x0000555555557df0 is .fini_array
        0x0000555555557df0 - 0x0000555555557fc0 is .dynamic
        0x0000555555557fc0 - 0x0000555555558000 is .got
        0x0000555555558000 - 0x0000555555558010 is .data
        0x0000555555558010 - 0x0000555555558018 is .bss
        0x00007ffff7fd12a8 - 0x00007ffff7fd12c8 is .note.gnu.property in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7fd12c8 - 0x00007ffff7fd12ec is .note.gnu.build-id in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7fd12f0 - 0x00007ffff7fd13c4 is .hash in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7fd13c8 - 0x00007ffff7fd14c0 is .gnu.hash in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7fd14c0 - 0x00007ffff7fd17f0 is .dynsym in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7fd17f0 - 0x00007ffff7fd1a14 is .dynstr in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7fd1a14 - 0x00007ffff7fd1a58 is .gnu.version in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7fd1a58 - 0x00007ffff7fd1afc is .gnu.version_d in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7fd1b00 - 0x00007ffff7fd1f20 is .rela.dyn in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7fd1f20 - 0x00007ffff7fd1fc8 is .rela.plt in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7fd2000 - 0x00007ffff7fd2080 is .plt in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7fd2080 - 0x00007ffff7fd2090 is .plt.got in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7fd2090 - 0x00007ffff7fd2100 is .plt.sec in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7fd2100 - 0x00007ffff7ff2504 is .text in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7ff3000 - 0x00007ffff7ff7bfb is .rodata in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7ff7bfc - 0x00007ffff7ff8328 is .eh_frame_hdr in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7ff8328 - 0x00007ffff7ffabac is .eh_frame in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7ffc520 - 0x00007ffff7ffce64 is .data.rel.ro in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7ffce68 - 0x00007ffff7ffcfd8 is .dynamic in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7ffcfd8 - 0x00007ffff7ffcfe8 is .got in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7ffd000 - 0x00007ffff7ffd050 is .got.plt in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7ffd060 - 0x00007ffff7ffdff8 is .data in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7ffe000 - 0x00007ffff7ffe198 is .bss in /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
        0x00007ffff7fcf120 - 0x00007ffff7fcf164 is .hash in system-supplied DSO at 0x7ffff7fcf000
        0x00007ffff7fcf168 - 0x00007ffff7fcf1b8 is .gnu.hash in system-supplied DSO at 0x7ffff7fcf000
        0x00007ffff7fcf1b8 - 0x00007ffff7fcf2d8 is .dynsym in system-supplied DSO at 0x7ffff7fcf000
        0x00007ffff7fcf2d8 - 0x00007ffff7fcf34a is .dynstr in system-supplied DSO at 0x7ffff7fcf000
        0x00007ffff7fcf34a - 0x00007ffff7fcf362 is .gnu.version in system-supplied DSO at 0x7ffff7fcf000
        0x00007ffff7fcf368 - 0x00007ffff7fcf3a0 is .gnu.version_d in system-supplied DSO at 0x7ffff7fcf000
        0x00007ffff7fcf3a0 - 0x00007ffff7fcf4b0 is .dynamic in system-supplied DSO at 0x7ffff7fcf000
        0x00007ffff7fcf4b0 - 0x00007ffff7fcf504 is .note in system-supplied DSO at 0x7ffff7fcf000
        0x00007ffff7fcf504 - 0x00007ffff7fcf540 is .eh_frame_hdr in system-supplied DSO at 0x7ffff7fcf000
        0x00007ffff7fcf540 - 0x00007ffff7fcf61c is .eh_frame in system-supplied DSO at 0x7ffff7fcf000
        0x00007ffff7fcf620 - 0x00007ffff7fcfc15 is .text in system-supplied DSO at 0x7ffff7fcf000
        0x00007ffff7fcfc15 - 0x00007ffff7fcfcb1 is .altinstructions in system-supplied DSO at 0x7ffff7fcf000
        0x00007ffff7fcfcb1 - 0x00007ffff7fcfce5 is .altinstr_replacement in system-supplied DSO at 0x7ffff7fcf000
gef➤
gef➤  i shared
From                To                  Syms Read   Shared Object Library
0x00007ffff7fd2100  0x00007ffff7ff2504  Yes         /home/<username>/glibc-2.31/lib/ld-linux-x86-64.so.2
gef➤

在 Ubuntu 22.04:我还尝试构建 glibc-2.32 和 glibc-2.33 并将程序链接到这些版本的 glibc。 2.32 版本也会产生段错误,但 2.33 版本使程序运行良好。

在 Ubuntu 20.04 上:除了不需要修改上面提到的 Makefile 之外,在 Ubuntu 20.04 上构建 glibc-2.31 并将 C 程序链接到自定义 glibc-2.31 会导致正常执行而不会出现段错误。将

libc-2.31.so
ld-linux-x86-64.so.2
文件从 Ubuntu 20.04 内置的自定义 glibc-2.31 移动到 Ubuntu 22.04 环境,并将 C 程序链接到 Ubuntu 22.04 中的这些文件后,程序也可以正常运行,不会立即出现段错误。

使用 Ubuntu 22.04 内置的 glibc-2.31 时出现段错误的原因是什么?我在构建之前是否错误地配置了 glibc?也许 Ubuntu 22.04 有导致 glibc-2.31 构建不正确的文件?

build segmentation-fault glibc wsl-2 ubuntu-22.04
1个回答
0
投票

使用 Ubuntu 22.04 内置的 glibc-2.31 时出现段错误的原因是什么?

我们不知道也无法判断:您遇到了一些错误(您没有告诉我们),您以某种方式修复了该错误(您没有告诉我们)。我怀疑你的修复实际上可能是不正确的,因为当GLIBC-2.31构建时一切正常,没有你的修复(尽管在旧系统上,但是应该不重要)。

您所做的其他一切似乎都是正确的,并且工作正常。

我建议你问一个不同的问题:“我正在尝试在 Ubuntu 22.04 上构建 GLIBC-2.31 并遇到以下错误......我该如何解决这个问题?”

© www.soinside.com 2019 - 2024. All rights reserved.