成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

漲知識了,Linux的ld和ldd一起用,可以幫我們分析運行時加載庫文件失敗的原因

系統 Linux
本篇文章以分析 libmpi_usempif80.so 這個動態庫文件,依賴哪些其他動態庫,作為問題起因。

很多時候,開發人員/運維人員需要處理軟件運行時報錯找不到依賴庫的問題,除了可以通過strace、gdb等工具跟蹤啟動加載的過程獲得依賴庫信息,還可以通過本文介紹的 ld + ldd 命令,幫助分析。

這里以分析 libmpi_usempif80.so 這個動態庫文件,依賴哪些其他動態庫,作為問題起因。

首先介紹 ld 命令如何幫我們分析mpi_usempif80 庫依賴其他哪些庫?mpi_usempif80 庫被加載時,會從當前系統的哪些路徑下搜索這些庫?

#ld -lmpi_usempif08 --verbose

GNU ld (GNU Binutils for Ubuntu) 2.38
  Supported emulations:
   elf_x86_64
   elf32_x86_64
   elf_i386
   elf_iamcu
   elf_l1om
   elf_k1om
   i386pep
   i386pe
using internal linker script:
==================================================
/* Script for -z combreloc -z separate-code */
/* Copyright (C) 2014-2022 Free Software Foundation, Inc.
   Copying and distribution of this script, with or without modification,
   are permitted in any medium without royalty provided the copyright
   notice and this notice are preserved.  */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
       "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu"); SEARCH_DIR("=/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib64"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib");
SECTIONS
{
  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
  .interp         : { *(.interp) }
  .note.gnu.build-id  : { *(.note.gnu.build-id) }
  .hash           : { *(.hash) }
  .gnu.hash       : { *(.gnu.hash) }
  .dynsym         : { *(.dynsym) }
  .dynstr         : { *(.dynstr) }
  .gnu.version    : { *(.gnu.version) }
  .gnu.version_d  : { *(.gnu.version_d) }
  .gnu.version_r  : { *(.gnu.version_r) }
  .rela.dyn       :
    {
      *(.rela.init)
      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
      *(.rela.fini)
      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
      *(.rela.ctors)
      *(.rela.dtors)
      *(.rela.got)
      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
      *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
      *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
      *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
      *(.rela.ifunc)
    }
  .rela.plt       :
    {
      *(.rela.plt)
      PROVIDE_HIDDEN (__rela_iplt_start = .);
      *(.rela.iplt)
      PROVIDE_HIDDEN (__rela_iplt_end = .);
    }
  .relr.dyn : { *(.relr.dyn) }
  . = ALIGN(CONSTANT (MAXPAGESIZE));
  .init           :
  {
    KEEP (*(SORT_NONE(.init)))
  }
  .plt            : { *(.plt) *(.iplt) }
.plt.got        : { *(.plt.got) }
.plt.sec        : { *(.plt.sec) }
  .text           :
  {
    *(.text.unlikely .text.*_unlikely .text.unlikely.*)
    *(.text.exit .text.exit.*)
    *(.text.startup .text.startup.*)
    *(.text.hot .text.hot.*)
    *(SORT(.text.sorted.*))
    *(.text .stub .text.* .gnu.linkonce.t.*)
    /* .gnu.warning sections are handled specially by elf.em.  */
    *(.gnu.warning)
  }
  .fini           :
  {
    KEEP (*(SORT_NONE(.fini)))
  }
  PROVIDE (__etext = .);
  PROVIDE (_etext = .);
  PROVIDE (etext = .);
  . = ALIGN(CONSTANT (MAXPAGESIZE));
  /* Adjust the address for the rodata segment.  We want to adjust up to
     the same address within the page on the next page up.  */
  . = SEGMENT_START("rodata-segment", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));
  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
  .rodata1        : { *(.rodata1) }
  .eh_frame_hdr   : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
  .gnu_extab   : ONLY_IF_RO { *(.gnu_extab*) }
  /* These sections are generated by the Sun/Oracle C++ compiler.  */
  .exception_ranges   : ONLY_IF_RO { *(.exception_ranges*) }
  /* Adjust the address for the data segment.  We want to adjust up to
     the same address within the page on the next page up.  */
  . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
  /* Exception handling  */
  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
  .gnu_extab      : ONLY_IF_RW { *(.gnu_extab) }
  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
  .exception_ranges   : ONLY_IF_RW { *(.exception_ranges*) }
  /* Thread Local Storage sections  */
  .tdata   :
   {
     PROVIDE_HIDDEN (__tdata_start = .);
     *(.tdata .tdata.* .gnu.linkonce.td.*)
   }
  .tbss    : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
  .preinit_array    :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  }
  .init_array    :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
    KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
    PROVIDE_HIDDEN (__init_array_end = .);
  }
  .fini_array    :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
    KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
    PROVIDE_HIDDEN (__fini_array_end = .);
  }
  .ctors          :
  {
    /* gcc uses crtbegin.o to find the start of
       the constructors, so we make sure it is
       first.  Because this is a wildcard, it
       doesn't matter if the user does not
       actually link against crtbegin.o; the
       linker won't look for a file to match a
       wildcard.  The wildcard also means that it
       doesn't matter which directory crtbegin.o
       is in.  */
    KEEP (*crtbegin.o(.ctors))
    KEEP (*crtbegin?.o(.ctors))
    /* We don't want to include the .ctor section from
       the crtend.o file until after the sorted ctors.
       The .ctor section from the crtend file contains the
       end of ctors marker and it must be last */
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
  }
  .dtors          :
  {
    KEEP (*crtbegin.o(.dtors))
    KEEP (*crtbegin?.o(.dtors))
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
  }
  .jcr            : { KEEP (*(.jcr)) }
  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
  .dynamic        : { *(.dynamic) }
  .got            : { *(.got) *(.igot) }
  . = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
  .got.plt        : { *(.got.plt) *(.igot.plt) }
  .data           :
  {
    *(.data .data.* .gnu.linkonce.d.*)
    SORT(CONSTRUCTORS)
  }
  .data1          : { *(.data1) }
  _edata = .; PROVIDE (edata = .);
  . = .;
  __bss_start = .;
  .bss            :
  {
   *(.dynbss)
   *(.bss .bss.* .gnu.linkonce.b.*)
   *(COMMON)
   /* Align here to ensure that the .bss section occupies space up to
      _end.  Align after .bss to ensure correct alignment even if the
      .bss section disappears because there are no input sections.
      FIXME: Why do we need it? When there is no .bss section, we do not
      pad the .data section.  */
   . = ALIGN(. != 0 ? 64 / 8 : 1);
  }
  .lbss   :
  {
    *(.dynlbss)
    *(.lbss .lbss.* .gnu.linkonce.lb.*)
    *(LARGE_COMMON)
  }
  . = ALIGN(64 / 8);
  . = SEGMENT_START("ldata-segment", .);
  .lrodata   ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
  {
    *(.lrodata .lrodata.* .gnu.linkonce.lr.*)
  }
  .ldata   ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
  {
    *(.ldata .ldata.* .gnu.linkonce.l.*)
    . = ALIGN(. != 0 ? 64 / 8 : 1);
  }
  . = ALIGN(64 / 8);
  _end = .; PROVIDE (end = .);
  . = DATA_SEGMENT_END (.);
  /* Stabs debugging sections.  */
  .stab          0 : { *(.stab) }
  .stabstr       0 : { *(.stabstr) }
  .stab.excl     0 : { *(.stab.excl) }
  .stab.exclstr  0 : { *(.stab.exclstr) }
  .stab.index    0 : { *(.stab.index) }
  .stab.indexstr 0 : { *(.stab.indexstr) }
  .comment       0 : { *(.comment) }
  .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
  /* DWARF debug sections.
     Symbols in the DWARF debugging sections are relative to the beginning
     of the section so we begin them at 0.  */
  /* DWARF 1.  */
  .debug          0 : { *(.debug) }
  .line           0 : { *(.line) }
  /* GNU DWARF 1 extensions.  */
  .debug_srcinfo  0 : { *(.debug_srcinfo) }
  .debug_sfnames  0 : { *(.debug_sfnames) }
  /* DWARF 1.1 and DWARF 2.  */
  .debug_aranges  0 : { *(.debug_aranges) }
  .debug_pubnames 0 : { *(.debug_pubnames) }
  /* DWARF 2.  */
  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
  .debug_abbrev   0 : { *(.debug_abbrev) }
  .debug_line     0 : { *(.debug_line .debug_line.* .debug_line_end) }
  .debug_frame    0 : { *(.debug_frame) }
  .debug_str      0 : { *(.debug_str) }
  .debug_loc      0 : { *(.debug_loc) }
  .debug_macinfo  0 : { *(.debug_macinfo) }
  /* SGI/MIPS DWARF 2 extensions.  */
  .debug_weaknames 0 : { *(.debug_weaknames) }
  .debug_funcnames 0 : { *(.debug_funcnames) }
  .debug_typenames 0 : { *(.debug_typenames) }
  .debug_varnames  0 : { *(.debug_varnames) }
  /* DWARF 3.  */
  .debug_pubtypes 0 : { *(.debug_pubtypes) }
  .debug_ranges   0 : { *(.debug_ranges) }
  /* DWARF 5.  */
  .debug_addr     0 : { *(.debug_addr) }
  .debug_line_str 0 : { *(.debug_line_str) }
  .debug_loclists 0 : { *(.debug_loclists) }
  .debug_macro    0 : { *(.debug_macro) }
  .debug_names    0 : { *(.debug_names) }
  .debug_rnglists 0 : { *(.debug_rnglists) }
  .debug_str_offsets 0 : { *(.debug_str_offsets) }
  .debug_sup      0 : { *(.debug_sup) }
  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}


