suche "sauberste" methode um automatisch gestartetes firefox wieder zu beenden

Begonnen von frank, 24 August 2020, 11:12:06

Vorheriges Thema - Nächstes Thema

frank

moin.

ich starte auf pi3/buster automatisch ein mit apt-get installiertes firefox-esr, um ein screenshot zu generieren.

hminfo:lastErrChange:.* {
my $ps = "\n".`ps -C firefox-esr`;
$ps =~ s/\n$//;
Log(1, "----- firefox start-ps ----- -> $ps");
my $pid = `pidof firefox-esr`;
$pid =~ s/\n$//;
Log(1, "----- firefox start-pids ----- -> $pid");
if($ps =~ m/<defunct>/ && $pid) {
Log(1, "----- firefox kill-zombie ----- -> $pid");
my @pids = split(' ',$pid);
#system("kill -9 $pids[-1]");
system("pkill -f firefox-esr");
$pid = `pidof firefox-esr`;
$pid =~ s/\n$//;
Log(1, "----- firefox new-pids ----- -> $pid");
}
if(!$pid) {
#system('/usr/lib/firefox-esr/firefox-esr -headless localhost:8084/fhem?room=00_hminfo &');
fhem("defmod at_start_ff at +00:00:30 {system(
'/usr/lib/firefox-esr/firefox-esr -headless -private localhost:8084/fhem?room=00_hminfo &')
}");
}
}



"beendet wird es mit folgendem notify, wenn der screenshot erstellt wurde:

hminfo:screenshot:.* {
if(ReadingsVal("DLNA_84a466d8e6d1","presence","offline") eq "online") {
fhem("set DLNA_84a466d8e6d1 stream http://raspberrypi:8083/fhem/rss/rss_tv_08.jpg");
fhem("sleep 30; set DLNA_84a466d8e6d1 stop");
}
my $pid = `pidof firefox-esr`;
$pid =~ s/\n//;
Log(1, "----- firefox close-pids ----- -> $pid");
if($pid) {
my @pids = split(' ',$pid);
Log(1, "----- firefox kill-pid ----- -> $pids[-1]");
fhem("defmod at_kill_ff at +00:01 {system('kill -15 ".$pids[-1]." &')}");
}
}




beim start werden mit "pidof" immer 4 pids angezeigt, die ich auch unter top finden kann

2020.08.22 11:23:01.540 1: ----- firefox new-pids ----- -> 10982 10944 10897 10857  #meine fhem.log ausgabe

root@raspberrypi:/home/pi# pidof firefox-esr
10982 10944 10897 10857

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
10857 fhem      20   0  606860 168716  94676 S   0.0  17.8   0:12.05 firefox-esr
10897 fhem      20   0  456136 126724  91672 S   0.0  13.4   0:12.72 Web Content
10944 fhem      20   0  383616  77200  62452 S   0.0   8.1   0:02.59 WebExtensions
10982 fhem      20   0  366004  56392  47320 S   0.0   5.9   0:00.79 Web Content



die letzte pid von "pidof" (kleinste zahl) ist immer der hauptprozess "firefox-esr"
wenn ich diesen hauptprozess mit "kill -15 10857" beende, werden auch die 3 childprozesse beendet.



ist "kill -15" mit einem "normalen" beenden des programs vergleichbar?
gibt es bessere methoden?



manchmal bekomme ich über "system('kill -15 ".$pids[-1]." &')" log meldungen, die mich vermuten lassen, dass es eventuell eine bessere methode zum beenden geben müsste.

Exiting due to channel error.
[GFX1-]: Receive IPC close with reason=AbnormalShutdown
[Child 25125, Chrome_ChildThread] WARNING: pipe error (3): Connection reset by peer: file /build/firefox-esr-RgOFaD/firefox-esr-68.11.0esr/ipc/chromium/src/chrome/common/ipc_channel_posix.cc, line 358
Exiting due to channel error.
Exiting due to channel error.



die zur zeit "suberste" logmeldung beim beenden ist scheinbar folgende:

Exiting due to channel error.
Exiting due to channel error.
Exiting due to channel error.


scheinbar gibt es für jeden child prozess immer die rückmeldung "Exiting due to channel error." .
und manchmal eben noch zusätzlich eventuelle besondere fehlermeldungen.



im internet finde ich viele hinweise zum starten des firefox, aber eigentlich nichts zum beenden über die cmdline.

hat vielleicht jemand verbesserungs vorschläge, oder ideen?
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

vbs

SIGTERM (15) ist durchaus die höfliche Bitte an einen Prozess, sich sauber zu beenden. Also mMn der richtige Weg. Was dann genau innerhalb des Prozesses passiert bzw. wie lange es dauert, bis er sich beendet (bzw. ob er es überhaupt tut), liegt dann in seiner Verantwortung.
Wenn der Prozess nicht spurt, dann nimmt man SIGKILL (9). Da hat der Prozess dann kaum/keine Möglichkeit sich gegen zu wehren (bzw. darauf zu reagieren). Kann aber zu halb geschrieben Datensätzen o.ä. führen.

