Mendapatkan GDB untuk menyimpan daftar breakpoints


129

OK, info break mencantumkan breakpoints, tetapi tidak dalam format yang akan bekerja dengan baik dengan menggunakan mereka kembali menggunakan - perintah seperti pada pertanyaan ini . Apakah GDB memiliki metode untuk membuangnya ke file yang dapat diterima untuk input lagi? Terkadang dalam sesi debugging, perlu untuk memulai kembali GDB setelah membangun satu set breakpoint untuk pengujian.

File .gdbinit memiliki masalah yang sama dengan --command. Perintah info break tidak mencantumkan perintah, melainkan tabel untuk konsumsi manusia.

Untuk menguraikan, berikut adalah contoh dari info break :

(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x08048517 <foo :: bar (void) +7>

Jawaban:


204

Pada GDB 7.2 (2011-08-23) Anda sekarang dapat menggunakan perintah save breakpoints .

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.

Gunakan source <filename>untuk mengembalikan breakpoint yang disimpan dari file.


2
bagaimana jika mereka berasal dari beban lib bersama? Tampaknya jawaban N secara default ...Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]
bjackfly

2
@bjackfly digunakan set breakpoint pending onseperti yang dijelaskan dalam cara menjawab Y dalam skrip gdb dan gdb: cara mengatur breakpoint pada pustaka bersama di masa mendatang dengan --command flag
aculich

Perhatikan bahwa ketika Anda memiliki kondisi breakpoint yang tidak dapat diselesaikan saat startup ( break g_log if log_level==G_LOG_LEVEL_CRITICAL), maka setidaknya gdb 7.8.1 akan berhenti mem-parsing perintah lebih lanjut. Jika Anda memiliki perintah tambahan yang harus dijalankan untuk breakpoint itu, letakkan commandsbaris sebelum conditionbaris.
Lekensteyn

@Andry Saya memutar kembali hasil edit Anda ke blockquote asli saya karena teks tersebut adalah kutipan kata demi kata dari dokumentasi ... Saya sebaliknya akan setuju dengan hasil edit Anda jika itu adalah kata-kata saya sendiri.
aculich

@aculich: Begitu. Saya akan merekomendasikan untuk menggunakan gaya kutipan daripada gaya kode dalam hal apa pun.
Andry

26

Jawaban ini sudah usang. GDB sekarang mendukung penyimpanan secara langsung. Lihat jawaban ini .

Anda dapat menggunakan pencatatan:

(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

File breaks.txt sekarang berisi:

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

Menulis skrip AWK yang mengubahnya menjadi format yang berguna untuk file .gdbinitatau --commandmudah. Atau Anda bahkan dapat membuat skrip memancarkan terpisah --eval-commandke baris perintah GDB ...

Menambahkan makro kecil ini ke .gdbinit akan membantu Anda melakukannya:

# 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

Orang bisa dengan mudah menggunakan cut-and-paste, tetapi metode skrip tampaknya menjadi cara untuk pergi.
casualcoder

1
Saya tidak berpikir cut-and-paste lebih mudah daripada hanya menulis skrip sekali, kemudian menggunakannya sekali lagi :) setelah semua, itulah alasan Anda mengajukan pertanyaan ini di tempat pertama, saya pikir :)
Johannes Schaub - litb

Um, maksud saya gunakan cut-and-paste daripada metode logging. Scripting sejauh ini pasti.
casualcoder

Wow! gdb gagal! Saya menggunakannya setiap hari dan menyukai banyak fitur-fiturnya. Tetapi kekurangan hanyalah kebodohan.
deft_code

4
Jawaban ini sekarang sudah lebih dari 2 tahun sehingga mungkin sudah usang jika Anda menggunakan versi gdb yang lebih baru. Pada gdb 7.2 sekarang Anda dapat menggunakan save breakpointsperintah.
aculich

11

Masukkan perintah dan breakpoint GDB Anda dalam file .gdbinit sama seperti Anda mengetiknya di gdb>prompt, dan GDB akan secara otomatis memuat dan menjalankannya saat startup. Ini adalah file per direktori, sehingga Anda dapat memiliki file yang berbeda untuk proyek yang berbeda.