==================================================
ld: mode elf_x86_64
attempt to open /usr/local/lib/x86_64-linux-gnu/libmpi_usempif08.so failed
attempt to open /usr/local/lib/x86_64-linux-gnu/libmpi_usempif08.a failed
attempt to open /lib/x86_64-linux-gnu/libmpi_usempif08.so succeeded
/lib/x86_64-linux-gnu/libmpi_usempif08.so
libmpi_mpifh.so.40 needed by /lib/x86_64-linux-gnu/libmpi_usempif08.so
attempt to open /build/openmpi-RCkqwI/openmpi-4.1.2/debian/build-gfortran/ompi/mpi/fortran/mpif-h/.libs/libmpi_mpifh.so.40 failed
attempt to open /build/openmpi-RCkqwI/openmpi-4.1.2/debian/build-gfortran/ompi/.libs/libmpi_mpifh.so.40 failed
attempt to open /usr/lib/x86_64-linux-gnu/openmpi/lib/libmpi_mpifh.so.40 failed
attempt to open /usr/lib/x86_64-linux-gnu/libfakeroot/libmpi_mpifh.so.40 failed
attempt to open /usr/local/lib/libmpi_mpifh.so.40 failed
found libmpi_mpifh.so.40 at /usr/lib/x86_64-linux-gnu/libmpi_mpifh.so.40
libmpi.so.40 needed by /lib/x86_64-linux-gnu/libmpi_usempif08.so
attempt to open /build/openmpi-RCkqwI/openmpi-4.1.2/debian/build-gfortran/ompi/mpi/fortran/mpif-h/.libs/libmpi.so.40 failed
attempt to open /build/openmpi-RCkqwI/openmpi-4.1.2/debian/build-gfortran/ompi/.libs/libmpi.so.40 failed
attempt to open /usr/lib/x86_64-linux-gnu/openmpi/lib/libmpi.so.40 failed
attempt to open /usr/lib/x86_64-linux-gnu/libfakeroot/libmpi.so.40 failed
attempt to open /usr/local/lib/libmpi.so.40 failed
found libmpi.so.40 at /usr/lib/x86_64-linux-gnu/libmpi.so.40
libc.so.6 needed by /lib/x86_64-linux-gnu/libmpi_usempif08.so
attempt to open /build/openmpi-RCkqwI/openmpi-4.1.2/debian/build-gfortran/ompi/mpi/fortran/mpif-h/.libs/libc.so.6 failed
attempt to open /build/openmpi-RCkqwI/openmpi-4.1.2/debian/build-gfortran/ompi/.libs/libc.so.6 failed
attempt to open /usr/lib/x86_64-linux-gnu/openmpi/lib/libc.so.6 failed
attempt to open /usr/lib/x86_64-linux-gnu/libfakeroot/libc.so.6 failed
attempt to open /usr/local/lib/libc.so.6 failed
attempt to open /usr/lib/x86_64-linux-gnu/fortran/gfortran/libc.so.6 failed
attempt to open /usr/lib/x86_64-linux-gnu/openmpi/lib/libc.so.6 failed
attempt to open /usr/local/lib/x86_64-linux-gnu/libc.so.6 failed
attempt to open /usr/local/lib/x86_64-linux-gnu/libc.so.6 failed
attempt to open /usr/lib/x86_64-linux-gnu64/libc.so.6 failed
attempt to open /usr/local/lib64/libc.so.6 failed
attempt to open /lib64/libc.so.6 failed
attempt to open /usr/lib64/libc.so.6 failed
attempt to open /usr/local/lib/libc.so.6 failed
attempt to open /lib/libc.so.6 failed
attempt to open /usr/lib/libc.so.6 failed
attempt to open /usr/x86_64-linux-gnu/lib64/libc.so.6 failed
attempt to open /usr/x86_64-linux-gnu/lib/libc.so.6 failed
attempt to open /build/openmpi-RCkqwI/openmpi-4.1.2/debian/build-gfortran/ompi/mpi/fortran/mpif-h/.libs/libc.so.6 failed
attempt to open /build/openmpi-RCkqwI/openmpi-4.1.2/debian/build-gfortran/ompi/.libs/libc.so.6 failed
attempt to open /usr/lib/x86_64-linux-gnu/openmpi/lib/libc.so.6 failed
attempt to open /usr/lib/x86_64-linux-gnu/libfakeroot/libc.so.6 failed
attempt to open /usr/local/lib/libc.so.6 failed
found libc.so.6 at /usr/lib/x86_64-linux-gnu/libc.so.6
libopen-pal.so.40 needed by /usr/lib/x86_64-linux-gnu/libmpi_mpifh.so.40
attempt to open /build/openmpi-RCkqwI/openmpi-4.1.2/debian/build-gfortran/ompi/.libs/libopen-pal.so.40 failed
attempt to open /build/openmpi-RCkqwI/openmpi-4.1.2/debian/build-gfortran/opal/.libs/libopen-pal.so.40 failed
attempt to open /usr/lib/x86_64-linux-gnu/openmpi/lib/libopen-pal.so.40 failed
attempt to open /usr/lib/x86_64-linux-gnu/libfakeroot/libopen-pal.so.40 failed
attempt to open /usr/local/lib/libopen-pal.so.40 failed
found libopen-pal.so.40 at /usr/lib/x86_64-linux-gnu/libopen-pal.so.40
libopen-rte.so.40 needed by /usr/lib/x86_64-linux-gnu/libmpi.so.40
attempt to open /usr/lib/x86_64-linux-gnu/openmpi/lib/libopen-rte.so.40 failed
attempt to open /usr/lib/x86_64-linux-gnu/libfakeroot/libopen-rte.so.40 failed
attempt to open /usr/local/lib/libopen-rte.so.40 failed
found libopen-rte.so.40 at /usr/lib/x86_64-linux-gnu/libopen-rte.so.40
libm.so.6 needed by /usr/lib/x86_64-linux-gnu/libmpi.so.40
attempt to open /usr/lib/x86_64-linux-gnu/openmpi/lib/libm.so.6 failed
attempt to open /usr/lib/x86_64-linux-gnu/libfakeroot/libm.so.6 failed
attempt to open /usr/local/lib/libm.so.6 failed
found libm.so.6 at /usr/lib/x86_64-linux-gnu/libm.so.6
libhwloc.so.15 needed by /usr/lib/x86_64-linux-gnu/libmpi.so.40
attempt to open /usr/lib/x86_64-linux-gnu/openmpi/lib/libhwloc.so.15 failed
attempt to open /usr/lib/x86_64-linux-gnu/libfakeroot/libhwloc.so.15 failed
attempt to open /usr/local/lib/libhwloc.so.15 failed
found libhwloc.so.15 at /usr/lib/x86_64-linux-gnu/libhwloc.so.15
ld-linux-x86-64.so.2 needed by /usr/lib/x86_64-linux-gnu/libc.so.6
attempt to open /usr/lib/x86_64-linux-gnu/libfakeroot/ld-linux-x86-64.so.2 failed
attempt to open /usr/local/lib/ld-linux-x86-64.so.2 failed
found ld-linux-x86-64.so.2 at /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
libevent_core-2.1.so.7 needed by /usr/lib/x86_64-linux-gnu/libopen-pal.so.40
attempt to open /usr/lib/x86_64-linux-gnu/libfakeroot/libevent_core-2.1.so.7 failed
attempt to open /usr/local/lib/libevent_core-2.1.so.7 failed
found libevent_core-2.1.so.7 at /usr/lib/x86_64-linux-gnu/libevent_core-2.1.so.7
libevent_pthreads-2.1.so.7 needed by /usr/lib/x86_64-linux-gnu/libopen-pal.so.40
attempt to open /usr/lib/x86_64-linux-gnu/libfakeroot/libevent_pthreads-2.1.so.7 failed
attempt to open /usr/local/lib/libevent_pthreads-2.1.so.7 failed
found libevent_pthreads-2.1.so.7 at /usr/lib/x86_64-linux-gnu/libevent_pthreads-2.1.so.7
libz.so.1 needed by /usr/lib/x86_64-linux-gnu/libopen-rte.so.40
attempt to open /usr/lib/x86_64-linux-gnu/openmpi/lib/libz.so.1 failed
attempt to open /usr/lib/x86_64-linux-gnu/libfakeroot/libz.so.1 failed
attempt to open /usr/local/lib/libz.so.1 failed
found libz.so.1 at /usr/lib/x86_64-linux-gnu/libz.so.1
libudev.so.1 needed by /usr/lib/x86_64-linux-gnu/libhwloc.so.15
attempt to open /usr/lib/x86_64-linux-gnu/libfakeroot/libudev.so.1 failed
attempt to open /usr/local/lib/libudev.so.1 failed
found libudev.so.1 at /usr/lib/x86_64-linux-gnu/libudev.so.1


