2012-11-02 20 views
5

Bir işlevin yanlış sürümünün bir segfault nedeninin çağrıldığı bir sorunu ayıklamaya çalışıyorum. Derlediğim kod, makine tarafından üretilir ve bir karmaşıkın iki argümanını çoğaltan 'zamanlar' adlı bir işlev içerir. Bu kod, daha yüksek düzeyli bir nesne dosyasına bağlanmadan önce bir .o'ya derlenir.C programın yanlış sürümüne program bağlantıları

Bu kod çalıştırıldığında segfaults ve gdb, glibc'nin 'times' sürümünde olduğunu ve bu bile aynı sayıda argümanı almadığını belirtir. Bu kodun herhangi bir yerinde #include bulunmaz.

Zamanların ismini defa1 olarak değiştirmek sorunu çözer. Bu, kodun makine tarafından oluşturulmuş yapısı nedeniyle ve bu fonksiyonun adını her zaman elden bırakmadan dolayı uzun süreli bir çözüm değildir.

Tüm pislik -Wall ile temizlik derler, bu yüzden nereye bakacağımı bilmiyorum. Bunu nasıl çözeceğiniz konusunda bir fikrin var mı?

Compile chain: 
    gcc -Wall -I. -g --shared -o dpd.o -fPIC *.c (mahine generated code here) 
    gcc -g --std=c99 -c -fpic getData.c -I/usr/local/include -L/usr/local/lib -lmatio -I/usr/local/include/iverilog -I$(MATLAB) 
    gcc -g -shared -o getData.vpi getData.o $(MATLAB)/dpd.o -lvpi -lmatio -L/usr/local/lib 
+3

Birden çok C dosyasını tek bir '.o'ya ​​derlemek geleneksel değildir. Times.c, bu grupta derlenen birkaç C dosyasından biri ise, sorunu açıklayabilir. – Gene

+1

'# include' yalnızca bildirimlerde bulunur; Bağlantının kontrolü yoktur. 'Times' adında bir işlev bildirir ve sonra onu çağırırsanız, derleyici, sembol tablosunda bu ada sahip bir başvuru içeren bir nesne dosyası üretecek ve daha sonra linker, son yürütülebilir dosyayı üretirken bu adın bir tanımını arayacaktır. . Libc'de 'times' işlevi var ve linker bu şekilde bulundu. – Wyzard

+0

Gene - Yorumunuzu detaylandırır mısınız? times.c gerçekten bu tek nesneye derlenmiş ayrı bir C dosyasıdır. Neden bunun bir soruna yol açmasını bekliyorsun? Gerçekten bunun için ilgilendiğim tek bir giriş noktası var .o ve 'zamanlar' bunlardan biri değil. yani tamamen içsel olmalı ve daha yüksek katmanlara dinamik bir sembol olarak görülmemelidir. Bu konuda gcc söylemenin bir yolu var mı? –

cevap

0

Bunun için gerçek cevap, -fno-builtin-times gcc'ye atmaktır. Bu, problemsizce karışıklıktan kaçınır.

Bu, elbette, bir glibc işleviyle çakışmayan bir şeye times adını değiştiremeyeceğinizi varsayar.

3

C yalnızca bir işlevin adını bir tanımlayıcı olarak kullanır, böylece aynı ada sahip iki (dışa aktarılmış) işlev çakışacaktır. Normal onaylama, dışa aktarılan tüm adların bir kitaplıkta benzersiz bir önek ile öneklenmesidir. Diğer bir alternatif ise C++ 'yı "daha iyi bir C" olarak kullanmak ve C++ derleyicisini kullanarak C + C kodunuzu kullanmaktır.

+0

Bu durumda, bağlayıcı "yinelenen sembol" ile boğulmamalıdır? –

+0

İki farklı .o dosyası içinde aynı sembolle sürüklemek için zorlamadığınız sürece değil. – bmargulies

+0

@ H2CO3 UNIX bağlayıcıları * aynı simge ana yürütülebilir dosyada ve paylaşılan bir kütüphanede ('libc.so.6' burada) tanımlandığında * asla * şikayetçi olur - böyle bir sembol interpozisyonu oldukça yaygındır ve genellikle çok faydalıdır. –