c - 如果一个简单的 linux c 程序链接到自定义的 glibc 库,则会出现段错误

标签 c linux gcc segmentation-fault

我正在使用 64 位 Ubuntu 14.04.5 LTS(内核:4.4.0-31-generic)。 gcc版本是

gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4

我是 linux c 和 glibc 的新手。我对linux c运行时的内部了解不多。

我有一个非常简单的 C 代码:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char *str = NULL;
    str = (char *)malloc(sizeof(char));
    *str = 'a';

    char *p = (char *)realloc(str, sizeof(char) * 10);
    if (p != NULL)
    {
        str = p;
    }

    printf("%s\n", str);

    return 0;
}

我使用 gcc 编译代码并使其在 x64 linux 上成为 32 位可执行文件。

VirtualBox:/software/code/c++workspace/kernel$ gcc -g -m32 -o malc malloc.c
VirtualBox:/software/code/c++workspace/kernel$ ./malc   #here output a. It's correct
a
VirtualBox:/software/code/c++workspace/kernel$ ldd malc
    linux-gate.so.1 =>  (0xf7712000)
    libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7541000)
    /lib/ld-linux.so.2 (0x565d9000)

这里的演示只是想表明,如果我在操作系统上使用默认库,一切都很好。

我想学习glibc中的一些功能,所以我想编译一个调试x86模式的libc.so对象,然后将它链接到我的代码。

我首先想将 glibc 源代码编译成 64 位模式,然后尝试链接到我的代码以检查我编译的 glibc 是否可以在 64 位运行时运行。

我在尝试将 glibc 编译为 32 位和 64 位时遇到了同样的问题。 所以下面的步骤只是显示尝试编译成 64 位的输出。

我的步骤是: 1)

git clone git://sourceware.org/git/glibc.git
cd glibc
git checkout --track -b local_glibc-2.25 origin/release/2.25/master

2)

VirtualBox:/software/code/c++workspace/glibc_source$ ./glibc/configure --prefix=/software/code/c++workspace/glibc_bin_x64
VirtualBox:/software/code/c++workspace/glibc_source$ make
VirtualBox:/software/code/c++workspace/glibc_source$ make install

3)

 VirtualBox:/software/code/c++workspace/kernel$ gcc -g -O0 -v -da -Q -o malc malloc.c -Wl,-rpath /software/code/c++workspace/glibc_bin_x64/lib
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.4-2ubuntu1~14.04.3' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3) 
COLLECT_GCC_OPTIONS='-g' '-O0' '-v' '-da' '-Q' '-o' 'malc' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/4.8/cc1 -v -imultiarch x86_64-linux-gnu malloc.c -dumpbase malloc.c -da -mtune=generic -march=x86-64 -auxbase malloc -g -O0 -version -fstack-protector -Wformat -Wformat-security -o /tmp/ccREHRcN.s
GNU C (Ubuntu 4.8.4-2ubuntu1~14.04.3) version 4.8.4 (x86_64-linux-gnu)
    compiled by GNU C version 4.8.4, GMP version 5.1.3, MPFR version 3.1.2-p3, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/4.8/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
GNU C (Ubuntu 4.8.4-2ubuntu1~14.04.3) version 4.8.4 (x86_64-linux-gnu)
    compiled by GNU C version 4.8.4, GMP version 5.1.3, MPFR version 3.1.2-p3, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
options passed:  -v -imultiarch x86_64-linux-gnu malloc.c -mtune=generic
 -march=x86-64 -g -O0 -fstack-protector -Wformat -Wformat-security