1
Ini sebenarnya gagal, saya mendapat "peringatan: save-tracepoints: tidak ada tracepoint untuk disimpan. ' Ini meskipun breakpoints sedang diatur. Menggunakan gdb 6.8.
casualcoder

Ini bekerja untuk saya. GDB membutuhkan kehadiran global .gdbinit di $ HOME / .gdbinit Anda dengan konten 'add-auto-load-safe-path /home/johnny/src/.gdbinit' dan dengan demikian src / folder juga memiliki .gdbinit terpisah
truthadjustr

9

Perpanjangan ke perpanjangan anon ke jawaban Johannes :

.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

Dengan brestoreAnda kemudian dapat mengembalikan breakpoint yang disimpan bsave.


Berikut regex yang lebih baik: perl -ne "print \" break \ $ 1 \ n \ "jika /at \s(.*:\d+)/" brestore.txt
George Godik

6

Ekstensi ke jawaban dari Johannes : Anda dapat secara otomatis memformat ulang output info breakmenjadi file perintah GDB yang valid:

.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

Setelah itu Anda memiliki file perintah yang valid di brestore.gdb.

Ini berfungsi untuk saya ketika aplikasi dikompilasi dengan -g.

Saya juga berhasil mengujinya dengan GDB v6.8 di Ubuntu 9.10 (Karmic Koala).


1
Terima kasih atas cuplikan ini! Bagus sekali. Berhasil diuji dengan GNU gdb 6.3.50-20050815 (Versi Apple gdb-966) di CarbonEmacs GNU Emacs 22.3.1 (i386-apple-darwin9.6.0, Carbon Version 1.6.0) pada Mac OS 10.5.8.
pestophagous


3

Masukkan berikut ini di ~ / .gdbinit untuk mendefinisikan bsave dan brestore sebagai perintah GDB untuk menyimpan- dan mengembalikan breakpoints.

define bsave
    save breakpoints ~/.breakpoints
end

define brestore
   source ~/.breakpoints
end

1

peringatan: Protokol keluaran saat ini tidak mendukung pengalihan

Saya juga mendapatkan kesalahan / peringatan ini di GDB ketika mencoba mengaktifkan logging dalam mode TUI . Namun, logging tampaknya berfungsi ketika dalam mode "non-TUI". Jadi saya meninggalkan mode TUI setiap kali saya ingin mencatat sesuatu. (Beralih bolak-balik ke mode TUI dengan Ctrl+X , Ctrl+A ).

Begini cara saya bekerja:

  1. mulai GDB (dalam mode normal)
  2. aktifkan logging: set logging on- sekarang seharusnya tidak mengeluh.
  3. beralih / balik ke mode TUI dan melakukan hal-hal GDB
  4. setiap kali saya ingin mencatat sesuatu (seperti dump backtrace besar) - beralih ke mode normal

Oh, dan jika Anda suka menggunakan "layar" (seperti yang saya lakukan) itu akan menjadi sedikit berantakan, karena menggunakan tombol pintas yang sama.
Magnux

1

Saya menemukan tambahan berikut untuk jawaban sebelumnya yang berguna untuk menyimpan / memuat breakpoint ke file tertentu.

  • Simpan breakpoints: bsave {nama file}
  • Muat breakpoints: bload {nama file}

Seperti pada jawaban sebelumnya, tambahkan kode berikut ke file ~ / .gdbinit

# 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

Masalahnya adalah bahwa menetapkan breakpoint adalah konteks sensitif. Bagaimana jika Anda memiliki dua fungsi statis bernama foo ?

Jika Anda telah men-debug salah satu modul yang mendefinisikan foo, maka GDB akan menganggap Anda bermaksud melakukannya. Tetapi jika Anda hanya membuang "break foo" ke dalam file dan kemudian membaca file itu saat start-up, tidak akan jelas fungsi foo yang Anda maksud.


0

Ada ide lain? Saya punya

warning: Current output protocol does not support redirection

setelah

set logging on

EDIT:

Saya tahu pertanyaan itu adalah "bagaimana cara menyimpan daftar breakpoints", namun saya baru saja menemukan, bahwa dengan GDB kita dapat dengan mudah mengatur breakpoint "save in file" oleh

gdb> source breakpoints.txt

di mana breakpoints.txtfile seperti ini:

break main.cpp:25
break engine.cpp:465
break wheel.cpp:57
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.