سؤال

قمت بتجميع 2 ثنائيات مختلفة على نفس خادم GNU/Linux باستخدام G ++ الإصدار 4.2.3.

أول واحد يستخدم:

GLIBC_2.0
GLIBC_2.2
GLIBC_2.1
GLIBCXX_3.4
GLIBC_2.1.3

الثاني يستخدم:

GLIBC_2.0
GLIBC_2.2
GLIBC_2.1
GLIBCXX_3.4.9
GLIBCXX_3.4
GLIBC_2.1.3

لماذا يستخدم الثنائي الثاني glibcxx_3.4.9 الذي يتوفر فقط على libstdc ++. so.6.0.9 و ليس في libstdc ++. so.6.0.8

ما هي الميزة الجديدة التي تم إنشاؤها بواسطة G ++ والتي تتطلب كسر ABI وإجبار النظام على الحصول على glibcxx_3.4.9؟

هل هناك طريقة لتعطيل هذه الميزة الجديدة حتى لا تتطلب glibcxx_3.4.9؟

هل كانت مفيدة؟

المحلول

لمعرفة أي من الرموز (s) الرمز (S) الرمز (S) الخاص بك ، يعتمد على ثنائي ، القيام بذلك:

readelf -s ./a.out | grep 'GLIBCXX_3\.4\.9' | c++filt

بمجرد معرفة الرموز التي يجب البحث عنها ، يمكنك العودة إلى الكائن الذي يحتاجها:

nm -A *.o | grep _ZN<whatever>

أخيرًا ، لربط هذا مرة أخرى إلى المصدر ، يمكنك القيام بذلك:

objdump -dS foo.o

ومعرفة الرمز الذي يشير إلى 3.4.9 رمز (ق).

نصائح أخرى

نظرًا لأنك طلبت ذلك ، فإليك الرموز التي لها إصدار ABI على الأقل 3.4.9:

GLIBCXX_3.4.9 {

    _ZNSt6__norm15_List_node_base4hook*;
    _ZNSt6__norm15_List_node_base4swap*;
    _ZNSt6__norm15_List_node_base6unhookEv;
    _ZNSt6__norm15_List_node_base7reverseEv;
    _ZNSt6__norm15_List_node_base8transfer*;

    _ZNSo9_M_insertI[^g]*;
    _ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertI[^g]*;
    _ZNSi10_M_extractI[^g]*;
    _ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractI[^g]*;

    _ZSt21__copy_streambufs_eofI[cw]St11char_traitsI[cw]EE[il]PSt15basic_streambuf*;

    _ZSt16__ostream_insert*;

    _ZN11__gnu_debug19_Safe_sequence_base12_M_get_mutexEv;
    _ZN11__gnu_debug19_Safe_iterator_base16_M_attach_singleEPNS_19_Safe_sequence_baseEb;
    _ZN11__gnu_debug19_Safe_iterator_base16_M_detach_singleEv;
    _ZN11__gnu_debug19_Safe_iterator_base12_M_get_mutexEv;

    _ZNKSt9bad_alloc4whatEv;
    _ZNKSt8bad_cast4whatEv;
    _ZNKSt10bad_typeid4whatEv;
    _ZNKSt13bad_exception4whatEv;

} GLIBCXX_3.4.8;

تشغيل الملف libstdc++-v3/config/abi/post/i386-linux-gnu/baseline_symbols.txt من خلال filt C ++ ، grepping for glibcxx_3.4.9 لفهم هذه الأسماء (تبدو مثل البطاقات البرية فقط). لم أفعل ذلك لأن هذه الأسماء تصبح طويلة جدًا ومتداخلة. تتضمن الإصدارات اللاحقة في الغالب أشياء C ++ 1x. انظر الملف libstdc++-v3/config/abi/pre/gnu.ver للأعلى. اقرأ هنا حول أمر نص الإصدار.

حسنًا ، السؤال الأول هو كيف قمت بإنشاء القائمة أعلاه.
يمكن للمرء أن يفترض أن المترجم حتمي وبالتالي يربط الثنائيات بالطريقة نفسها.

أفترض أنني حصلت على علامة لعدم الإجابة على السؤال مباشرة ولكن التعليق سيكون لطيفًا. لكنني ما زلت أعتقد أنك لم تقدم المعلومات الصحيحة وسيكون من الجيد رؤية إخراج الأمر الذي يوضح مشكلتك.

على افتراض أنك استخدمت LDD:
ستحصل على إخراج يشبه هذا:

lib<X>.so.<ver>  =>  /usr/lib/lib<X>.so.<verM>  (<Addr>)

ولكن هذه ليست نهاية القصة.
محاولة القيام LS على الملف قد يكون رابطًا رمزيًا

> ls /usr/lilb/lib<X>.so.<verM>
lrwxrwxrwx 1 root root    <Date>  /usr/lib/lib<X>.so.<verM>  -> lib<X>.so.<verM>.<verm>.<verp>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top