libpthread.so.0: ข้อผิดพลาดการเพิ่มสัญลักษณ์: DSO หายไปจากบรรทัดคำสั่ง


205

เมื่อฉันรวบรวม openvswitch-1.5.0 ฉันพบข้อผิดพลาดในการคอมไพล์ต่อไปนี้:

 gcc -Wstrict-prototypes -Wall -Wno-sign-compare -Wpointer-arith
     -Wdeclaration-after-statement -Wformat-security -Wswitch-enum -Wunused-parameter -Wstrict-aliasing -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -Wno-override-init  -g -O2 -export-dynamic ***-lpthread***  -o utilities/ovs-dpctl utilities/ovs-dpctl.o lib/libopenvswitch.a
 /home/jyyoo/src/dpdk/build/lib/librte_eal.a
 /home/jyyoo/src/dpdk/build/lib/libethdev.a
 /home/jyyoo/src/dpdk/build/lib/librte_cmdline.a
 /home/jyyoo/src/dpdk/build/lib/librte_hash.a
 /home/jyyoo/src/dpdk/build/lib/librte_lpm.a
 /home/jyyoo/src/dpdk/build/lib/librte_mbuf.a
 /home/jyyoo/src/dpdk/build/lib/librte_ring.a
 /home/jyyoo/src/dpdk/build/lib/librte_mempool.a
 /home/jyyoo/src/dpdk/build/lib/librte_malloc.a -lrt -lm 
     /usr/bin/ld: /home/jyyoo/src/dpdk/build/lib/librte_eal.a(eal.o): undefined reference
     to symbol 'pthread_create@@GLIBC_2.2.5'
     /lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from 
     command line

ถ้าฉันพยายามที่จะเห็นสัญลักษณ์ของlibpthreadมันดูดี

$ readelf -s /lib/x86_64-linux-gnu/libpthread.so.0 | grep pthread_create
   199: 0000000000008220  2814 FUNC    GLOBAL DEFAULT   13 pthread_create@@GLIBC_2.2.5
   173: 0000000000008220  2814 FUNC    LOCAL  DEFAULT   13 __pthread_create_2_1
   462: 0000000000008220  2814 FUNC    GLOBAL DEFAULT   13 pthread_create@@GLIBC_2.2

คุณสามารถให้คำแนะนำหรือพอยน์เตอร์ได้หรือไม่?



link_l ไลบรารี (pthread)
Alex Punnen

# readelf -s /lib/x86_64-linux-gnu/libncurses.so readelf: ข้อผิดพลาด: ไม่พบ '/lib/x86_64-linux-gnu/libncurses.so' ข้อความแสดงข้อผิดพลาดของระบบ: มีการเชื่อมโยงสัญลักษณ์หลายระดับเกินไป
Ashish Karpe

ซ้ำซ้อนที่เป็นไปได้ของDSO หายไปจากบรรทัดคำสั่ง
luator

4
Goddamnit ฉันไม่gccได้g++
โพสต์ด้วยตัวเอง

คำตอบ:


163

คุณควรพูดถึงไลบรารีบนบรรทัดคำสั่งหลังจากรวบรวมไฟล์ออบเจ็กต์:

 gcc -Wstrict-prototypes -Wall -Wno-sign-compare -Wpointer-arith -Wdeclaration-after-statement -Wformat-security -Wswitch-enum -Wunused-parameter -Wstrict-aliasing -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -Wno-override-init \
     -g -O2 -export-dynamic -o utilities/ovs-dpctl utilities/ovs-dpctl.o \
     lib/libopenvswitch.a \
     /home/jyyoo/src/dpdk/build/lib/librte_eal.a /home/jyyoo/src/dpdk/build/lib/libethdev.a /home/jyyoo/src/dpdk/build/lib/librte_cmdline.a /home/jyyoo/src/dpdk/build/lib/librte_hash.a /home/jyyoo/src/dpdk/build/lib/librte_lpm.a /home/jyyoo/src/dpdk/build/lib/librte_mbuf.a /home/jyyoo/src/dpdk/build/lib/librte_ring.a /home/jyyoo/src/dpdk/build/lib/librte_mempool.a /home/jyyoo/src/dpdk/build/lib/librte_malloc.a \
     -lrt -lm -lpthread 

