![]() |
Exception abfangen und Fortsetzen
Hi,
ich habe ein RIESEN Problem. Eventuell bin ich nur zu doof zum suchen, bzw. ich suche nach den falschen Sachen. Ich schreibe einen Newsletter-Versender der unter Debian läuft. Es laufen ca. 40 Threads um die Mails per Synapse zu versenden. Es wird ein Bodyhash und DKIM berechnet. Dabei wird ab und zu eine Exception im OpenSSL ausgelöst. Ich kann diesen Fehler leider nicht reproduzieren. Mal läuft das Programm 4 Tage durch, dann kommt der Fehler schon nach 2 Stunden. Ich hänge die Exception die mir gdb anzeigt hier dran. Vielleicht hat ja jemand eine Idee. Nun dachte ich, egal, eine Mail weniger die rausgeht und möchte die Exception abfangen. Das mache ich mit einem Override von HandleException. Nun zur eigentlichen Frage. Gibt es eine Möglichkeit das er danach weiter macht, und nicht das Programm "intern" neu Startet? Hier die Exception die kommt:
Code:
Vielen dank im Voraus
Thread 5 "newsletter" received signal SIGPIPE, Broken pipe.
[Switching to Thread 0x7ffff6dc8700 (LWP 2906)] __libc_write (nbytes=35, buf=0x7fffe00f4c43, fd=5) at ../sysdeps/unix/sysv/linux/write.c:26 26 return SYSCALL_CANCEL (write, fd, buf, nbytes); (gdb) bt #0 __libc_write (nbytes=35, buf=0x7fffe00f4c43, fd=5) at ../sysdeps/unix/sysv/linux/write.c:26 #1 __libc_write (fd=5, buf=0x7fffe00f4c43, nbytes=35) at ../sysdeps/unix/sysv/linux/write.c:24 #2 0x00007ffff7b21ad5 in ?? () from /lib/x86_64-linux-gnu/libcrypto.so #3 0x00007ffff7b1cd5a in ?? () from /lib/x86_64-linux-gnu/libcrypto.so #4 0x00007ffff7b1bdb3 in ?? () from /lib/x86_64-linux-gnu/libcrypto.so #5 0x00007ffff7b1c253 in BIO_write () from /lib/x86_64-linux-gnu/libcrypto.so #6 0x00007ffff79f0877 in ?? () from /lib/x86_64-linux-gnu/libssl.so #7 0x00007ffff79f1b71 in ?? () from /lib/x86_64-linux-gnu/libssl.so #8 0x00007ffff7a03f82 in ?? () from /lib/x86_64-linux-gnu/libssl.so #9 0x00007ffff7a040b3 in SSL_write () from /lib/x86_64-linux-gnu/libssl.so #10 0x0000000000656478 in SSLWRITE (SSL=0x7fffe002f370, BUF=0x686960, NUM=6) at ../HelperUnits/Synapse/ssl_openssl_lib.pas:1328 #11 0x00000000004c8d07 in SENDBUFFER (this=0x7fffe00557d8, BUFFER=0x686960, LEN=6) at ../HelperUnits/Synapse/ssl_openssl.pas:637 #12 0x000000000062d538 in SENDBUFFER (this=0x7fffe00a3f38, BUFFER=0x686960, LENGTH=6) at ../HelperUnits/Synapse/blcksock.pas:4066 #13 0x0000000000626968 in SENDSTRING (this=0x7fffe00a3f38, DATA=0x686960 "QUIT\r\n") at ../HelperUnits/Synapse/blcksock.pas:2113 #14 0x00000000004bf57c in LOGOUT (this=0x7fffe0061338) at ../HelperUnits/Synapse/smtpsend.pas:486 #15 0x000000000049567d in SENDTHREAD (VARPTR=0xa1b9d8) at ../uSendMailThrdRuleVx.pas:651 #16 0x0000000000428750 in CTHREADS_$$_THREADMAIN$POINTER$$POINTER () #17 0x0000000000493590 in ?? () #18 0x0000000000a1b9d8 in ?? () #19 0x0000000000400000 in ?? () #20 0x00000000000004c8 in ?? () #21 0x0000000000000000 in ?? () |
AW: Exception abfangen und Forsetzen
Wie sieht denn dein Quelltext in uSendMailThrdRuleVx.pas um die Zeile 651 aus?
|
AW: Exception abfangen und Forsetzen
Dort logge ich mich aus.
SMTP.Logout; Die ganze Routine ist mit try except. Aber es kommt kein except. Ich denke mal weil es im sysdeps/unix/sysv/linux/write.c:26 passiert und nicht in meinem Programm. Edit: Vielleicht ist es noch wichtige das ich das mit CustApp mache. |
AW: Exception abfangen und Forsetzen
Hi,
das Programm ist heute Nacht wieder abgeschmiert. Er kommt allerdings NICHT durch das HandleException wenn das passiert. Kann man das ändern? Was mache ich falsch? Das Programm ist nicht gestript. Vielen dank im Voraus |
AW: Exception abfangen und Forsetzen
Nutzt du irgendwo Threads, die nicht durch TThread behandelt werden?
In der VCL und im TThread ist ein try-except um alles drumrum, (die Exception im TThread wird aber standardmäßig nur abgefangen, aber nicht behandelt .... niemand reagiert drauf und loggt die oder zeugt sie an) Wenn eine Exception bis zum System durchrauscht, dann wird der komplette Prozess umgegehend beendet. Aber vermutlich sollte sich dann zumindestens in der Windows-Ereignisanzeige ein Eintrag finden lassen. |
AW: Exception abfangen und Forsetzen
Zitat:
erstmal danke für die Antwort. Aber das ist ein Unix Konsolen Programm. Steht im ersten Beitrag. Im moment starte ich die Threads wie folgt: BeginThread(@SendThread,@ThreadData[Idx]); Ist unter Unix die TThread version besser? |
AW: Exception abfangen und Forsetzen
Zitat:
|
AW: Exception abfangen und Forsetzen
Ups.
TThread arbeitet dort aber gleich und FMX macht auch seine Try-Except drumrum. (betrifft also nicht nur VCL) Hmmm, Linux hat doch auch ein paar Logs im System. Streht da denn nicht dann auch was drin, wenn ein Programm hart abraucht? |
AW: Exception abfangen und Forsetzen
Hi,
erstmal sorry für die späte Antwort. Aber ich musste der "Regierung" versprechen das ich Weihnachten nicht an den PC gehe. Nochmal zu meinem Problem. Nein, in den Logs steht nix. Nun nochmal zu meiner eigentlichen frage: Kann ich irgendwie mitbekommen das eine exception in einer lib/dll aufgetreten ist? Wenn ja, wie? Vielen dank nochmal im Voraus |
AW: Exception abfangen und Forsetzen
Ich weiß nicht wie es in Linux mit Laufzeitpackages (BPL) aussieht.
In Windows hat ja jeder EXE/DLL seine eigene RTTI (außer wenn mit BPLs kompiliert wurde), womit beim Übergang von Exceptions die andere Seite nichts mit der Exception-Klasse anfangen kann. Wenn in der Library/DLL eine Exception auttritt, diese Funktion von der EXE aus aufgerufen wurde, dann geht zwar die Exception in die EXE über, aber die Delphi-Exception und deren Message-Text ist drüben dann nicht (direkt) bekannt. Von einer Exception in einem Thread, der z.B. ausschließlich innerhalb der Library/DLL arbeitet, davon bekommt die EXE natürlich nichts mit. Sowas wie Eurekalog/MadExcept fügten einen Hook ein, welcher Exceptions abfängt. k.A. ob sowas schon für Linux+Delphi existiert. |
AW: Exception abfangen und Forsetzen
Im Trace sieht man, dass das Logout noch ein "Quit" hinschicken will.
Ist vielleicht hier eine Race Condition vorhanden, dass z.B. das SSL nicht mehr richtig geladen ist oder so? Du hast ja was mit 40 Threads gearbeitet wird. Die Fragen die mir in den Kopf springen: Alles über eine Verbindung? Jeder Thread eine eigene? Wie wurde das SSL initialisiert bzw. wie wird das abgeräumt? Ist das OpenSSL threadsafe? ___ Zu Try / Except gibt es auf Coding BOTT ein Video: try / finally / except - Schutzblöcke in Delphi kurz erklärt ![]() |
AW: Exception abfangen und Forsetzen
Hi,
Jeder Thread hat seinen eigenen SMTP den er beim Start des Threads im Thread erstellt. Im Fehlerfall wird der gelöscht und neu erstellt. Das ist aber nur zur Sicherheit und meines wissen noch nicht passiert. OpenSSL wird beim Programm Start Initialisiert. OpenSSL ist Threadfest. Nochmal kurz an @himitsu. Es handelt sich um FreePascal. Ich selber arbeite, wenn ich es brauche, mit CodeTyphon. Da ich auch Programme für ARM Prozessoren schreibe. Meint ihr die Class TThread wäre besser und ich könnte dann nur den einen Thread beenden? |
AW: Exception abfangen und Forsetzen
Hmm, dann hab ich nur noch folgende Idee:
Das Quit wird an den SMTP Server übermittelt. Was ist wenn ein Quit#13#10 geschickt wird und "der" aktuell SMTP auf Linux läuft und dann die Verbindung nach dem #13 beendet, dass das "Broken Pipe" entsteht, weil das #10 noch durch will? Du könntest also mal Loggen, bei welchen SMTP Server das entsteht. Edit: In der RFC steht CRLF
Code:
4.1.1.10. QUIT (QUIT)
This command specifies that the receiver MUST send a "221 OK" reply, and then close the transmission channel. The receiver MUST NOT intentionally close the transmission channel until it receives and replies to a QUIT command (even if there was an error). The sender MUST NOT intentionally close the transmission channel until it sends a QUIT command, and it SHOULD wait until it receives the reply (even if there was an error response to a previous command). If the connection is closed prematurely due to violations of the above or system or network failure, the server MUST cancel any pending transaction, but not undo any previously completed transaction, and generally MUST act as if the command or transaction in progress had received a temporary error (i.e., a 4yz response). The QUIT command may be issued at any time. Any current uncompleted mail transaction will be aborted. Syntax: quit = "QUIT" CRLF Evtl. das hier? ![]() |
AW: Exception abfangen und Forsetzen
Hi,
also ich habe hier 10 MailServer. Dort habe ich eben knapp 100.000 Mails hin gesendet. Natürlich Fehlerfrei. :( Wie schon angemerkt, der Fehler ist nicht Reproduzierbar. Leider. Ich glaube nach einem "generellen" Fehler braucht man nicht suchen. Ich schätze das ich vor Weihnachten locker 1 Mio. Mails ohne Fehler gesendet habe. Wenn ich doch nur diese blöde Exception mitbekommen würde. Trotzdem vielen dank für die Hilfe. |
AW: Exception abfangen und Forsetzen
Zitat:
...Spammer. :zwinker: :stupid: [Scherz OFF] |
AW: Exception abfangen und Forsetzen
Ne, Newsletter. :-D Außerdem sind es lokale Mailserver mserver100.intern - mserver109.intern mit der EMailadresse test@
Irgendwie muss ich das Programm ja "fordern". Ich glaube fast das ich den Fehler nie finden werde.... Mit ist aber was eingefallen. Kann man vielleicht folgendes abfangen? Dann könnte ich einfach diesen einen Thread neu Starten.
Code:
Thread 5 "newsletter" received signal SIGPIPE, Broken pipe.
|
AW: Exception abfangen und Fortsetzen
Abfang ist ja kein Problem.
Schutzblock drum und im
Code:
die e.message auslesen und reagieren.
on e: Exception
Besser wäre noch, wenn es eine spezifischere Exception gibt als "Exception". Ich denke aber auch, dass die Mail bereits richtig versandt ist. Das Problem halte ich für ein ungünstiges Abräumen. |
AW: Exception abfangen und Fortsetzen
Hi,
leider geht das nicht mit dem Schutzblock (try/except). Da der Fehler nicht im Programm auftritt sondern in OpenSSL (siehe 1. Post von mir). Das habe ich schon alles versucht. Wie gesagt, ich stehe total auf dem Schlauch.......... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:20 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz