2012-02-02 10 views
5

Başlığın dediği gibi, C programımdaki yığınının içeriğini yazdırmak istiyorum.C programındaki yığın içeriğini nasıl yazdırabilirim?

İşte aldı adımlar şunlardır:

  • Ben adresini dönmek benim ebp kaydının adresini dönmek için bir işlev ve bir işlevi dahil basit montaj (helper.s) dosyası yapılmış benim eSP kayıt

    .globl get_esp 
    
    get_esp: 
        movl %esp, %eax 
        ret 
    # get_ebp is defined similarly, and included in the .globl section 
    
  • Ben baskı I (başarıyla sanırım)
  • (FPC bir int fpC = get_esp();) benim C programından get_esp() ve get_ebp() fonksiyonları denilen esp ve ebp yazmaçlarımın adresini (fprintf (stderr, "%x", fcP);)
  • Kayıt defterimin içeriğini yazdırmayı denedim ve başaramadım. (Diğer yöntemlerin yanı sıra fprintf (sderr, "%d", *fcP); ve fprintf (sderr, "%x", *((int *)fcP)); denedim). Programım, bu satır işlendiğinde çalışma zamanında bir segmentasyon hatasına neden oluyor.

Neyi yanlış yapıyorum?

DÜZENLEME: Yığın işaretlerini almak için bu montaj işlevlerini çağırarak bu işlemi gerçekleştirmeniz gerekir. EDIT2: Bu bir ev ödevi görevidir.

+0

Başarısız olduğunu söylediğinde ne demek istiyorsun? Ne çıktı ve ne bekliyordun? –

+0

İşaretçiler yazdırmak için, printf ("% p", (void *) (p)) 'komutunu kullanmalısınız. "% Esp'in içeriği" bir işaretçidir. –

+0

@CarlNorum: Hayır, 'printf 'kullanımı basitçe C standardı tarafından zorunlu kılındı. (Cf. "variadic arguments".) –

cevap

5

Bir GNU sisteminden yararlanıyorsanız, GNU'nun uzantısını geriye doğru işlemek için C kütüphanesine yükleyebilirsiniz, bkz. here.

#include <execinfo.h> 

int main(void) 
{ 
    //call-a-lot-of-functions 
} 

void someReallyDeepFunction(void) 
{ 
    int count; 
    void *stack[50]; // can hold 50, adjust appropriately 
    char **symbols; 

    count = backtrace(stack, 50); 
    symbols = backtrace_symbols(stack, count); 

    for (int i = 0; i < count; i++) 
     puts(symbols[i]); 

    free(symbols); 
} 
+0

Bunun için iyi bir yol gibi görünüyor, ancak bunu montaj işlevleri (atama gereksinimleri için) kullanarak uygulamak gerekiyor. İlk başta benim sorunumda belirtmeliydim. – Nate

+0

Ev ödevi sorularını ev ödevi olarak işaretlemeniz önemlidir. – dreamlax

+0

Bunun için üzgünüz. Orijinal gönderi düzenlendi. – Nate

4

get_esp döner esp bu işlevi içinde olduğu gibi. Ancak arama işlevi esp ile aynı değildir, çünkü arama işlemi esp olarak değişir.

Bu işlevi bir satır içi montaj parçasıyla değiştirmenizi öneriyorum. Bu şekilde okumaya çalışırken esp değişmeyecektir.

Ayrıca, sderr numaralı baskı da yardımcı olmaz. Deneyimlerime göre, stderr çok daha iyi çalışıyor.

İlgili konular