คำอธิบาย: การเชื่อมโยงจะขึ้นอยู่กับลำดับของโมดูล มีการร้องขอสัญลักษณ์ก่อนแล้วจึงเชื่อมโยงจากไลบรารีที่มี ดังนั้นคุณต้องระบุโมดูลที่ใช้ไลบรารีก่อนและไลบรารีหลังจากนั้น แบบนี้:

gcc x.o y.o z.o -la -lb -lc

ยิ่งกว่านั้นในกรณีที่มีการพึ่งพาแบบวนรอบคุณควรระบุไลบรารีเดียวกันบนบรรทัดคำสั่งหลาย ๆ ครั้ง ดังนั้นในกรณีที่libbต้องการสัญลักษณ์จากlibcและlibcต้องการสัญลักษณ์จากlibbบรรทัดคำสั่งควรเป็น:

gcc x.o y.o z.o -la -lb -lc -lb

23
ฉันคิดว่าคุณสามารถทำได้-Wl,--start-group -la -lb- -lc -Wl,--end-groupสำหรับการพึ่งพาแบบวงกลม
Z boson

2
หมายเหตุสิ่งนี้ยังใช้กับไฟล์ต้นฉบับด้วย - ควรแสดงรายการไว้ก่อนไลบรารี คุณสามารถนึกถึงวัตถุไฟล์ผลลัพธ์ที่เกิดขึ้นแทนไฟล์ต้นฉบับในบรรทัดคำสั่งและใช้ลำดับเดียวกันกับด้านบน
jspencer

หนึ่งควรเพิ่ม -lpthread เมื่อใช้ make เพื่อสร้างแอปพลิเคชัน?
codezombie

50

ข้อความแสดงข้อผิดพลาดขึ้นอยู่กับรุ่นการแจกจ่าย / ผู้รวบรวม:

อูบุนตูทะลึ่ง:

/usr/bin/ld: /mnt/root/ffmpeg-2.1.1//libavformat/libavformat.a(http.o): undefined reference to symbol 'inflateInit2_'
/lib/x86_64-linux-gnu/libz.so.1: error adding symbols: DSO missing from command line

Ubuntu Raring: (ให้ข้อมูลเพิ่มเติม)

/usr/bin/ld: note: 'uncompress' is defined in DSO /lib/x86_64-linux-gnu/libz.so.1 so try adding it to the linker command line

สารละลาย:คุณอาจขาดไลบรารีในขั้นตอนการรวบรวมระหว่างขั้นตอนการเชื่อมโยง ในกรณีของฉันฉันเพิ่ม '-lz' ลงในแฟล็ก makefile / GCC

พื้นหลัง: DSO เป็นวัตถุที่ใช้ร่วมกันแบบไดนามิกหรือห้องสมุดสาธารณะ


1
ฉันใช้โซลูชันนี้เพื่อสร้างโครงการอื่นที่ให้ข้อผิดพลาดเดียวกันโดยเพิ่ม -lz ใน LDFLAGS และทำงานได้อย่างสมบูรณ์ ขอบคุณ!
Mark Ellul

ข้อผิดพลาดยังคงอยู่สำหรับฉัน: / usr / bin / ld: gaSim.o: ไม่ได้อ้างอิงการอ้างอิงถึงสัญลักษณ์ 'pthread_create @@ GLIBC_2.1' /lib/i386-linux-gnu/libpthread.so.0: การกำหนดสัญลักษณ์ ขาดหายไปจากบรรทัดคำสั่ง
Aerox