rob

Hallo frank.

Beim Start haust Du die Zombies raus mit

system("pkill -f firefox-esr");

Wahrscheinlich, weil doch manchmal was weiterläuft.

Was passiert, wenn Du anstelle

fhem("defmod at_kill_ff at +00:01 {system('kill -15 ".$pids[-1]." &')}");

auch einfach pkill ausführst (analog Zombies)?

fhem("defmod at_kill_ff at +00:01 {system('pkill --oldest -f firefox-esr')}");

Wie vbs schreibt, ist SIGTERM schon die freundliche Variante. Anscheinend trotzdem für FF noch unfreundlicher als der Klick mit der Maus im GUI, denn wenn ich FF im GUI starte und einzelne Prozesse via cli mit kill -15 kicke, beschweren sich die noch offenen Tabs, dass FF abgestürzt sei.
Laut Quelle https://unix.stackexchange.com/questions/34101/exit-google-chrome-from-terminal/174451#174451 wäre "pkill --oldest processname" wohl auch eine gute Methode. Vielleicht einen Test wert.

Viele Grüße
rob

frank

Zitat von: vbs am 24 August 2020, 11:54:49
SIGTERM (15) ist durchaus die höfliche Bitte an einen Prozess, sich sauber zu beenden. Also mMn der richtige Weg. Was dann genau innerhalb des Prozesses passiert bzw. wie lange es dauert, bis er sich beendet (bzw. ob er es überhaupt tut), liegt dann in seiner Verantwortung.
Wenn der Prozess nicht spurt, dann nimmt man SIGKILL (9). Da hat der Prozess dann kaum/keine Möglichkeit sich gegen zu wehren (bzw. darauf zu reagieren). Kann aber zu halb geschrieben Datensätzen o.ä. führen.
danke für die bestätigung.
dann habe ich kill doch im prinzip verstanden.

ich bin halt verwundert, dass wenn ich den parent prozess "höfflichst" beende, dass dieser seine childs nicht ebenfalls höfflich beenden kann.
beim beobachten eines gestarteten firefox über top war mir aufgefallen, dass nach einiger zeit nur noch selten einer dieser 4 prozesse zu sehen war. wenn überhaupt war es meistens einer der 3 childs.
meine vermutung ist nun, dass wenn die zusätzlichen fehlermeldungen beim kill cmd auftauchen, zufällig gerade ein child aktiv am arbeiten war und dieser durch firefox selbst unhöfflich abgeschossen wird.

überlegt hatte ich noch, ob vielleicht ein starten über systemd besser wäre, so dass es beim beenden über "systemctl stop" noch "friedlicher" zugeht. aber wahrscheinlich macht systemd dann auch nichts anderes als den parent prozess höfflich zu beenden.
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

frank

Zitat von: rob am 24 August 2020, 16:19:38
Beim Start haust Du die Zombies raus mit

system("pkill -f firefox-esr");

Wahrscheinlich, weil doch manchmal was weiterläuft.

prima, sogar ein firefox insider.  :)
genau,der zombie ist der eigentliche hintergrund meines anliegens.

die hier gezeigte lösung hat jetzt allerdings schon ca. 50 start/stop prozeduren am stück überlebt.


meine bisherigen beobachtungen sehen folgendermassen aus:

der zombie bleibt nicht beim beenden von firefox übrig, sondern entsteht erst bei einem start von firefox.
manchmal beim beenden passiert irgend etwas, dass beim darauf folgenden start dann den zombie entstehen lässt.
bisher habe ich noch keine erkenntnis woran ich das nach dem beenden bereits erkennen kann.
"ps -C firefox-esr" zeigt dann zb nichts an.


nach einem "fehlstart" gibt es folgende ausgabe:
root@raspberrypi:/# ps -C firefox-esr
  PID TTY          TIME CMD
7966 ?        00:00:08 firefox-esr
7968 ?        00:00:00 firefox-esr <defunct>


dazu passt auch dann die 2-fache rückmeldung von system() beim start, die sonst nur einmal kommt:
*** You are running in headless mode.
*** You are running in headless mode.



das resultat ist, dass firefox nicht wie gewünscht arbeitet (es wird kein screenshot erstellt).
da ich headless bin, weiss ich nun nicht wirklich, was da genau los ist.
wahrscheinlich, wenn ich an mein firefox auf dem laptop denke, erscheint dann die firefox-absturz-meldung.

um die situation programmatisch auf zu lösen, reicht es aber nicht, die beiden prozesse mit
system("pkill -f firefox-esr");
abzuschiessen. bei jedem neuen start sind wieder 2 neue prozesse da, von denen einer ein zombie ist.

erst, wenn ich zusätzlich das versteckte file
/.mozilla/firefox/kkuoj0q7.default-esr/.parentlock
lösche, startet anschliessend firefox normal.