options enabled:  -faggressive-loop-optimizations
 -fasynchronous-unwind-tables -fauto-inc-dec -fbranch-count-reg -fcommon
 -fdelete-null-pointer-checks -fdwarf2-cfi-asm -fearly-inlining
 -feliminate-unused-debug-types -ffunction-cse -fgcse-lm -fgnu-runtime
 -fgnu-unique -fident -finline-atomics -fira-hoist-pressure
 -fira-share-save-slots -fira-share-spill-slots -fivopts
 -fkeep-static-consts -fleading-underscore -fmath-errno
 -fmerge-debug-strings -fmove-loop-invariants -fpeephole
 -fprefetch-loop-arrays -freg-struct-return -fsched-critical-path-heuristic
 -fsched-dep-count-heuristic -fsched-group-heuristic -fsched-interblock
 -fsched-last-insn-heuristic -fsched-rank-heuristic -fsched-spec
 -fsched-spec-insn-heuristic -fsched-stalled-insns-dep -fshow-column
 -fsigned-zeros -fsplit-ivs-in-unroller -fstack-protector
 -fstrict-volatile-bitfields -fsync-libcalls -ftrapping-math
 -ftree-coalesce-vars -ftree-cselim -ftree-forwprop -ftree-loop-if-convert
 -ftree-loop-im -ftree-loop-ivcanon -ftree-loop-optimize
 -ftree-parallelize-loops= -ftree-phiprop -ftree-pta -ftree-reassoc
 -ftree-scev-cprop -ftree-slp-vectorize -ftree-vect-loop-version
 -funit-at-a-time -funwind-tables -fvar-tracking -fvar-tracking-assignments
 -fzero-initialized-in-bss -m128bit-long-double -m64 -m80387
 -maccumulate-outgoing-args -malign-stringops -mfancy-math-387
 -mfp-ret-in-387 -mfxsr -mglibc -mieee-fp -mlong-double-80 -mmmx -mno-sse4
 -mpush-args -mred-zone -msse -msse2 -mtls-direct-seg-refs
Compiler executable checksum: a0a649d344b1ed798e33d30772d46437
 __bswap_32 __bswap_64 main
Analyzing compilation unit
Performing interprocedural optimizations
 <*free_lang_data> <visibility> <early_local_cleanups> <*free_inline_summary> <whole-program>Assembling functions:
 main
