Ketika saya mendapatkan pengecualian, seringkali dari dalam tumpukan panggilan. Ketika ini terjadi, lebih sering daripada tidak, baris kode menyinggung yang sebenarnya disembunyikan dari saya:
tmp.rb:7:in `t': undefined method `bar' for nil:NilClass (NoMethodError)
from tmp.rb:10:in `s'
from tmp.rb:13:in `r'
from tmp.rb:16:in `q'
from tmp.rb:19:in `p'
from tmp.rb:22:in `o'
from tmp.rb:25:in `n'
from tmp.rb:28:in `m'
from tmp.rb:31:in `l'
... 8 levels...
from tmp.rb:58:in `c'
from tmp.rb:61:in `b'
from tmp.rb:64:in `a'
from tmp.rb:67
Pemotongan "... 8 tingkat ..." itu menyebabkan saya banyak masalah. Saya tidak memiliki banyak kesuksesan googling untuk yang satu ini: Bagaimana saya memberi tahu ruby bahwa saya ingin dump menyertakan tumpukan penuh?
ruby
exception
stack-trace
Sniggerfardimungus
sumber
sumber
Jawaban:
Pengecualian # backtrace memiliki seluruh tumpukan di dalamnya:
(Terinspirasi oleh blog Ruby Inside Peter Cooper )
sumber
raise
. Tidak perlu secara eksplisit menentukan eksekusi yang ingin Anda tingkatkan.Anda juga bisa melakukan ini jika Anda ingin satu kalimat:
sumber
raise
bisa digunakan tanpa argumen. Saya tidak tahu bahwa iturescue
akan diperlakukan dengan benar sebagai satu-liner. Saya juga benar-benar mengabaikan vars global seperti itu$!
.puts "this line was reached by #{caller.join("\n")}"
y caller
untuk mencetak output seperti jejak tumpukan Java.caller(0,2)
akan mengembalikan dua entri terbaru di stacktrace. Bagus untuk menghasilkan stacktraces yang disingkat.Ini menghasilkan deskripsi kesalahan dan bersih, stacktrace indentasi bagus:
sumber
IRB memiliki pengaturan untuk "fitur" yang mengerikan ini, yang dapat Anda sesuaikan.
Buat file bernama
~/.irbrc
yang termasuk baris berikut:Ini memungkinkan Anda untuk melihat
irb
setidaknya 100 frame stack . Saya belum dapat menemukan pengaturan yang setara untuk runtime non-interaktif.Informasi terperinci tentang kustomisasi IRB dapat ditemukan di buku Beliung .
sumber
Satu liner untuk callstack:
Satu liner untuk callstack tanpa semua permata:
Satu liner untuk callstack tanpa semua permata dan relatif terhadap direktori saat ini
sumber
Ini meniru jejak Ruby resmi, jika itu penting bagi Anda.
Yang mengherankan, itu tidak menangani 'unhandled exception' dengan benar, melaporkannya sebagai 'RuntimeError', tetapi lokasinya benar.
sumber
Saya mendapatkan kesalahan ini ketika mencoba memuat lingkungan pengujian saya (melalui tes rake atau autotest) dan saran IRB tidak membantu. Saya akhirnya membungkus seluruh test / test_helper.rb saya di blok begin / rescue dan semuanya sudah beres.
sumber
[periksa semua utas jejak untuk menemukan penyebabnya]
Bahkan tumpukan panggilan yang diperluas sepenuhnya masih dapat menyembunyikan baris kode yang menyinggung dari Anda saat Anda menggunakan lebih dari satu utas!
Contoh: Satu utas adalah iterating ruby Hash, utas lainnya sedang mencoba memodifikasinya. LEDAKAN! Pengecualian! Dan masalah dengan jejak tumpukan yang Anda dapatkan ketika mencoba untuk memodifikasi hash 'sibuk' adalah bahwa ia menunjukkan Anda rantai fungsi ke tempat di mana Anda mencoba untuk memodifikasi hash, tetapi itu TIDAK menunjukkan siapa yang saat ini mengulanginya secara paralel ( siapa yang memilikinya)! Inilah cara untuk mengetahuinya dengan mencetak jejak tumpukan untuk SEMUA utas yang saat ini berjalan. Begini cara Anda melakukan ini:
Cuplikan kode di atas berguna bahkan hanya untuk tujuan pendidikan karena dapat menunjukkan kepada Anda (seperti x-ray) berapa banyak utas yang Anda miliki (versus berapa banyak yang Anda pikir Anda miliki - cukup sering keduanya adalah angka yang berbeda;)
sumber
Anda juga dapat menggunakan backtrace Ruby gem (saya penulis):
sumber