ในส่วนที่แก้ไขการเพิ่ม '-lpthread' แต่ตอนนี้มันแสดงให้ฉัน: gaSim.c :(. ข้อความ + 0x11d6): การอ้างอิงที่ไม่ได้กำหนดกับ `glewInit '
Aerox

@erox: สำหรับglewInitคุณต้องการ-lGLEW
mchiasson

19

พื้นหลัง

DSO missing from command lineข้อความจะปรากฏเมื่อลิงเกอร์ไม่พบสัญลักษณ์ที่จำเป็นพร้อมด้วยการค้นหาปกติ แต่สัญลักษณ์ที่มีอยู่ในการอ้างอิงของห้องสมุดแบบไดนามิกที่ระบุไว้โดยตรง

ในอดีตที่ผ่านมา linker พิจารณาสัญลักษณ์ในการพึ่งพาของภาษาที่ระบุจะพร้อมใช้งาน แต่มันเปลี่ยนไปในเวอร์ชั่นที่ใหม่กว่าและตอนนี้ตัวเชื่อมโยงใช้มุมมองที่เข้มงวดมากขึ้นเกี่ยวกับสิ่งที่มีให้ ข้อความจึงมีวัตถุประสงค์เพื่อช่วยในการเปลี่ยนแปลง

จะทำอย่างไร?

หากคุณเป็นผู้ดูแลซอฟต์แวร์

คุณควรแก้ปัญหานี้ด้วยการตรวจสอบให้แน่ใจว่าไลบรารีทั้งหมดที่ต้องการเพื่อให้เป็นไปตามสัญลักษณ์ที่ต้องการนั้นถูกระบุโดยตรงในบรรทัดคำสั่งของ linker โปรดจำไว้ว่าคำสั่งมักจะมีความสำคัญ

หากคุณเพียงแค่พยายามรวบรวมซอฟต์แวร์

เป็นวิธีแก้ปัญหาเป็นไปได้ที่จะเปลี่ยนกลับไปเป็นมุมมองที่อนุญาตของสัญลักษณ์ที่มีอยู่โดยใช้ตัวเลือก -Wl,--copy-dt-needed-entriesเป็นวิธีแก้ปัญหามันเป็นไปได้ที่จะเปลี่ยนกลับไปเป็นมุมมองอนุญาตเพิ่มเติมจากสิ่งที่สัญลักษณ์ที่มีอยู่โดยใช้ตัวเลือก

วิธีทั่วไปในการแทรกสิ่งนี้ลงในบิลด์คือการส่งออก LDFLAGS ก่อนที่จะทำงานconfigureหรือคล้ายกันดังนี้:

export LDFLAGS="-Wl,--copy-dt-needed-entries"

บางครั้งการส่งผ่านLDFLAGS="-Wl,--copy-dt-needed-entries"โดยตรงmakeอาจใช้งานได้


gcc เวอร์ชั่น 7.4.0 (Ubuntu 7.4.0-1ubuntu1 ~ 18.04.1) ไม่รู้จักการตั้งค่าสถานะนี้
UserX

1
มันไม่ใช่ตัวเลือก gcc ดังนั้นคุณจึงขาด-Wl,bit หรือมี linker ที่ไม่รองรับตัวเลือกนี้ คุณใช้ลิงเกอร์อะไร คำตอบนี้ถือว่าตัวเชื่อมต่อ binutils แบบคลาสสิก (ld.bfd) binutils gold linker (ld.gold) เอกสาร--copy-dt-needed-entriesเป็น "ไม่รองรับ" ดังนั้นหากคุณมี (หรือตัวเชื่อมโยงอื่น ๆ ที่ไม่สนับสนุนตัวเลือกนี้) เป็นค่าเริ่มต้นคุณอาจต้องทำตามในส่วนของผู้ดูแลหรือเปลี่ยนไปใช้คลาสดั้งเดิมสำหรับการเชื่อมโยง ฉันคิดว่าคุณสามารถใช้-fuse-ld=ld.bfdสิ่งนั้นได้
ข้อความจาก

14

ฉันพบกรณีอื่นและดังนั้นสิ่งที่คุณผิดทั้งหมด

นี่คือสิ่งที่ฉันมี:

/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/ld: eggtrayicon.o: undefined reference to symbol 'XFlush'
/usr/lib64/libX11.so.6: error adding symbols: DSO missing from command line

ปัญหาคือว่าบรรทัดคำสั่งไม่ได้มี -lX11 - แม้ว่า libX11.so ควรจะเพิ่มเป็นการพึ่งพาเพราะมีห้องสมุด GTK และ GNOME ในอาร์กิวเมนต์

ดังนั้นคำอธิบายเดียวสำหรับฉันคือข้อความนี้อาจมีจุดประสงค์เพื่อช่วยคุณแต่ไม่ได้ทำอย่างถูกต้อง นี่อาจเป็นเรื่องง่าย: ไลบรารีที่ให้สัญลักษณ์ไม่ได้ถูกเพิ่มในบรรทัดคำสั่ง

โปรดทราบกฎสำคัญสามข้อที่เกี่ยวข้องกับการเชื่อมโยงใน POSIX:

  • ไลบรารีแบบไดนามิกได้กำหนดการขึ้นต่อกันดังนั้นควรจัดหาไลบรารีจากการพึ่งพาสูงสุดเท่านั้นในลำดับใด ๆ (แม้ว่าหลังจากที่สแตติกไลบรารี)
  • ไลบรารีแบบสแตติกมีเพียงสัญลักษณ์ที่ไม่ได้กำหนด - มันขึ้นอยู่กับคุณที่จะรู้ว่าการอ้างอิงของพวกเขาและให้พวกเขาทั้งหมดในบรรทัดคำสั่ง
  • ลำดับคงห้องสมุดอยู่เสมอ: ขอครั้งแรก , ผู้ให้บริการดังต่อไปนี้ มิฉะนั้นคุณจะได้รับข้อความสัญลักษณ์ที่ไม่ได้กำหนดเช่นเดียวกับเมื่อคุณลืมที่จะเพิ่มห้องสมุดในบรรทัดคำสั่ง
  • เมื่อคุณระบุไลบรารีด้วย-l<name>คุณจะไม่มีทางรู้ว่าจะใช้lib<name>.soหรือlib<name>.aไม่ หากต้องการไลบรารีแบบไดนามิกถ้าพบและไลบรารีแบบคงที่สามารถบังคับใช้โดยตัวเลือกคอมไพเลอร์ - นั่นคือทั้งหมด และไม่ว่าคุณจะมีปัญหาใด ๆ ข้างต้นหรือไม่นั้นขึ้นอยู่กับว่าคุณมีห้องสมุดแบบคงที่หรือแบบไดนามิก
  • ดีบางครั้งการพึ่งพาอาจจะขาดในไลบรารีแบบไดนามิก: D

มันไม่ได้มีไว้เพื่อช่วยคุณเท่านั้นมันเป็นสิ่งจำเป็นโดย linker เพื่อแก้ไขชื่อที่เป็นปัญหา ข้อผิดพลาดนั้นถูกต้องสมบูรณ์ หากคอมไพเลอร์ตัดสินใจที่จะปล่อยให้ผ่านคุณจะได้รับ segfault สำหรับการเข้าถึงบางสิ่งที่ไม่ได้อยู่ในไบนารีรันไทม์
kevr

1
ในการเพิ่มอาจเป็นไปได้ว่าบนแพลตฟอร์มที่แตกต่างกันแหล่งที่รวบรวมจะแตกต่างกัน; สิ่งที่ลิงก์ในระบบหนึ่งอาจไม่ได้เชื่อมโยงกับอีกระบบหนึ่ง นี่ไม่ใช่กรณีปกติ แต่เป็นไปได้ 100%
kevr

ปัญหาไม่ได้อยู่ที่ว่ามันไม่ถูกต้อง แต่มันไม่ได้มีประโยชน์อย่างแน่นอนในการค้นหาสาเหตุของปัญหา
Ethouris

7

ฉันพบว่าฉันมีข้อผิดพลาดเดียวกัน ฉันกำลังรวบรวมรหัสด้วย lapack และ blas เมื่อฉันเปลี่ยนลำดับที่ห้องสมุดทั้งสองถูกเรียกว่าข้อผิดพลาดก็หายไป

"LAPACK_LIB = -llapack -lblas" ทำงานโดยที่ "LAPACK_LIB = -lblas -llapack" ให้ข้อผิดพลาดที่อธิบายไว้ข้างต้น


9
ฉันได้รับข้อผิดพลาดนี้ในโครงการที่กำหนด cmake ... ดังนั้นมีข้อผิดพลาดใน Cmake ที่ทำให้คำสั่ง linker ผิดหรือเปล่า?
เตอร์ karasev

กำลังตอบกลับถึง @peterkarasev: ลองใช้find_package(Threads)และtarget_link_libraries( ... ${CMAKE_THREAD_LIBS_INIT})
activedecay

7

ฉันยังพบปัญหาเดียวกัน ฉันไม่ทราบว่าทำไมฉันเพียงแค่เพิ่ม-lpthreadตัวเลือกในการรวบรวมและทุกอย่างโอเค

เก่า:

$ g++ -rdynamic -m64 -fPIE -pie  -o /tmp/node/out/Release/mksnapshot ...*.o *.a -ldl -lrt

มีข้อผิดพลาดในการติดตาม ถ้าฉันผนวก-lpthreadตัวเลือกเพื่อเหนือคำสั่งแล้วตกลง

/usr/bin/ld: /tmp/node/out/Release/obj.host/v8_libbase/deps/v8/src/base/platform/condition-variable.o: undefined reference to symbol 'pthread_condattr_setclock@@GLIBC_2.3.3'
//lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

สิ่งนี้ได้ผลสำหรับฉัน ฉันต้องเพิ่มวินาที "redundant" -lpthread ไปยังคำสั่ง g ++ ใน makefile ที่เชื่อมโยง (มันปรากฏขึ้นครั้งเดียวในรายการ LIBS ใน makefile) ฉันยังเพิ่ม "-L / lib / x86_64-linux-gnu" ในคำจำกัดความของ LDFLAGS ใน makefile
UserX

2

สิ่งที่ฉันได้พบคือบางครั้งห้องสมุดที่ linker บ่นนั้นไม่ใช่ห้องสมุดที่ทำให้เกิดปัญหา อาจเป็นไปได้ว่าวิธีที่ชาญฉลาดในการหาจุดที่เป็นปัญหา แต่นี่คือสิ่งที่ฉันทำ:

  • ใส่เครื่องหมายข้อคิดเห็นไลบรารีที่ลิงก์ทั้งหมดในคำสั่งลิงก์
  • ล้างทั้งหมด. o's, .so ฯลฯ (โดยทั่วไปแล้วการทำให้สะอาดก็เพียงพอแล้ว แต่คุณอาจต้องการเรียกใช้ find + rm แบบเรียกซ้ำหรืออะไรทำนองนั้น)
  • ยกเลิกหมายเหตุไลบรารีในคำสั่งลิงก์ทีละรายการและจัดเรียงลำดับใหม่ตามความจำเป็น

@ peter karasev: ฉันเจอปัญหาเดียวกันกับ gcc 4.8.2 cmake project บน CentOS7 ลำดับของไลบรารีในส่วน "target_link_l ไลบรารี" มีความสำคัญ ฉันเดา cmake เพียงส่งรายการไปยังตัวเชื่อมโยงตามที่เป็นอยู่นั่นคือมันไม่ได้พยายามและเรียงลำดับที่ถูกต้อง นี่คือเหตุผล - เมื่อคุณคิดเกี่ยวกับมัน cmake ไม่ทราบว่าลำดับที่ถูกต้องคืออะไรจนกว่าการเชื่อมโยงจะเสร็จสมบูรณ์



1

ปัญหาเดียวกันนี้เกิดขึ้นกับฉันเมื่อฉันใช้distccเพื่อทำโครงการ c ++ export CXX="distcc g++"ในที่สุดผมก็แก้ไขมันด้วย



0

สิ่งเดียวกันเกิดขึ้นกับฉันในขณะที่ฉันกำลังติดตั้งมาตรฐาน HPCC (รวมถึง HPL และมาตรฐานอื่น ๆ อีกสองสาม) ฉันเพิ่มลง-lmในธงคอมไพเลอร์ในสคริปต์สร้างของฉันและจากนั้นก็รวบรวมได้สำเร็จ


3
สิ่งนี้ไม่ได้ตอบคำถามเฉพาะนี้หรือให้คำตอบทั่วไปสำหรับครอบครัวที่มีปัญหาคล้ายกัน นี่คือคำตอบที่เป็นภาษาท้องถิ่นอย่างมากสำหรับคำถามอื่นอย่างสิ้นเชิง
Hermann Döppes

0

หากใช้g++ให้แน่ใจว่าคุณไม่ได้ทำงานgccแทน


3
ทำไม? คุณอธิบายรายละเอียดเล็กน้อยได้ไหม?
Ivan Ivković

@ IvanIvkovićดี gcc คือคอมไพเลอร์ C, g ++ คือคอมไพเลอร์ C ++ ในขณะที่ C ++ สามารถคอมไพล์ C, gcc ไม่สามารถคอมไพล์ C ++ ได้
Jean-Marc Zimmer

0

ลองเพิ่ม-pthreadที่ส่วนท้ายของรายการไลบรารีในMakefile Makefile

มันใช้งานได้สำหรับฉัน


0

หากคุณใช้ CMake มีบางวิธีที่คุณสามารถแก้ไขได้:

โซลูชันที่ 1:หรูหราที่สุด

add_executable(...)
target_include_directories(...)
target_link_libraries(target_name pthread)

โซลูชันที่ 2:ใช้ CMakefind_package

find_package(Threads REQUIRED) # this will generate the flag for CMAKE_THREAD_LIBS_INIT

add_executable(...)
target_include_directories(...)
target_link_libraries(target_name ${CMAKE_THREAD_LIBS_INIT})

โซลูชันที่ 3:เปลี่ยนค่าสถานะ CMake

# e.g. with C++ 17, change to other version if you need
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -pthread")
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.