Execution times (seconds)
 phase setup             :   0.00 ( 0%) usr   0.00 ( 0%) sys   0.01 (20%) wall    1106 kB (50%) ggc
 phase parsing           :   0.01 (50%) usr   0.02 (100%) sys   0.03 (60%) wall    1027 kB (47%) ggc
 phase opt and generate  :   0.01 (50%) usr   0.00 ( 0%) sys   0.01 (20%) wall      44 kB ( 2%) ggc
 callgraph optimization  :   0.01 (50%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall       1 kB ( 0%) ggc
 preprocessing           :   0.00 ( 0%) usr   0.00 ( 0%) sys   0.03 (60%) wall     326 kB (15%) ggc
 lexical analysis        :   0.01 (50%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall       0 kB ( 0%) ggc
 parser (global)         :   0.00 ( 0%) usr   0.01 (50%) sys   0.00 ( 0%) wall     483 kB (22%) ggc
 parser enumerator list  :   0.00 ( 0%) usr   0.01 (50%) sys   0.00 ( 0%) wall       2 kB ( 0%) ggc
 rest of compilation     :   0.00 ( 0%) usr   0.00 ( 0%) sys   0.01 (20%) wall       2 kB ( 0%) ggc
 TOTAL                 :   0.02             0.02             0.05               2197 kB
COLLECT_GCC_OPTIONS='-g' '-O0' '-v' '-da' '-Q' '-o' 'malc' '-mtune=generic' '-march=x86-64'
 as -v --64 -o /tmp/cc8sf3O6.o /tmp/ccREHRcN.s
GNU assembler version 2.24 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.24
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.8/:/usr/lib/gcc/x86_64-linux-gnu/4.8/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.8/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.8/:/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-g' '-O0' '-v' '-da' '-Q' '-o' 'malc' '-mtune=generic' '-march=x86-64'
 /usr/lib/gcc/x86_64-linux-gnu/4.8/collect2 --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -z relro -o malc /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.8 -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../.. /tmp/cc8sf3O6.o -rpath /software/code/c++workspace/glibc_bin_x64/lib -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.8/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crtn.o

4)

   VirtualBox:/software/code/c++workspace/kernel$ ldd malc
    linux-vdso.so.1 =>  (0x00007ffeeabf2000)
    libc.so.6 => /software/code/c++workspace/glibc_bin_x64/lib/libc.so.6   (0x00007ff0ede98000)
    /lib64/ld-linux-x86-64.so.2 (0x0000560d287e1000)

  VirtualBox:/software/code/c++workspace/kernel$ ./malc
  Segmentation fault

我对 linux c 编程了解不多。也许输出提供了线索。

我的问题是,如果链接到我自己编译的glibc共享库,为什么程序不能运行?

更新 1: 添加 gdb 输出:

VirtualBox:/software/code/c++workspace/kernel$ gdb ./malc
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
....
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./malc...done.
gdb-peda$ run
Starting program: /software/code/c++workspace/kernel/malc 

Program received signal SIGSEGV, Segmentation fault.

[----------------------------------registers-----------------------------------]
RAX: 0x7ffff7ffccc0 --> 0x4040d00000000 
RBX: 0x7ffff7a40000 (jg     0x7ffff7a40047)
RCX: 0x7ffff7dee828 (<_dl_open+904>:    sub    %eax,%esp)
RDX: 0x7fffffffdad8 --> 0x7fffffffdae0 --> 0x2000000000 ('')
RSI: 0x7ffff7dee4a0 (<_dl_open>:    push   %rbp)
RDI: 0x7ffff7b9e892 (pop    %rdi)
RBP: 0x7fffffffdc70 --> 0x7fffffffdd80 --> 0x9 ('\t')
RSP: 0x7fffffffdab8 --> 0x7ffff7b5bd6d (mov    0x18(%rsp),%rdx)
RIP: 0x0 
R8 : 0x7fffffffdb10 --> 0x7ffff7b9cbe8 (rex.WR)
R9 : 0x0 
R10: 0x0 
R11: 0x0 
R12: 0x7ffff7a5fa88 (pushq  $0x3940)
R13: 0x7ffff7a5fb00 (sbb    %al,0x39(%rax))
R14: 0x394080 
R15: 0x7ffff7ff75b0 --> 0x7ffff7a40000 (jg     0x7ffff7a40047)
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x0
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffdab8 --> 0x7ffff7b5bd6d (mov    0x18(%rsp),%rdx)
0008| 0x7fffffffdac0 --> 0x7fff00000000 
0016| 0x7fffffffdac8 --> 0x0 
0024| 0x7fffffffdad0 --> 0x0 
0032| 0x7fffffffdad8 --> 0x7fffffffdae0 --> 0x2000000000 ('')
0040| 0x7fffffffdae0 --> 0x2000000000 ('')
0048| 0x7fffffffdae8 --> 0x0 
0056| 0x7fffffffdaf0 --> 0x0 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x0000000000000000 in ?? ()
gdb-peda$ bt
#0  0x0000000000000000 in ?? ()
#1  0x00007ffff7b5bd6d in ?? ()
#2  0x00007fff00000000 in ?? ()
#3  0x0000000000000000 in ?? ()
gdb-peda$

更新 2: 根据回复,我将代码更改为:

int main()
{
    char *str = NULL;
    //str = (char *)malloc(sizeof(char));
    //*str = 'a';

    str = malloc(sizeof(*str)*2);
    memset(str,0,sizeof(*str)*2);
    //strcpy(str,"a");
    str[0]='a';
    ////str[1]='\n';  //here is a mistake.
    str[1]='\0';      

    char *p = (char *)realloc(str, sizeof(char) * 10);
    if (p != NULL)
    {
        str = p;
    }

    printf("%s\n", str);

    return 0;
}

VirtualBox:/software/code/c++workspace/kernel$ gcc -g -O0 -v -da -Q -o malc malloc.c
VirtualBox:/software/code/c++workspace/kernel$ ./malc
a

VirtualBox:/software/code/c++workspace/kernel$ gcc -g -O0 -v -da -Q -o malc malloc.c -Wl,-rpath /software/code/c++workspace/glibc_bin_x64/lib
VirtualBox:/software/code/c++workspace/kernel$ ./malc
Segmentation fault

更新 3:我更改了代码,安装了 valgrind,并提供了 valgrind 输出。

我想我编译的libc.so很可能有一些不同。我没有发布 glibc 的配置/制作/制作安装,因为我认为我已经正确安装了 libc.so(我在安装过程中没有看到任何列出的错误)。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char *str = NULL;
    str = malloc(4);
    strcpy(str,"a"); 
    printf("%s\n", str);

    return 0;
}