ld -lmpi_usempif08 --verbose | grep found
found libmpi_mpifh.so.40 at /usr/lib/x86_64-linux-gnu/libmpi_mpifh.so.40
found libmpi.so.40 at /usr/lib/x86_64-linux-gnu/libmpi.so.40
ld: warning: cannot find entry symbol _start; not setting start address
found libc.so.6 at /usr/lib/x86_64-linux-gnu/libc.so.6
found libopen-pal.so.40 at /usr/lib/x86_64-linux-gnu/libopen-pal.so.40
found libopen-rte.so.40 at /usr/lib/x86_64-linux-gnu/libopen-rte.so.40
found libm.so.6 at /usr/lib/x86_64-linux-gnu/libm.so.6
found libhwloc.so.15 at /usr/lib/x86_64-linux-gnu/libhwloc.so.15
found ld-linux-x86-64.so.2 at /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
found libevent_core-2.1.so.7 at /usr/lib/x86_64-linux-gnu/libevent_core-2.1.so.7
found libevent_pthreads-2.1.so.7 at /usr/lib/x86_64-linux-gnu/libevent_pthreads-2.1.so.7
found libz.so.1 at /usr/lib/x86_64-linux-gnu/libz.so.1
found libudev.so.1 at /usr/lib/x86_64-linux-gnu/libudev.so.1

