In welchen Szenarien erhält ein Prozess in C ++ ein SIGABRT? Kommt dieses Signal immer aus dem Prozess oder kann dieses Signal von einem Prozess zum anderen gesendet werden?
Gibt es eine Möglichkeit zu identifizieren, welcher Prozess dieses Signal sendet?
Antworten:
abort()
Sendet dem aufrufenden Prozess dasSIGABRT
Signal, so funktioniert dasabort()
grundsätzlich.abort()
wird normalerweise von Bibliotheksfunktionen aufgerufen, die einen internen Fehler oder eine ernsthaft fehlerhafte Einschränkung erkennen. Zum Beispielmalloc()
wird aufgerufen,abort()
wenn seine internen Strukturen durch einen Heap-Überlauf beschädigt werden.quelle
libc
versucht wurde,free()
einen nicht initialisierten / beschädigten ZeigerClose()
Methode hat, sodass sie vergessen wurde. Hatte aber eine großartige Berichterstattung. : rolleyes:SIGABRT
wird häufig von libc und anderen Bibliotheken verwendet, um das Programm bei kritischen Fehlern abzubrechen. Zum Beispiel sendet glibcSIGABRT
im Falle einer erkannten Double-Free- oder anderen Heap-Beschädigung eine.Außerdem verwenden die meisten
assert
ImplementierungenSIGABRT
im Falle einer fehlgeschlagenen Zusicherung.Darüber hinaus
SIGABRT
kann von jedem anderen Prozess wie jedes andere Signal gesendet werden. Natürlich muss der Sendevorgang als derselbe Benutzer oder Root ausgeführt werden.quelle
Sie können jedes Signal über die
kill(2)
Schnittstelle an jeden Prozess senden :kill -SIGABRT 30823
30823 war ein
dash
Prozess, den ich gestartet habe, sodass ich den Prozess, den ich töten wollte, leicht finden konnte.Die
Aborted
Ausgabe ist anscheinend, wiedash
ein SIGABRT gemeldet wird.Es kann direkt unter Verwendung von einem Prozess gesendet werden
kill(2)
, oder ein Verfahren , kann das Signal an sich selbst über sendenassert(3)
,abort(3)
oderraise(3)
.quelle
Dies tritt normalerweise auf, wenn ein Problem mit der Speicherzuordnung vorliegt.
Es ist mir passiert, als mein Programm versucht hat, ein Array mit negativer Größe zuzuweisen.
quelle
Es gibt eine andere einfache Ursache im Fall von c ++.
dh Umfang des Threads beendet, aber Sie haben vergessen, entweder aufzurufen
oder
quelle
Die GNU libc druckt Informationen zu
/dev/tty
einigen schwerwiegenden Zuständen aus, bevor sie aufgerufen wirdabort()
(was dann ausgelöst wirdSIGABRT
). Wenn Sie Ihr Programm jedoch als Dienst ausführen oder auf andere Weise nicht in einem echten Terminalfenster, können diese Meldungen verloren gehen, da keine vorhanden sind tty, um die Nachrichten anzuzeigen.Siehe meinen Beitrag zum Umleiten von libc zum Schreiben an stderr anstelle von / dev / tty:
Abrufen von libc-Fehlermeldungen, Umleiten von / dev / tty
quelle
Ein Fall, in dem ein Prozess SIGABRT von sich selbst erhält: Hrvoje erwähnte, dass ein begrabenes reines virtuelles Wesen von ctor aufgerufen wurde, um einen Abbruch zu erzeugen. Ich habe ein Beispiel dafür neu erstellt. Wenn d hier konstruiert werden soll, ruft es zuerst seine Basisklasse A ctor auf und übergibt den inneren Zeiger an sich selbst. Der A ctor ruft eine reine virtuelle Methode auf, bevor die Tabelle mit einem gültigen Zeiger gefüllt wurde, da d noch nicht erstellt wurde.
kompilieren: g ++ -o aa aa.cpp
ulimit -c unbegrenzt
run: ./aa
Lassen Sie uns nun schnell die Kerndatei sehen und überprüfen, ob SIGABRT tatsächlich aufgerufen wurde:
siehe regs:
Code überprüfen:
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
:) :)
quelle
In meinem Fall lag dies an einer Eingabe in ein Array mit einem Index, der der Länge des Arrays entspricht.
Auf x [5] wird zugegriffen, was nicht vorhanden ist.
quelle
Wie "@sarnold" treffend hervorhebt, kann jeder Prozess ein Signal an einen anderen Prozess senden, daher kann ein Prozess SIGABORT an einen anderen Prozess senden, und in diesem Fall kann der empfangende Prozess nicht unterscheiden, ob er aufgrund seiner eigenen Optimierung von kommt Speicher usw., oder jemand anderes hat "unicastly", senden Sie an ihn.
In einem der Systeme, an denen ich gearbeitet habe, gibt es einen Deadlock-Detektor, der tatsächlich erkennt, ob ein Prozess aus einer Aufgabe herauskommt, indem er einen Herzschlag gibt oder nicht. Wenn nicht, wird der Prozess als Deadlock deklariert und SIGABORT an ihn gesendet.
Ich wollte diese Perspektive nur mit Bezug auf die gestellte Frage teilen.
quelle
Ich werde meine Antwort aus der Perspektive einer wettbewerbsfähigen Programmierung (CP) geben , aber sie gilt auch für andere Bereiche.
Während der Arbeit mit cp sind die Einschränkungen oft recht groß.
Zum Beispiel : Ich hatte eine Frage mit
N, M, Q
solchen Variablen , dass1 ≤ N, M, Q < 10^5
.Der Fehler , den ich machte , war ich ein 2D - Integer - Array der Größe deklarierte
10000 x 10000
inC++
den und kämpfteSIGABRT
Fehlern bei Codechef für fast 2 Tage.Nun, wenn wir rechnen:
Ihre Lösungen für solche Fragen funktionieren auf Ihrem PC (nicht immer), da er sich diese Größe leisten kann.
Die Ressourcen an Codierungsseiten (Online-Richtern) sind jedoch auf wenige KB beschränkt.
Daher der
SIGABRT
Fehler und andere solche Fehler.Fazit:
In solchen Fragen sollten wir kein Array oder Vektor oder einen anderen DS dieser Größe deklarieren, aber unsere Aufgabe ist es, unseren Algorithmus so effizient zu machen, dass er ohne sie (DS) oder mit weniger Speicher funktioniert.
PS : Es kann andere Gründe für diesen Fehler geben. oben war einer von ihnen.
quelle