VirtualBox:/software/code/c++workspace/kernel$ gcc -g -O0 -v -da -Q -o malc malloc.c -Wl,-rpath /software/code/c++workspace/glibc_bin_x64/lib

VirtualBox:/software/code/c++workspace/kernel$ valgrind -v --tool=memcheck --leak-check=full ./malc

==27238== Memcheck, a memory error detector
==27238== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==27238== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==27238== Command: ./malc
==27238== 
--27238-- Valgrind options:
--27238--    -v
--27238--    --tool=memcheck
--27238--    --leak-check=full
--27238-- Contents of /proc/version:
--27238--   Linux version 4.4.0-31-generic (buildd@lgw01-43) (gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3) ) #50~14.04.1-Ubuntu SMP Wed Jul 13 01:07:32 UTC 2016
--27238-- Arch and hwcaps: AMD64, LittleEndian, amd64-cx16-rdtscp-sse3-avx
--27238-- Page sizes: currently 4096, max supported 4096
--27238-- Valgrind library directory: /usr/lib/valgrind
--27238-- Reading syms from /software/code/c++workspace/kernel/malc
--27238-- Reading syms from /lib/x86_64-linux-gnu/ld-2.19.so
--27238--   Considering /lib/x86_64-linux-gnu/ld-2.19.so ..
--27238--   .. CRC mismatch (computed 84cd48b7 wanted 021f91fa)
--27238--   Considering /usr/lib/debug/lib/x86_64-linux-gnu/ld-2.19.so ..
--27238--   .. CRC is valid
--27238-- Reading syms from /usr/lib/valgrind/memcheck-amd64-linux
--27238--   Considering /usr/lib/valgrind/memcheck-amd64-linux ..
--27238--   .. CRC mismatch (computed fed8e6c5 wanted e6be554a)
--27238--    object doesn't have a symbol table
--27238--    object doesn't have a dynamic symbol table
--27238-- Scheduler: using generic scheduler lock implementation.
--27238-- Reading suppressions file: /usr/lib/valgrind/default.supp
==27238== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-27238-by-abbott-on-???
==27238== embedded gdbserver: writing to   /tmp/vgdb-pipe-to-vgdb-from-27238-by-abbott-on-???
==27238== embedded gdbserver: shared mem   /tmp/vgdb-pipe-shared-mem-vgdb-27238-by-abbott-on-???
==27238== 
==27238== TO CONTROL THIS PROCESS USING vgdb (which you probably
==27238== don't want to do, unless you know exactly what you're doing,
==27238== or are doing some strange experiment):
==27238==   /usr/lib/valgrind/../../bin/vgdb --pid=27238 ...command...
==27238== 
==27238== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==27238==   /path/to/gdb ./malc
==27238== and then give GDB the following command
==27238==   target remote | /usr/lib/valgrind/../../bin/vgdb --pid=27238
==27238== --pid is optional if only one valgrind process is running
==27238== 
--27238-- REDIR: 0x4019e20 (ld-linux-x86-64.so.2:strlen) redirected to 0x380764b1 (???)
--27238-- Reading syms from /usr/lib/valgrind/vgpreload_core-amd64-linux.so
--27238--   Considering /usr/lib/valgrind/vgpreload_core-amd64-linux.so ..
--27238--   .. CRC mismatch (computed 4bcdfe99 wanted 3143e841)
--27238--    object doesn't have a symbol table
--27238-- Reading syms from /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so
--27238--   Considering /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so ..
--27238--   .. CRC mismatch (computed 3df18bf1 wanted 14fefe1c)
--27238--    object doesn't have a symbol table
==27238== WARNING: new redirection conflicts with existing -- ignoring it
--27238--     old: 0x04019e20 (strlen              ) R-> (0000.0) 0x380764b1 ???
--27238--     new: 0x04019e20 (strlen              ) R-> (2007.0) 0x04c2e1a0 strlen
--27238-- REDIR: 0x4019bd0 (ld-linux-x86-64.so.2:index) redirected to 0x4c2dd50 (index)
--27238-- REDIR: 0x4019df0 (ld-linux-x86-64.so.2:strcmp) redirected to 0x4c2f2f0 (strcmp)
--27238-- REDIR: 0x401ab40 (ld-linux-x86-64.so.2:mempcpy) redirected to 0x4c31da0 (mempcpy)
--27238-- Reading syms from /software/code/c++workspace/glibc_bin_x64/lib/libc-2.25.so
--27238-- REDIR: 0x4eba880 (libc.so.6:strcasecmp) redirected to 0x4a25720 (_vgnU_ifunc_wrapper)
==27238== Jump to the invalid address stated on the next line
==27238==    at 0x0: ???
==27238==    by 0x40043A1: dl_main (rtld.c:2237)
==27238==    by 0x40176F4: _dl_sysdep_start (dl-sysdep.c:249)
==27238==    by 0x4001BB7: _dl_start_final (rtld.c:347)
==27238==    by 0x4001BB7: _dl_start (rtld.c:573)
==27238==    by 0x4001267: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==27238==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==27238== 
==27238== 
==27238== Process terminating with default action of signal 11 (SIGSEGV)
==27238==  Bad permissions for mapped region at address 0x0
==27238==    at 0x0: ???
==27238==    by 0x40043A1: dl_main (rtld.c:2237)
==27238==    by 0x40176F4: _dl_sysdep_start (dl-sysdep.c:249)
==27238==    by 0x4001BB7: _dl_start_final (rtld.c:347)
==27238==    by 0x4001BB7: _dl_start (rtld.c:573)
==27238==    by 0x4001267: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==27238== Jump to the invalid address stated on the next line
==27238==    at 0x5A6: ???
==27238==    by 0x4F52D6C: _dl_vdso_vsym (dl-vdso.c:40)
==27238==    by 0x4EDE814: time (in /software/code/c++workspace/glibc_bin_x64/lib/libc-2.25.so)
==27238==    by 0x400C4EA: elf_machine_lazy_rel (dl-machine.h:529)
==27238==    by 0x400C4EA: elf_dynamic_do_Rela (do-rel.h:77)
==27238==    by 0x400C4EA: _dl_relocate_object (dl-reloc.c:264)
==27238==    by 0x40043A1: dl_main (rtld.c:2237)
==27238==    by 0x40176F4: _dl_sysdep_start (dl-sysdep.c:249)
==27238==    by 0x4001BB7: _dl_start_final (rtld.c:347)
==27238==    by 0x4001BB7: _dl_start (rtld.c:573)
==27238==    by 0x4001267: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==27238==  Address 0x5a6 is not stack'd, malloc'd or (recently) free'd
==27238== 
==27238== 
==27238== Process terminating with default action of signal 11 (SIGSEGV)
==27238==  Bad permissions for mapped region at address 0x5A6
==27238==    at 0x5A6: ???
==27238==    by 0x4F52D6C: _dl_vdso_vsym (dl-vdso.c:40)
==27238==    by 0x4EDE814: time (in /software/code/c++workspace/glibc_bin_x64/lib/libc-2.25.so)
==27238==    by 0x400C4EA: elf_machine_lazy_rel (dl-machine.h:529)
==27238==    by 0x400C4EA: elf_dynamic_do_Rela (do-rel.h:77)
==27238==    by 0x400C4EA: _dl_relocate_object (dl-reloc.c:264)
==27238==    by 0x40043A1: dl_main (rtld.c:2237)
==27238==    by 0x40176F4: _dl_sysdep_start (dl-sysdep.c:249)
==27238==    by 0x4001BB7: _dl_start_final (rtld.c:347)
==27238==    by 0x4001BB7: _dl_start (rtld.c:573)
==27238==    by 0x4001267: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==27238== 
==27238== HEAP SUMMARY:
==27238==     in use at exit: 0 bytes in 0 blocks
==27238==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==27238== 
==27238== All heap blocks were freed -- no leaks are possible
==27238== 
==27238== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
==27238== 
==27238== 1 errors in context 1 of 2:
==27238== Jump to the invalid address stated on the next line
==27238==    at 0x5A6: ???
==27238==    by 0x4F52D6C: _dl_vdso_vsym (dl-vdso.c:40)
==27238==    by 0x4EDE814: time (in /software/code/c++workspace/glibc_bin_x64/lib/libc-2.25.so)
==27238==    by 0x400C4EA: elf_machine_lazy_rel (dl-machine.h:529)
==27238==    by 0x400C4EA: elf_dynamic_do_Rela (do-rel.h:77)
==27238==    by 0x400C4EA: _dl_relocate_object (dl-reloc.c:264)
==27238==    by 0x40043A1: dl_main (rtld.c:2237)
==27238==    by 0x40176F4: _dl_sysdep_start (dl-sysdep.c:249)
==27238==    by 0x4001BB7: _dl_start_final (rtld.c:347)
==27238==    by 0x4001BB7: _dl_start (rtld.c:573)
==27238==    by 0x4001267: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==27238==  Address 0x5a6 is not stack'd, malloc'd or (recently) free'd
==27238== 
==27238== 
==27238== 1 errors in context 2 of 2:
==27238== Jump to the invalid address stated on the next line
==27238==    at 0x0: ???
==27238==    by 0x40043A1: dl_main (rtld.c:2237)
==27238==    by 0x40176F4: _dl_sysdep_start (dl-sysdep.c:249)
==27238==    by 0x4001BB7: _dl_start_final (rtld.c:347)
==27238==    by 0x4001BB7: _dl_start (rtld.c:573)
==27238==    by 0x4001267: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==27238==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==27238== 
==27238== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault

