2011-01-11 9 views
8

Linux'ta kütüphane sürümleri hakkında daha fazla şey öğrenmeye çalışıyorum ve bunların hepsini nasıl çalıştıracağım. İşte bağlam var:Linux, GNU GCC, ld, sürüm komut dosyaları ve ELF ikili formatı - Nasıl çalışır?

- Ben arayüzleri aynı seti maruz dinamik kitaplığında iki sürümü yüklü, libsome1.so ve libsome2.so söylerler.

- Bir uygulama libsome1.so ile bağlantılıdır.

- Bu uygulama, libmagic.so adlı başka bir modülü dinamik olarak yüklemek için libdl.so kullanır.

- Şimdi libmagic.so karşı libsome2.so adresinden bağlanmıştır. Açıkçası, libmagic.so'daki sembolleri gizlemek için linker komut dosyaları kullanmadan, çalışma zamanında libsome2.so'daki arabirimlere yapılan tüm çağrılar libsome1.so olarak çözülür. Bu, libVersion() tarafından döndürülen değeri LIB_VERSION makrosunun değerine göre kontrol ederek doğrulanabilir.

- libmagic.so numaralı belgede tanımlanmış olan ve dışa aktarılan 3 dışındaki tüm sembolleri gizleyen bir bağlayıcı komut dosyasıyla derlemek ve libmagic.so numaralı bağlantıyı bağlamayı deneyin. Bu çalışır ... Veya en az libVersion() ve LIB_VERSION değerleri eşleşir (ve sürüm 2 değil 1 rapor eder).

- Ancak, bazı veri yapıları diske serileştirildiğinde, bazı bozulmaları fark ettim. Uygulamanın dizininde libsome1.so'u silip yerine libsome2.so'a işaret edecek bir yumuşak bağlantı oluşturursam her şey beklendiği gibi çalışır ve aynı bozulma olmaz.

Yardım edemiyorum ama bunun çalışma zamanı bağlantılarının sembol çözümlemesindeki bazı çakışmalardan kaynaklanabileceğini düşünmüyorum. libsome2.so'u bağlamaya çalışmak gibi pek çok şey denedim, böylece tüm semboller(nm -CD libsome2.so komutu hala symbol ve [email protected]@VER_2 gibi semboller olduğu için kafam karıştı). Hiçbir şey işe yaramıyor! Yardım et!!!!!!

Düzenleme: Daha önce bahsetmeliydim, ancak söz konusu uygulama Firefox'tur ve libsome1.so, onunla birlikte gelen libsqlite3.so'dir. Onları yeniden derleme seçeneğim yok. Ayrıca, simgelerini gizlemek için sürüm komut dosyalarını kullanmak şu anda tek çözüm gibi görünüyor. Peki, semboller gizlendiğinde gerçekten ne olur? SO'ya 'yerel' oluyorlar mı? Rtld onların varlığını bilmez mi? Dışa aktarılan bir işlev gizli bir simgeye başvurduğunda ne olur? kendi projeleri (ld için --version-script seçeneğini kullanın) ile sembol sürüm, her eklemek hem libsome1.so ve libsome2.so derleme

+0

http://unix.stackexchange.com/ adresinde bulundunuz mu? – joksnet

+2

@joksnet: Stackexchange'in kullanıcılar için değil geliştiriciler için olduğunu sanmıştım ... Bu soru C++ Linux'taki gelişmelerle ilgili ... Ya da sadece aldatılmış mıyım? :) Düzenleme: Yanlışım! Bazı nedenlerden dolayı stackexchange = serverfault! Unix.stackexchange.com farkında değildim! – themoondothshine

+0

Evet! Çünkü hala beta’da ve kendi alanı yok. – joksnet

cevap

4

deneyin. Ardından uygulamayı ve libmagic.so yeni kütüphaneleri kullanarak bağlayın. Ardından, libsome1.so ve libsome2.so tamamen ayrı olmalıdır. Sembollere dönüştürülmemiş referanslar varsa, problemler hala oluşabilir. Bu tür referanslar, sürüm tanımları ile karşılanabilir (böylece ikili sürümleri bozmadan bir kütüphaneye sembol versiyonlama eklenebilir). Aynı isimde birden fazla sembol varsa, hangisinin kullanılacağını tahmin etmek bazen zor olabilir.

Araçlar ile ilgili olarak, nm -D sembol versiyonlaması hakkında herhangi bir bilgi göstermez. Bunun yerine objdump -T veya readelf -s'u deneyin.

+0

Bilgi için teşekkürler. Yeni bir şey öğrendim! Muhtemelen daha önce bahsetmeliydim, ama söz konusu uygulama Firefox ve 'libsome1.so'' libsqlite3.so' ile birlikte geliyor. Yani onları yeniden derleme seçeneğim yok. Ancak, çözümünüzü modellemek için yarattığım minimalist örnekte çözümünüzü denedim ... Ve işe yaradı! Bana yeni bir şey öğrettiğin cevabın için – themoondothshine

+0
+0

Size ödül vereceğim. Bunun haklı olduğunu düşünüyorum; Cevabınız iyidir. Biraz daha temsilcisi var! –

İlgili konular