上面這段信息很長,有很多有價值的信息,如果你只想看關鍵部分,那么我保留其中的關鍵內容,來一個精華版的輸出信息:

#ld -lmpi_usempif08 --verbose

GNU ld (GNU Binutils for Ubuntu) 2.38
  Supported emulations:
   elf_x86_64
……
using internal linker script:

   notice and this notice are preserved.  */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
       "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)  # 運行時可執行文件從代碼段的 _start 位置開始運行。

# 運行時需從哪些目錄找動態庫文件
SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu"); SEARCH_DIR("=/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib64"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib");

# 二進制文件有哪些的代碼段、數據段
SECTIONS
{
  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
  .interp         : { *(.interp) }
……
  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }

……
  /* Thread Local Storage sections  */
  # 線程本地存儲區域
  .tdata   :
   {
     PROVIDE_HIDDEN (__tdata_start = .);
     *(.tdata .tdata.* .gnu.linkonce.td.*)
   }
  .tbss    : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
  .preinit_array    :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  }
  # 數據區
  .data           :
  {
    *(.data .data.* .gnu.linkonce.d.*)
    SORT(CONSTRUCTORS)
  }
  .data1          : { *(.data1) }
  _edata = .; PROVIDE (edata = .);
  . = .;
  __bss_start = .;
  
  # BSS區
  .bss            :
  {
   ……
  }
 ……
}