最佳答案

这与您编译代码的方式无关。您的代码中有一个巨大而明显的错误。

C 中的字符串必须以 NUL 终止,否则当您尝试对字符串执行某些操作(即打印出来)时,您会得到未定义的行为。这正是这里发生的事情。

如果你改变

str = (char *)malloc(sizeof(char));
*str = 'a';

成为

str = malloc(sizeof(*str)*2);
strcpy(str,"a");

您将为所需的 2 个字符(“a”和“\0”)分配足够的空间,strcpy 将为您添加“\0”字符。

或者,您可以像这样替换 strcpy 并自己添加 NUL 字符

str[0]='a';
str[1]='\0';

或者像这样用memset确保你的内存完全设置为0

memset(str,0,sizeof(*str)*2);

关于c - 如果一个简单的 linux c 程序链接到自定义的 glibc 库,则会出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45434150/

相关文章:

c++ - 如果直接跟随形成有效标识符的字符,则宏变量不会扩展

c - 从字符中提取位序列

linux - IPC::Open3 以不同于独立 snmwalk 命令的行为运行 snmpwalk

c++ - 在编译之前解析文件

C:编写可以自动矢量化的代码,嵌套循环,GCC

c - 如何从 ELF 文件中提取通过编译器优化添加的常量地址?

从 LKM 在/proc 中创建条目

linux - 使用带有 Go 和 GoCV 的 OpenVINO 加载预训练的 DNN 模型 - 符号查找错误

linux - 确定 Linux 下的标准文件位置

python - 由于 gcc 错误,无法使用 pip 安装 sasl