Apa skenario di mana proses mendapatkan SIGABRT di C ++? Apakah sinyal ini selalu datang dari dalam proses atau dapatkah sinyal ini dikirim dari satu proses ke proses lainnya?
Apakah ada cara untuk mengidentifikasi proses mana yang mengirim sinyal ini?
Jawaban:
abort()
mengirimkan proses panggilanSIGABRT
sinyal, iniabort()
pada dasarnya cara kerjanya.abort()
biasanya dipanggil oleh fungsi pustaka yang mendeteksi kesalahan internal atau beberapa kendala serius rusak. Misalnyamalloc()
akan memanggilabort()
jika struktur internalnya rusak oleh heap overflow.sumber
libc
mencoba memanggilfree()
penunjuk yang tidak diinisialisasi / rusakClose()
metode, jadi itu terlupakan. Memiliki cakupan yang bagus. : rolleyes:SIGABRT
umumnya digunakan oleh libc dan perpustakaan lain untuk membatalkan program jika terjadi kesalahan kritis. Sebagai contoh, glibc mengirimkanSIGABRT
dalam kasus korupsi tumpukan ganda yang terdeteksi atau bebas.Juga, sebagian besar
assert
implementasi memanfaatkanSIGABRT
jika pernyataan gagal.Selanjutnya,
SIGABRT
dapat dikirim dari proses lain seperti sinyal lainnya. Tentu saja, proses pengiriman perlu dijalankan sebagai pengguna atau root yang sama.sumber
Anda dapat mengirim sinyal apa pun ke proses apa pun menggunakan
kill(2)
antarmuka:kill -SIGABRT 30823
30823 adalah
dash
proses yang saya mulai, jadi saya dapat dengan mudah menemukan proses yang ingin saya bunuh.The
Aborted
output rupanya bagaimanadash
melaporkan SIGABRT a.Hal ini dapat dikirim langsung ke setiap proses menggunakan
kill(2)
, atau suatu proses dapat mengirim sinyal untuk dirinya sendiri melaluiassert(3)
,abort(3)
atauraise(3)
.sumber
Ini biasanya terjadi ketika ada masalah dengan alokasi memori.
Itu terjadi pada saya ketika program saya mencoba mengalokasikan array dengan ukuran negatif.
sumber
Ada penyebab sederhana lain dalam kasus c ++.
yaitu ruang lingkup utas berakhir tetapi Anda lupa menelepon juga
atau
sumber
GNU libc akan mencetak informasi
/dev/tty
tentang beberapa kondisi fatal sebelum ia dipanggilabort()
(yang kemudian memicuSIGABRT
), tetapi jika Anda menjalankan program Anda sebagai layanan atau tidak dalam jendela terminal nyata, pesan ini dapat hilang, karena tidak ada tty untuk menampilkan pesan.Lihat posting saya di redirect libc untuk menulis ke stderr bukannya / dev / tty:
Menangkap pesan kesalahan libc, mengalihkan dari / dev / tty
sumber
Sebuah kasus ketika proses mendapatkan SIGABRT dari dirinya sendiri: Hrvoje menyebutkan tentang virtual murni yang terkubur yang dipanggil dari ctor yang membuat abort, saya menciptakan contoh untuk ini. Di sini ketika d akan dibangun, pertama-tama memanggil ctor kelas dasar A, dan meneruskan pointer ke dalam dirinya sendiri. a ctor memanggil metode virtual murni sebelum tabel diisi dengan pointer yang valid, karena d belum dibangun.
kompilasi: g ++ -o aa aa.cpp
ulimit -c tidak terbatas
jalankan: ./aa
sekarang mari kita cepat melihat file inti, dan memvalidasi bahwa SIGABRT memang dipanggil:
lihat regs:
periksa kode:
disas 0x7feae3170c37
http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/
234 sys_tgkill pid_t tgid pid_t pid int sig = 6 = SIGABRT
:)
sumber
Dalam kasus saya, itu disebabkan oleh input dalam array pada indeks yang sama dengan panjang array.
x [5] sedang diakses yang tidak ada.
sumber
Seperti "@sarnold", dengan tepat menunjukkan, setiap proses dapat mengirim sinyal ke proses lain, karenanya, satu proses dapat mengirim SIGABORT ke proses lain & dalam hal ini proses penerima tidak dapat membedakan apakah itu datang karena penyesuaian sendiri dari tweaker sendiri. memori dll, atau orang lain memiliki "unicastly", kirim ke sana.
Dalam salah satu sistem saya bekerja ada satu kebuntuan detektor yang sebenarnya mendeteksi jika proses keluar dari suatu tugas dengan memberikan detak jantung atau tidak. Jika tidak, maka dinyatakan prosesnya dalam kondisi menemui jalan buntu dan mengirim SIGABORT ke sana.
Saya hanya ingin membagikan calon ini dengan referensi pertanyaan yang diajukan.
sumber
Saya akan memberikan jawaban saya dari perspektif pemrograman kompetitif (cp) , tetapi itu berlaku untuk domain lain juga.
Banyak kali saat melakukan cp, kendala cukup besar.
Sebagai contoh : Saya punya pertanyaan dengan variabel
N, M, Q
seperti itu1 ≤ N, M, Q < 10^5
.Kesalahan saya membuat adalah saya menyatakan 2D array integer dari ukuran
10000 x 10000
diC++
dan berjuang denganSIGABRT
kesalahan pada Codechef selama hampir 2 hari.Sekarang, jika kita menghitung:
Solusi Anda untuk pertanyaan-pertanyaan seperti itu akan bekerja pada PC Anda (tidak selalu) karena mampu membayar ukuran ini.
Tetapi sumber daya di situs pengkodean (juri online) terbatas pada beberapa KB.
Oleh karena itu,
SIGABRT
kesalahan dan kesalahan lainnya.Kesimpulan:
Dalam pertanyaan seperti itu, kita tidak boleh mendeklarasikan array atau vektor atau DS lain dari ukuran ini, tetapi tugas kita adalah membuat algoritma kita sedemikian efisien sehingga berfungsi tanpa mereka (DS) atau dengan memori lebih sedikit.
PS : Mungkin ada alasan lain untuk kesalahan ini; di atas adalah salah satunya.
sumber