dass es zur zeit so gut läuft, liegt eventuell an der eingebauten verzögerung des "kill -15", wodurch das beenden von firefox nun zu einem "unkritischen zeitpunkt" stattfindet.

zum beenden habe ich bereits viele verschiedene kill-methoden probiert. allerdings hatte ich da noch nicht so viele log meldungen eingebaut. daher werde ich das noch mal probieren, wenn sich die augenblickliche konstellation verabschiedet.

hast du eventuell einen tip für ein profil, in dem alles "unnötige" abgeschaltet ist?
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

rob

Hallo frank.

Nein, ich muss dich leider enttäuschen: ich bin kein FF insider. Höchstens google-Schläue vorhanden ;D
Du hast eh schon alle Kill-Varianten durchgekaut, hätte ich wissen müssen - sorry.

Ich hatte via GUI einfach versucht nachzustellen und da hat es mit pkill gereicht. Unterschied zu meinem Test ist natürlich, dass Du a) headless arbeitest und b) mit FF-esr.
Beobachtungen:
- Start mit GUI und eine leere Seite ergibt 4 pid
- schließe ich via Maus, sind alle pid weg - ohne meckern
- kille ich den ersten mit kill -15, meckert er rum:
Exiting due to channel error.
Exiting due to channel error.
[GFX1-]: Receive IPC close with reason=AbnormalShutdown
Exiting due to channel error.
Beendet


zu a) headless
Laut https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Headless_mode sollte der Aufruf für headless so klappen und sich selbst beenden:
firefox -P deleteme --screenshot https://developer.mozilla.org/
(deleteme heißt mein Testprofil)

Beobachtung:
- es werden nur 3 pid erstellt
user@laptop:~$ pidof firefox
user@laptop:~$ pidof firefox
4168 4135 4090

- Meldung *** You are running in headless mode. kommt
- nach einigen Sekunden beendet sich alles selbst -- rückstandsfrei, keinerlei Fehlermeldungen

OK, also hab ich ein lahmes (öffentliches) Wifi benutzt (geht auch zu simulieren gänzlich ohne Internetzugriff). Nochmal headless wie oben ausgeführt.
Beobachtung:
- es werden nur 3 pid erstellt
- Meldung *** You are running in headless mode. kommt
- da Seite nicht erfolgreich geöffnet werden kann, breche ich mit STRG+C nach einigen Minuten ab:
user@laptop:~$ firefox -P deleteme --screenshot https://developer.mozilla.org/
*** You are running in headless mode.
^CExiting due to channel error.
Exiting due to channel error.


Vermutung: Ein Timeout könnte die Ursache sein, dass headless sich nicht selbst korrekt beendet. Jede andere Beendigung bringt dann Meldungen.
Wäre natürlich die Frage, ob das bei Dir überhaupt eine Rolle spielen kann.

zu b) firefox-esr
Ich habe alles geteset mit FF v79. Bis v57 gab es wohl einen Bug zum headless: https://bugzilla.mozilla.org/show_bug.cgi?id=1403934
Vielleicht aber bei Deinem FF nicht mehr relevant. Gegenchecken kann nicht schaden.
Einen Unterschied macht vielleicht noch die Kombination mit der Option -private.

Interessant wäre der Versuch ohne -private, mit einem aktuellen nicht-esr-FF und einem konkreten Profil (geht auch via cli "firefox -CreateProfile JoelUser" lt. https://developer.mozilla.org/en-US/docs/Mozilla/Command_Line_Options).
Wahrscheinlich kennst Du eh schon alles. Könnte aber einen Versuch wert sein.

Viele Grüße
rob

frank

hi rob,
danke für deine mühen.


headless [--screenshot]

die option kann ich leider nicht benutzen, da der screenshot zu schnell erstellt wird.
eine tabelle, um die es mir geht, ist dann noch nicht vorhanden, da sie erst nach diversen zusätzlichen requests erstellt werden kann.

interessant ist die beobachtung, dass dort nur 3 pids entstehen.
eventuell ist es dann, mit entsprechenden einträgen im profil, auch im "normalen" headless möglich, einen child weniger zu starten.
je weniger childs, desto weniger potentielle problemquellen.  ;)


firefox-esr

firefox-esr (68.11.0) ist die aktuelle, "offizielle" firefox version, die bei raspian buster über paketquellen angeboten wird.
mit dieser version möchte ich schon gern weiterarbeiten, um die nutzung dieses features für eventuelle weitere user möglichst einfach zu gestalten. das ist bis hier hin eigentlich schon zu aufwendig.

die option -private macht keinen unterschied.
von meiner logik aus, müsste firefox mit der option -private weniger zu tun haben.


zur zeit will der testlauf nicht mehr "aussteigen".
ich denke, als nächstes werde ich mal meine "exit-verzögerung" langsam verkürzen.
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html