Kesme noktalarının bir listesini kaydetmek için GDB'yi alma


129

Tamam, bilgi sonu kesme noktalarını listeler, ancak bu soruda olduğu gibi - komutunu kullanarak onları yeniden kullanmakla iyi sonuç verecek bir biçimde değil . GDB'nin bunları tekrar giriş için kabul edilebilir bir dosyaya dökmek için bir yöntemi var mı? Bazen bir hata ayıklama oturumunda, test için bir dizi kesme noktası oluşturduktan sonra GDB'yi yeniden başlatmak gerekir.

.Gdbinit dosyasında --command ile aynı sorun vardır. Bilgi mola komutu yerine insan tüketimi için bir tablo komutları listelemek, ancak vermez.

Ayrıntılı olarak açıklamak için, işte bilgi molasından bir örnek :

(gdb) bilgi arası
Num Type Disp Enb Address Ne
1 kesme noktası y 0x08048517 <foo :: bar (void) +7> tutmak

Yanıtlar:


204

GDB 7.2'den (2011-08-23) itibaren artık kesme noktalarını kaydet komutunu kullanabilirsiniz.

save breakpoints <filename>
  Save all current breakpoint definitions to a file suitable for use
  in a later debugging session.  To read the saved breakpoint
  definitions, use the `source' command.

source <filename>Kaydedilen kesme noktalarını dosyadan geri yüklemek için kullanın .


2
ya paylaşılan bir kitaplık yükünden geliyorlarsa? Varsayılan olarak N yanıtını veriyor, öyle görünüyor ...Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
bjackfly


Başlangıçta ( break g_log if log_level==G_LOG_LEVEL_CRITICAL) çözülemeyen bir kesme noktası koşulunuz olduğunda , en azından gdb 7.8.1'in diğer komutları ayrıştırmayı durduracağını unutmayın. Bu kesme noktası için yürütülmesi gereken ek komutlarınız varsa, commandssatırı satırın önüne koyun condition.
Lekensteyn

@Ve düzenlemenizi orijinal blok alıntıya geri aldım çünkü metin dokümantasyondan birebir alıntıdır ... Aksi takdirde, kendi sözlerim olsaydı düzenlemenize katılırdım.
aculich

@aculich: Anlıyorum. Her durumda kod stili yerine alıntı stilini kullanmanızı tavsiye ederim.
Andry

26

Bu cevap güncel değil. GDB artık doğrudan kaydetmeyi destekliyor. Bu cevaba bakın .

Günlük kaydını kullanabilirsiniz:

(gdb) b main
Breakpoint 1 at 0x8049329
(gdb) info break
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x08049329 <main+16>
(gdb) set logging file breaks.txt
(gdb) set logging on
Copying output to breaks.txt.
(gdb) info break
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x08049329 <main+16>
(gdb) q

Breaks.txt dosyası artık şunları içerir:

Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x08049329 <main+16>

Bunu .gdbinitveya bir --commanddosya için yararlı bir biçime dönüştüren bir AWK komut dosyası yazmak kolaydır. Veya betiğin --eval-commandGDB komut satırından ayrı 's göndermesini bile sağlayabilirsiniz ...

Bu küçük makroyu .gdbinit'e eklemek , bunu yapmanıza yardımcı olacaktır:

# Call with dump_breaks file.txt
define dump_breaks
    set logging file $arg0
    set logging redirect on
    set logging on
    info breakpoints
    set logging off
    set logging redirect off
end

Kes ve yapıştır da aynı şekilde kolaylıkla kullanılabilir, ancak komut dosyası oluşturma yöntemi gitmenin yolu gibi görünüyor.
casualcoder

1
Kes-yapıştırın sadece bir senaryo yazmaktan ve sonra her seferinde tekrar kullanmaktan daha kolay olduğunu düşünmüyorum :) Sonuçta, bu soruyu ilk başta sormanızın nedeni de buydu, bence :)
Johannes Schaub - litb

Günlüğe kaydetme yöntemi yerine kes ve yapıştır kullanmayı kastetmiştim. Komut dosyası şimdiye kadar kesinlikle.
casualcoder

Vaov! gdb başarısız! Her gün kullanıyorum ve birçok özelliğini seviyorum. Ama eksiklik sadece aptalca.
deft_code

4
Bu yanıt şu anda 2 yaşın üzerinde olduğundan daha yeni bir gdb sürümü kullanıyorsanız geçerliliğini yitirmiş olabilir. Gdb 7.2'den itibaren artık save breakpointskomutu kullanabilirsiniz .
aculich

11

GDB komutlarınızı ve kesme noktalarınızı bir .gdbinit dosyasına , gdb>komut istemine yazdığınız gibi koyun ve GDB bunları başlangıçta otomatik olarak yükleyecek ve çalıştıracaktır. Bu, dizin başına bir dosyadır, bu nedenle farklı projeler için farklı dosyalara sahip olabilirsiniz.


1
Bu aslında işe yaramıyor, "uyarı: tracepoints kaydet: kaydedilecek izleme noktası yok." Bu, kesme noktalarının ayarlanmasına rağmen. Gdb 6.8 kullanılıyor.
casualcoder

Bu benim için çalışıyor. GDB, $ HOME / .gdbinit'inizde 'add-auto-load-safe-path /home/johnny/src/.gdbinit' içeriğine sahip global bir .gdbinit'in bulunmasına ihtiyaç duyar ve bu nedenle src / klasöründe ayrı bir .gdbinit bulunur
truthadjustr

9

İçin bir uzantısı anon uzantısı için Johannes' cevabı :

.gdbinit:

define bsave
    shell rm -f brestore.txt
    set logging file brestore.txt
    set logging on
    info break
    set logging off
    # Reformat on-the-fly to a valid GDB command file
    shell perl -n -e 'print "break $1\n" if /^\d+.+?(\S+)$/g' brestore.txt > brestore.gdb
end
document bsave
  store actual breakpoints
end

define brestore
  source brestore.gdb
end
document brestore
  restore breakpoints saved by bsave
end

İle brestoredaha sonra ile kaydedilen kesme noktalarını geri yükleyebilirsiniz bsave.


İşte daha iyi bir normal ifade: perl -ne "print \" break \ $ 1 \ n \ "if /at\s(.*:\d+)/" brestore.txt
George Godik

6

Johannes'in yanıtına uzantı : çıktısını otomatik olarak info breakgeçerli bir GDB komut dosyasına yeniden biçimlendirebilirsiniz :

.gdbinit:

define bsave
   shell rm -f brestore.txt
   set logging file brestore.txt
   set logging on
   info break
   set logging off
   # Reformat on-the-fly to a valid gdb command file
   shell perl -n -e 'print "break $1\n" if /^\d+.+?(\S+)$/g' brestore.txt > brestore.gdb
end
document bsave
  store actual breakpoints
end

Daha sonra içinde geçerli bir komut dosyanız var brestore.gdb.

Uygulama ile derlendiğinde bu benim için çalıştı -g.

Ayrıca Ubuntu 9.10 (Karmic Koala) üzerinde GDB v6.8 ile başarıyla test ettim .


1
Bu pasaj için teşekkürler! Harika çalışıyor. Mac OS 10.5.8'de CarbonEmacs GNU Emacs 22.3.1'de (i386-apple-darwin9.6.0, Carbon Sürüm 1.6.0) GNU gdb 6.3.50-20050815 (Apple sürümü gdb-966) ile başarıyla test edildi.
pestophagous


3

Kesme noktalarını kaydetmek ve geri yüklemek için bsave ve brestore'u GDB komutları olarak tanımlamak için aşağıdakileri ~ / .gdbinit içine koyun .

define bsave
    save breakpoints ~/.breakpoints
end

define brestore
   source ~/.breakpoints
end

1

uyarı: Geçerli çıktı protokolü yeniden yönlendirmeyi desteklemiyor

TUI modunda oturum açmayı etkinleştirmeye çalışırken GDB'de de bu hatayı / uyarıyı alıyorum . Ancak, "TUI olmayan" moddayken günlük kaydı çalışıyor gibi görünüyor. Bu yüzden ne zaman bir şey kaydetmek istersem TUI modundan çıkıyorum. ( Ctrl+X , Ctrl+A İle TUI moduna geri ve ileri geçin ).

İşte böyle çalışıyorum:

  1. GDB'yi başlat (normal modda)
  2. günlüğe kaydetmeyi etkinleştir: set logging on- şimdi şikayet etmemeli.
  3. TUI moduna geri / ileri geçin ve GDB işleri yapın
  4. ne zaman bir şey kaydetmek istersem (büyük bir geri izleme dökümü gibi) - normal moda geçin

Oh, ve eğer "ekran" kullanmayı seviyorsanız (benim yaptığım gibi), aynı kısayol tuşlarını kullandığı için biraz dağınık olacaktır.
Magnux

1

Kesme noktalarını belirli bir dosyaya kaydetmek / yüklemek için önceki bir yanıta aşağıdaki eklemeyi yararlı buldum.

  • Kesme noktalarını kaydedin: bsave {dosya adı}
  • Kesme noktalarını yükle: bload {dosyaadı}

Önceki cevapta olduğu gibi, aşağıdaki kodu ~ / .gdbinit dosyasına ekleyin.

# Save breakpoints to a file
define bsave
    if $argc != 1
        help bsave
    else
    save breakpoints $arg0
    end
end
document bsave
Saves all current defined breakpoints to the defined file in the PWD
Usage: bsave <filename>
end

# Loads breakpoints from a file
define bload
    if $argc != 1
        help bload
    else
        source $arg0
    end
end
document bload
Loads all breakpoints from the defined file in the PWD
Usage: bload <filename>
end

0

Sorun, bir kesme noktası belirlemenin içeriğe duyarlı olmasıdır. Ya foo adında iki statik işleviniz varsa ?

Eğer zaten foo'yu tanımlayan modüllerden birinde hata ayıklıyorsanız, GDB bunu kastettiğinizi varsayacaktır. Eğer sadece bir dosya içine "mola foo" dökümü ve ardından start-up o dosyayı okursanız Ancak, hangi işlevi net olmayacaktır foo demek istiyorsun.


0

Başka fikrin var mı? Ben sahibim

warning: Current output protocol does not support redirection

sonra

set logging on

DÜZENLE:

Bu sorunun "bir kesme noktası listesi nasıl kaydedileceği" olduğunu biliyorum, ancak keşfettim ki, GDB ile "dosyaya kaydedilmiş" kesme noktalarını şu şekilde ayarlayabiliriz:

gdb> source breakpoints.txt

breakpoints.txtbunun gibi bir dosya nerede :

break main.cpp:25
break engine.cpp:465
break wheel.cpp:57
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.