# 下面是本文的重點關注部分
==================================================

# 文件1:逐個目錄匹配是否找到被依賴的libmpi_usempif08.so 庫文件
ld: mode elf_x86_64
attempt to open /usr/local/lib/x86_64-linux-gnu/libmpi_usempif08.so failed
attempt to open /usr/local/lib/x86_64-linux-gnu/libmpi_usempif08.a failed
attempt to open /lib/x86_64-linux-gnu/libmpi_usempif08.so succeeded
# 找到了 libmpi_usempif08.so 庫文件

# 文件2:逐個目錄匹配是否找到被依賴的 libmpi_mpifh.so 庫文件
libmpi_mpifh.so.40 needed by /lib/x86_64-linux-gnu/libmpi_usempif08.so
attempt to open /build/openmpi-RCkqwI/openmpi-4.1.2/debian/build-gfortran/ompi/mpi/fortran/mpif-h/.libs/libmpi_mpifh.so.40 failed
attempt to open /build/openmpi-RCkqwI/openmpi-4.1.2/debian/build-gfortran/ompi/.libs/libmpi_mpifh.so.40 failed
attempt to open /usr/lib/x86_64-linux-gnu/openmpi/lib/libmpi_mpifh.so.40 failed
attempt to open /usr/lib/x86_64-linux-gnu/libfakeroot/libmpi_mpifh.so.40 failed
attempt to open /usr/local/lib/libmpi_mpifh.so.40 failed
found libmpi_mpifh.so.40 at /usr/lib/x86_64-linux-gnu/libmpi_mpifh.so.40
# 找到了 libmpi_mpifh.so 庫文件

