GDB neden satırlar arasında tahmin edilemeyecek şekilde atlar ve değişkenleri "<optimize edilmiş değer>" olarak yazdırır?


84

Herhangi biri gdb'nin bu davranışını açıklayabilir mi?

Neden satır 903'ü yürüttükten sonra 905 908 910 için aynı şeyi tekrar yapıyor?

Başka şeyler foundbir olduğunu bool, tipi değişken yani neden o gösteriyor value optimized out? Ben de değerini ayarlayamıyorum found.

Bu bir derleyici optimizasyonu gibi görünüyor (bu durumda onun -O2); değerini hala nasıl ayarlayabilirim found?


8
Hata ayıklarken, optimizasyon bu tür sorunlara yol açtığı için genellikle -O0 ile derlemek iyi bir fikirdir.
LiraNuna

Yanıtlar:


115

Optimize edilmiş kodda hata ayıklamak için montaj / makine dilini öğrenin.

GDB TUI modunu kullanın. GDB kopyam, eksi yazıp Enter'a girdiğimde bunu etkinleştiriyor. Sonra Cx 2 yazın (yani Control tuşunu basılı tutun ve X'e basın, ikisini de bırakın ve sonra 2'ye basın). Bu, onu bölünmüş kaynak ve sökme ekranına koyacaktır. Ardından , her seferinde bir makine talimatını taşımak için stepive nextituşlarını kullanın . TUI pencereleri arasında geçiş yapmak için Cx o kullanın.

CPU'nuzun makine dili ve işlev çağırma kuralları hakkında bir PDF indirin. İşlev bağımsız değişkenleri ve dönüş değerleri ile ne yapıldığını hızlıca öğreneceksiniz.

Bir GDB komutu kullanarak bir kaydın değerini görüntüleyebilirsiniz. p $eax


Hala "optimize edilmiş" sorunum var ve değişken değer diğer pencerelerde gösterilmiyor, ancak yine de harika bir bilgi, teşekkürler!
Tom Brito

16
@TomBrito: Optimize edilmiş, değişkenin bellekte olmadığı anlamına gelir. Muhtemelen yalnızca bir CPU kaydındadır, bu da onu bulmak için demontajı okumanız ve kayıt değerlerini yazdırmanız gerektiği anlamına gelir.
Zan Lynx

@Zan Lynx: Analizinize katılıyorum emin değilim. DWARF sembolleri, kayıtlardan değer çıkarmak için yeterli bilgiye sahiptir. Belki de burada kastedilen, derleyicinin değişkenin, yürütme mevcut satıra ulaştığında güvenli bir şekilde atılabileceğini belirlemiş olmasıdır. Bu durumda, değişkenin yaşadığı depolama muhtemelen başka bir şey için yeniden kullanılmıştır. Sanırım bunun normalde yalnızca değişken kaydedilmişse gerçekleşeceğini düşünüyorum.
Ian Ni-Lewis

@ IanNi-Lewis: DWARF'ın hangi sürümünü kullandığınızı bilmiyorum ama benim deneyimlerime göre GDB bir sicile kaydedilmiş bir değişkeni yazdıramıyor.
Zan Lynx

Eminim haklısın. DWARF ile olan deneyimim gdb kullanmaktan değil kendi ayrıştırıcımı yazmaktan kaynaklanıyor, bu yüzden gdb'nin neler yapabileceğini gerçekten bilmiyorum.
Ian Ni-Lewis

75

Optimizasyon yapmadan yeniden derleyin (gcc'de -O0).


17
-O0 bile optimize edilmiş kod üretebilir (şu anda bununla mücadele etmeye çalışıyorum), ancak neden olduğundan emin değilim.
Chris Gregg

@ChrisGregg Bende de aynı sorun var! Sorunun ne olduğunu buldunuz mu?
Paolo M

1
@paolom bir clang sorunu gibi görünüyor, bu yüzden maalesef hata ayıklama amacıyla g ++ ile derleme yapıyorum.
Chris Gregg

Genellikle bu bir çözüm değildir - özellikle üretimden bir çekirdek dökümünüz varsa ve / veya sorunu geliştirme ortamında yeniden oluşturamıyorsanız.
2017

39

"Uçucu" olarak bulundu beyanı . Bu, derleyiciye onu optimize etmemesini söylemelidir.


1
Gdb hata ayıklayıcısında bazı değişkenleri "uçucu" olarak tanımladığımda bile, onu optimize edilmiş değişken olarak gösteriyor! Artık bunda var mı?
M.Rez

11

Derleyici, optimizasyonlar açıkken çok akıllıca şeyler yapmaya başlayacaktır. Hata ayıklayıcı, değişkenlerin yazmaçlarda depolanma biçiminin optimize edilmesi nedeniyle kodun ileri ve geri atladığını gösterecektir. Hata ayıklayıcının erişebileceği bir doğrudan bellek konumuna sahip olmak yerine hız için kayıtlar arasında akıllıca dağıtıldığı için değişkeninizi ayarlayamamanızın (veya bazı durumlarda değerini görmenizin) nedeni muhtemelen budur.

Optimizasyon olmadan derlemek mi?


6

Tipik olarak, bu şekilde hesaplandıktan hemen sonra dallarda kullanılan boole değerleri aslında hiçbir zaman değişkenlerde depolanmaz. Bunun yerine, derleyici , önceki karşılaştırmadan ayarlanan koşul kodlarından doğrudan ayrılır . Örneğin,

Genellikle şu şekilde derler:

"Bool" un nasıl aslında hiçbir yerde depolanmadığına dikkat edin.


4

Bulunan değeri hemen hemen ayarlayamazsınız. Optimize edilmiş programların hatalarını ayıklamak nadiren zahmete değer, derleyici kodu hiçbir şekilde kaynak koduna karşılık gelmeyecek şekilde yeniden düzenleyebilir (aynı sonucu üretmek dışında), böylece hata ayıklayıcıları sonu gelmeyecek şekilde karıştırır.


4

Optimize edilmiş programlarda hata ayıklarken (hata ayıklama yapılarında hata görünmüyorsa gerekli olabilir), genellikle oluşturulan derleme derleyicisini anlamanız gerekir.

Sizin özel durumunuzda, dönüş değeri, cpnd_find_exact_ckptinfoplatformunuzda dönüş değerleri için kullanılan kayıt defterinde saklanacaktır. Açık ix86, bu olurdu %eax. Açık x86_64:, %raxvb. Yukarıdakilerden hiçbiri değilse, "[işlemciniz] prosedür çağırma kuralı" için Google'da arama yapmanız gerekebilir.

Bu kaydı inceleyebilir GDBve ayarlayabilirsiniz. Örneğin ix86:


0

Gdb ile QtCreator kullanıyorum.

Ekleme

Benim için iyi çalışıyor

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.