عندما يربط g بشكل ثابت pthread، مما يتسبب في خطأ التجزئة، لماذا؟
في الارتباط الثابت، سيتوقف الرابط عند الرمز الأول، حتى إذا كان ضعيفًا، وتوقف عن البحث عن الأقوياء. لإجباره على النظر إلى جميع الرموز (كما هو الحال مع مكتبة مرتبطة ديناميكيًا)، يدعم ld خيار --whole-archive.
سيعمل الأمر التالي:
g -o one one.cpp -Wall -std=c 11 -O3 -static -pthread \ -Wl,--whole-archive -lpthread -Wl,--no-whole-archive
إليك ما يحدث:
فهم الرموز الضعيفة
تنسيق ملف ELF له مفهوم الرموز الضعيفة والقوية. بشكل افتراضي، تكون الرموز الموجودة في ملف الكائن قوية. أثناء الربط، يمكن للرمز القوي أن يطغى على الرمز الضعيف الذي يحمل نفس الاسم.
في حالة glibc و pthreads، يستخدمون رموزًا ضعيفة. على سبيل المثال، يتطلب POSIX أن يكون fputc آمنًا ويجب مزامنته، وهو أمر مكلف. في بيئة ذات ترابط واحد، لا تريد دفع هذه التكاليف. وبالتالي، يمكن للتطبيق تنفيذ وظائف المزامنة ككعبات فارغة، وإعلان الوظائف كرموز ضعيفة.
لاحقًا، إذا تم ربط مكتبة متعددة الخيوط (على سبيل المثال، pthread)، يصبح من الواضح أن دعم مؤشر ترابط واحد ليس المقصود. عند ربط مكتبة متعددة الخيوط، يمكن للرابط بعد ذلك استبدال بذرة بوظائف المزامنة الحقيقية (المحددة كرموز قوية ويتم تنفيذها بواسطة مكتبة الخيوط).
تطبيق هذا على البرنامج النموذجي
تحتوي مكتبة libc.a على __pthread_mutex_lock كرمز ضعيف، وتحتوي مكتبة libpthread.a عليه كرمز قوي. عند الارتباط ديناميكيًا، يستبدل الرابط الرمز الضعيف بالرمز القوي. ومع ذلك، عند الارتباط بشكل ثابت، تحتاج إلى فرض نفس الدلالات. لهذا السبب -Wl,--whole-archive -lpthread -Wl,--no-whole-archive ليس هناك حاجة إلى أرشيف كامل.
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3