# 找 libmpi.so.40 
libmpi.so.40 needed by /lib/x86_64-linux-gnu/libmpi_usempif08.so
……
found libmpi.so.40 at /usr/lib/x86_64-linux-gnu/libmpi.so.40

# 找 libc.so.6 
libc.so.6 needed by /lib/x86_64-linux-gnu/libmpi_usempif08.so
……
found libc.so.6 at /usr/lib/x86_64-linux-gnu/libc.so.6

# 找 libopen-pal.so.40
libopen-pal.so.40 needed by /usr/lib/x86_64-linux-gnu/libmpi_mpifh.so.40
……
found libopen-pal.so.40 at /usr/lib/x86_64-linux-gnu/libopen-pal.so.40

# 找 libopen-rte.so.40
libopen-rte.so.40 needed by /usr/lib/x86_64-linux-gnu/libmpi.so.40
……
found libopen-rte.so.40 at /usr/lib/x86_64-linux-gnu/libopen-rte.so.40

# 找 libm.so.6
libm.so.6 needed by /usr/lib/x86_64-linux-gnu/libmpi.so.40
……
found libm.so.6 at /usr/lib/x86_64-linux-gnu/libm.so.6
libhwloc.so.15 needed by /usr/lib/x86_64-linux-gnu/libmpi.so.40

