Saya memiliki aplikasi Python ini yang macet dari waktu ke waktu dan saya tidak tahu di mana.
Apakah ada cara untuk memberi sinyal juru bahasa Python untuk menunjukkan kepada Anda kode persis yang sedang berjalan?
Semacam stacktrace on-the-fly?
Pertanyaan-pertanyaan Terkait:
Jawaban:
Saya memiliki modul yang saya gunakan untuk situasi seperti ini - di mana suatu proses akan berjalan untuk waktu yang lama tetapi kadang-kadang macet karena alasan yang tidak diketahui dan tidak dapat direproduksi. Agak aneh, dan hanya berfungsi di unix (memerlukan sinyal):
Untuk menggunakannya, panggil saja fungsi listen () di beberapa titik ketika program Anda dijalankan (Anda bahkan bisa menempelkannya di site.py agar semua program python menggunakannya), dan biarkan dijalankan. Kapan saja, kirim proses sinyal SIGUSR1, menggunakan kill, atau dengan python:
Ini akan menyebabkan program memecah konsol python pada titik saat ini, menunjukkan jejak stack, dan membiarkan Anda memanipulasi variabel. Gunakan control-d (EOF) untuk terus berjalan (meskipun perhatikan bahwa Anda mungkin akan mengganggu I / O dll pada titik yang Anda beri sinyal, sehingga tidak sepenuhnya tidak mengganggu.
Saya punya skrip lain yang melakukan hal yang sama, kecuali itu berkomunikasi dengan proses yang berjalan melalui pipa (untuk memungkinkan proses debugging latar belakang dll). Agak besar untuk memposting di sini, tapi saya telah menambahkannya sebagai resep buku resep python .
sumber
faulthandler
modul (dan backport-nya yang ditemukan di PyPI) untuk penangan sinyal level C yang akan mencetak tumpukan Python tanpa memerlukan loop interpreter untuk menjadi responsif.Saran untuk memasang pengendali sinyal adalah saran yang bagus, dan saya sering menggunakannya. Misalnya, bzr secara default menginstal pawang SIGQUIT yang memanggil
pdb.set_trace()
untuk segera menjatuhkan Anda ke prompt pdb . (Lihat sumber modul bzrlib.breakin untuk detail yang tepat.) Dengan pdb Anda tidak hanya bisa mendapatkan jejak stack saat ini tetapi juga memeriksa variabel, dll.Namun, kadang-kadang saya perlu men-debug proses yang saya tidak memiliki pandangan jauh ke depan untuk menginstal handler sinyal masuk. Di linux, Anda dapat melampirkan gdb ke proses dan mendapatkan jejak tumpukan python dengan beberapa makro gdb. Masukan http://svn.python.org/projects/python/trunk/Misc/gdbinit di
~/.gdbinit
, maka:gdb -p
PID
pystack
Sayangnya, ini tidak sepenuhnya dapat diandalkan, tetapi sebagian besar berfungsi.
Akhirnya, melampirkan
strace
sering dapat memberi Anda ide bagus tentang apa yang dilakukan suatu proses.sumber
python-dbg
). Tanpa simbol-simbol itu, Anda sepertinya tidak mendapatkan banyak informasi berguna.Unable to locate python frame
ke setiap perintahSaya hampir selalu berurusan dengan banyak utas dan utas utama umumnya tidak melakukan banyak hal, jadi yang paling menarik adalah membuang semua tumpukan (yang lebih mirip dump Java). Berikut ini adalah implementasi berdasarkan blog ini :
sumber
Mendapatkan jejak stack dari program python yang tidak siap , berjalan di stock python tanpa simbol debugging dapat dilakukan dengan pyrasite . Bekerja seperti pesona bagi saya di Ubuntu Trusty:
(Hat tip ke @Albert, yang jawabannya berisi petunjuk untuk ini, di antara alat-alat lain.)
sumber
dump_stacks.py
sederhananyaimport traceback; traceback.print_stack()
traceback -l
memberi Anda daftar skrip python standar yang dapat Anda gunakan, dandump_stacks.py
merupakan salah satunya. Jika Anda menggunakan milik Anda sendiri (misalnya untuk menulis jejak stack ke file) mungkin bijaksana untuk menggunakan nama yang berbeda.apt-get install gdb python-dbg
(atau setara) sebelum menjalankan pyrasite, jika tidak maka diam-diam akan gagal. Sebaliknya, berfungsi seperti mantra!Anda juga dapat memformat jejak tumpukan dengan baik, lihat dokumen .
Sunting : Untuk mensimulasikan perilaku Java, seperti yang disarankan oleh @Douglas Leeder, tambahkan ini:
ke kode startup di aplikasi Anda. Kemudian Anda dapat mencetak tumpukan dengan mengirim
SIGUSR1
ke proses Python yang sedang berjalan.sumber
The traceback modul memiliki beberapa fungsi yang bagus, di antaranya: print_stack:
sumber
import traceback; f = open('/tmp/stack-trace.log', 'w') traceback.print_stack(file=f) f.close()
Anda dapat mencoba modul faulthandler . Instal menggunakan
pip install faulthandler
dan tambahkan:di awal program Anda. Kemudian kirim SIGUSR1 ke proses Anda (mis .:)
kill -USR1 42
untuk menampilkan traceback Python semua utas ke keluaran standar. Baca dokumentasi untuk opsi lebih lanjut (mis: masuk ke file) dan cara lain untuk menampilkan traceback.Modul ini sekarang merupakan bagian dari Python 3.3. Untuk Python 2, lihat http://faulthandler.readthedocs.org/
sumber
Apa yang benar-benar membantu saya di sini adalah tip spiv (yang akan saya pilih dan komentari jika saya memiliki poin reputasi) untuk mendapatkan jejak stack dari proses Python yang tidak siap . Kecuali itu tidak berfungsi sampai saya memodifikasi skrip gdbinit . Begitu:
unduh http://svn.python.org/projects/python/trunk/Misc/gdbinit dan masukkan
~/.gdbinit
edit, ubah[edit: tidak lagi diperlukan; file tertaut sudah memiliki perubahan ini pada 2010-01-14]PyEval_EvalFrame
menjadiPyEval_EvalFrameEx
Lampirkan gdb:
gdb -p PID
Dapatkan jejak tumpukan python:
pystack
sumber
No symbol "co" in current context.
Saya akan menambahkan ini sebagai komentar untuk tanggapan haridsv , tetapi saya tidak memiliki reputasi untuk melakukannya:
Beberapa dari kita masih terjebak pada versi Python yang lebih tua dari 2,6 (diperlukan untuk Thread.ident), jadi saya mendapatkan kode yang berfungsi di Python 2.5 (meskipun tanpa nama utas yang ditampilkan) seperti:
sumber
python -dv yourscript.py
Itu akan membuat penerjemah berjalan dalam mode debug dan memberi Anda jejak apa yang dilakukan penerjemah.
Jika Anda ingin men-debug kode secara interaktif, Anda harus menjalankannya seperti ini:
python -m pdb yourscript.py
Itu memberi tahu interpreter python untuk menjalankan skrip Anda dengan modul "pdb" yang merupakan debugger python, jika Anda menjalankannya seperti itu interpreter akan dieksekusi dalam mode interaktif, seperti halnya GDB
sumber
Lihatlah
faulthandler
modul, baru dalam Python 3.3. Sebuahfaulthandler
backport untuk digunakan dalam Python 2 tersedia di PyPI.sumber
Pada Solaris, Anda dapat menggunakan pstack (1) Tidak diperlukan perubahan pada kode python. misalnya.
sumber
pstack
yang melakukan hal yang samaJika Anda menggunakan sistem Linux, gunakan kehebatan
gdb
dengan ekstensi debug Python (bisa dipython-dbg
ataupython-debuginfo
paket). Ini juga membantu dengan aplikasi multithreaded, aplikasi GUI dan modul C.Jalankan program Anda dengan:
Ini menginstruksikan
gdb
untuk mempersiapkanpython <programname>.py <arguments>
danr
melepaskannya.Sekarang ketika Anda memprogram hang, beralih ke
gdb
konsol, tekan Ctr+Cdan jalankan:Lihat contoh sesi dan info lebih lanjut di sini dan di sini .
sumber
Saya mencari solusi untuk men-debug thread saya dan saya menemukannya di sini berkat haridsv. Saya menggunakan versi yang sedikit disederhanakan menggunakan traceback.print_stack ():
Untuk kebutuhan saya, saya juga memfilter utas berdasarkan nama.
sumber
Layak untuk melihat Pydb , "versi diperluas dari Python debugger longgar berdasarkan pada set perintah gdb". Ini termasuk manajer sinyal yang dapat memulai debugger ketika sinyal tertentu dikirim.
Proyek Summer of Code 2006 melihat penambahan fitur debugging jarak jauh ke pydb dalam modul yang disebut mpdb .
sumber
Saya meretas beberapa alat yang terhubung ke proses Python yang sedang berjalan dan menyuntikkan beberapa kode untuk mendapatkan kulit Python.
Lihat di sini: https://github.com/albertz/pydbattach
sumber
pyrasite
bekerja dengan sempurna!Ini dapat dilakukan dengan mata-mata yang sangat baik . Ini adalah profiler pengambilan sampel untuk program Python , jadi tugasnya adalah melampirkan ke proses Python dan mencicipi tumpukan panggilan mereka. Oleh karena itu,
py-spy dump --pid $SOME_PID
semua yang perlu Anda lakukan untuk membuang tumpukan panggilan dari semua utas dalam$SOME_PID
proses. Biasanya diperlukan peningkatan hak (untuk membaca memori proses target ').Berikut ini contoh tampilannya untuk aplikasi Python berulir.
sumber
pyringe adalah debugger yang dapat berinteraksi dengan menjalankan proses python, mencetak jejak stack, variabel, dll. tanpa pengaturan apriori.
Meskipun saya sering menggunakan solusi penangan sinyal di masa lalu, masih sering kali sulit untuk mereproduksi masalah di lingkungan tertentu.
sumber
pyrasite
,, bekerja seperti pesona bagi saya.Tidak ada cara untuk menghubungkan ke proses python berjalan dan mendapatkan hasil yang masuk akal. Apa yang saya lakukan jika proses mengunci adalah mengaitkan strace dan mencoba mencari tahu apa yang sebenarnya terjadi.
Sayangnya sering strace adalah pengamat yang "memperbaiki" kondisi balapan sehingga hasilnya juga tidak berguna di sana.
sumber
Anda dapat menggunakan PuDB , debugger Python dengan antarmuka kutukan untuk melakukan ini. Cukup tambahkan
ke kode Anda dan gunakan Ctrl-C ketika Anda ingin istirahat. Anda dapat melanjutkan
c
dan memecahkan lagi beberapa kali jika Anda melewatkannya dan ingin mencoba lagi.sumber
Saya di kamp GDB dengan ekstensi python. Ikuti https://wiki.python.org/moin/DebuggingWithGdb , yang artinya
dnf install gdb python-debuginfo
atausudo apt-get install gdb python2.7-dbg
gdb python <pid of running process>
py-bt
Juga pertimbangkan
info threads
danthread apply all py-bt
.sumber
Traceback (most recent call first): Python Exception <class 'gdb.error'> No frame is currently selected.: Error occurred in Python command: No frame is currently selected.
saat menjalankanpy-bt
digdb
?sudo
. saya perlu menjalankangdb pyton <pid>
sebagai sudo juga.Cara debug fungsi apa saja di konsol :
Buat fungsi tempat Anda menggunakan pdb.set_trace () , lalu fungsi yang Anda inginkan untuk debug.
Kemudian panggil fungsi yang dibuat:
Selamat men-debug :)
sumber
Saya tidak tahu apa pun yang mirip dengan respons java terhadap SIGQUIT , jadi Anda mungkin harus membuatnya di dalam aplikasi Anda. Mungkin Anda bisa membuat server di utas lain yang bisa mendapatkan stacktrace tentang respons terhadap suatu pesan?
sumber
gunakan modul inspect.
stack (konteks = 1) Kembalikan daftar catatan untuk stack di atas bingkai pemanggil.
Saya merasa memang sangat membantu.
sumber
Dalam Python 3, pdb akan secara otomatis menginstal penangan sinyal saat pertama kali Anda menggunakan c (ont (inue)) di debugger. Menekan Control-C sesudahnya akan menjatuhkan Anda kembali ke sana. Dalam Python 2, berikut ini adalah satu-liner yang harus bekerja bahkan dalam versi yang relatif lama (diuji pada 2.7 tetapi saya memeriksa sumber Python kembali ke 2.4 dan terlihat oke):
pdb layak dipelajari jika Anda menghabiskan banyak waktu untuk debugging Python. Antarmuka agak tumpul tetapi harus akrab bagi siapa saja yang telah menggunakan alat serupa, seperti gdb.
sumber
Jika Anda perlu melakukan ini dengan uWSGI, ia memiliki built-in Python Tracebacker dan itu hanya masalah mengaktifkannya dalam konfigurasi (nomor terlampir pada nama untuk setiap pekerja):
Setelah selesai, Anda dapat mencetak jejak balik hanya dengan menghubungkan ke soket:
sumber
Pada titik di mana kode dijalankan, Anda dapat memasukkan potongan kecil ini untuk melihat jejak tumpukan cetakan yang diformat dengan baik. Diasumsikan bahwa Anda memiliki folder yang dipanggil
logs
di direktori root proyek Anda.sumber