# 找 libhwloc.so.15
……略

# 找 libudev.so.1
libudev.so.1 needed by /usr/lib/x86_64-linux-gnu/libhwloc.so.15
attempt to open /usr/lib/x86_64-linux-gnu/libfakeroot/libudev.so.1 failed
attempt to open /usr/local/lib/libudev.so.1 failed
found libudev.so.1 at /usr/lib/x86_64-linux-gnu/libudev.so.1

進一步,我們可以用 grep 過濾只顯示 mpi_usempif08 實際找到的庫的信息:

#ld -lmpi_usempif08 --verbose | grep found

found libmpi_mpifh.so.40 at /usr/lib/x86_64-linux-gnu/libmpi_mpifh.so.40
found libmpi.so.40 at /usr/lib/x86_64-linux-gnu/libmpi.so.40
ld: warning: cannot find entry symbol _start; not setting start address
found libc.so.6 at /usr/lib/x86_64-linux-gnu/libc.so.6
found libopen-pal.so.40 at /usr/lib/x86_64-linux-gnu/libopen-pal.so.40
found libopen-rte.so.40 at /usr/lib/x86_64-linux-gnu/libopen-rte.so.40
found libm.so.6 at /usr/lib/x86_64-linux-gnu/libm.so.6
found libhwloc.so.15 at /usr/lib/x86_64-linux-gnu/libhwloc.so.15
found ld-linux-x86-64.so.2 at /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
found libevent_core-2.1.so.7 at /usr/lib/x86_64-linux-gnu/libevent_core-2.1.so.7
found libevent_pthreads-2.1.so.7 at /usr/lib/x86_64-linux-gnu/libevent_pthreads-2.1.so.7
found libz.so.1 at /usr/lib/x86_64-linux-gnu/libz.so.1
found libudev.so.1 at /usr/lib/x86_64-linux-gnu/libudev.so.1

而ldd 與 ld是不同的。ldd是分析linux的運行庫的依賴關系、ld是可執行文件鏈接器常用于C/C++/Fortran等語言代碼生成可執行文件的鏈接階段。

我們看下 使用 ldd 對同一個動態庫所依賴的其他庫的分析:

#ldd /usr/lib/x86_64-linux-gnu/libmpi_usempif08.so.40.30.0

 linux-vdso.so.1 (0x00007ffd2f3fd000)
 libmpi_mpifh.so.40 => /usr/lib/x86_64-linux-gnu/libmpi_mpifh.so.40 (0x00007f34366bf000)
 libmpi.so.40 => /usr/lib/x86_64-linux-gnu/libmpi.so.40 (0x00007f3436588000)
 libc.so.6 => /usr/lib/x86_64-linux-gnu/libc.so.6 (0x00007f3436200000)
 libopen-pal.so.40 => /usr/lib/x86_64-linux-gnu/libopen-pal.so.40 (0x00007f34364d5000)
 libopen-rte.so.40 => /usr/lib/x86_64-linux-gnu/libopen-rte.so.40 (0x00007f3436143000)
 libm.so.6 => /usr/lib/x86_64-linux-gnu/libm.so.6 (0x00007f343605c000)
 libhwloc.so.15 => /usr/lib/x86_64-linux-gnu/libhwloc.so.15 (0x00007f3436477000)
 /lib64/ld-linux-x86-64.so.2 (0x00007f343677c000)
 libevent_core-2.1.so.7 => /usr/lib/x86_64-linux-gnu/libevent_core-2.1.so.7 (0x00007f3436442000)
 libevent_pthreads-2.1.so.7 => /usr/lib/x86_64-linux-gnu/libevent_pthreads-2.1.so.7 (0x00007f343643d000)
 libz.so.1 => /usr/lib/x86_64-linux-gnu/libz.so.1 (0x00007f3436040000)
 libudev.so.1 => /usr/lib/x86_64-linux-gnu/libudev.so.1 (0x00007f3436016000)

這里的順序與ld -lmpi_usempif08 --verbose | grep found 的結果是一致的。

責任編輯:趙寧寧 來源: 深入理解Linux
相關推薦

2024-04-30 14:09:00

代碼APIRust

2012-07-27 13:36:00

Office操作系統

2021-11-30 07:51:29

氣球數量空間

2023-03-28 08:12:06

優化系統IOPS

2021-05-07 11:29:54

MacFlutter開發

2022-04-07 09:29:04

文件系統硬盤操作系統

2021-05-19 10:37:16

WebFlux 前置工具

2023-08-02 08:35:54

文件操作數據源

2024-03-11 10:30:31

Linux文件系統

2024-03-21 09:15:58

JS運行的JavaScrip

2023-12-28 09:55:08

隊列數據結構存儲

2017-01-22 15:09:08

架構閉環演進

2023-04-26 07:30:00

promptUI非結構化

2022-07-10 23:15:46

Go語言內存

2021-05-31 07:17:42

數據分析算法

2022-10-08 00:00:05

SQL機制結構

2017-01-19 20:28:44

2021-01-13 09:07:32

MySQLOrderLimit

2022-03-03 08:15:19

云原生無服務器服務網格

2023-03-26 12:45:52

Linux內核頭文件
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产高清一区二区三区 | 日本一区二区高清不卡 | 日本在线中文 | 欧美一级淫片免费视频黄 | 国产日韩精品一区二区 | 天天看天天摸天天操 | 人成在线 | 91玖玖| 亚洲精选一区 | 97精品国产一区二区三区 | 亚洲精品视频久久 | 中文字幕成人网 | 中文字幕亚洲视频 | 麻豆av在线免费观看 | 久久99精品久久久久久狂牛 | 99精品国产一区二区青青牛奶 | 97精品超碰一区二区三区 | 亚洲一区二区在线播放 | 中文在线a在线 | 国产精品一二三区 | 国产精品资源在线观看 | 精品免费av | 亚州激情| 九九综合九九 | 日韩一区二区福利视频 | 精产国产伦理一二三区 | 特一级毛片| 亚洲欧美日韩在线一区二区 | 精品日韩 | 国产精品免费观看视频 | 国产精品视频一区二区三区 | 欧洲亚洲精品久久久久 | 亚洲免费婷婷 | 91久久久久 | 国产a级毛毛片 | 黄色大全免费看 | 狠狠干天天干 | 国产精品视频一区二区三区四蜜臂 | 亚洲一区二区在线免费观看 | 国产精品无码专区在线观看 | 亚洲成人黄色 |