/usr/lib/php5/sessionclean - SEGFAULT

Debian macht sich hervorragend als Web- und Mailserver. Schau auch in den " Tipps und Tricks"-Bereich.
Antworten
SupMap
Beiträge: 8
Registriert: 08.10.2018 09:51:47

/usr/lib/php5/sessionclean - SEGFAULT

Beitrag von SupMap » 08.10.2018 10:10:06

Guten Tag !

Ich habe seid einigen Tagen mit einem Problem mit dem Skript "sessionclean" auf meinem Debian Server (Plesk) zu kämpfen. Alles hat ohne Vorwarnung mit einem apt-get upgrade angefangen, bei dem eigentlich nichts wichtiges erneuert worden ist so weit ich das noch weiß. Ab diesem Zeitpunkt erhalte ich alle 30 Minuten eine E-Mail mit dem Inhalt "Segmentation fault" und dem Betreff "Cron <root@srv1> [ -x /usr/lib/php5/sessionclean ] && /usr/lib/php5/sessionclean". Das Problem, weder in der E-Mail noch in log files kann ich eine Bemerkung zu dem eigentlichen Fehler finden. Auch wenn ich das Skript als root aus der Konsole starte "/usr/lib/php5/sessionclean" bricht dieses mit "Segmentation fault" ab. Ich habe einmal den Inhalt des skriptes angehängt, eigentlich macht dieses ja nichts weiter als abgelaufene session files zu bereinigen - ich bin da bei der Fehlersuche wirklich am Ende :)

Code: Alles auswählen

SAPIS="apache2:apache2 apache2filter:apache2 cgi:php5 fpm:php5-fpm cli:php5"

# Iterate through all web SAPIs
(
proc_names=""
for sapi in ${SAPIS}; do
    conf_dir=${sapi%%:*}
    proc_name=${sapi##*:}
    if [ -e /etc/php5/${conf_dir}/php.ini ]; then
        # Get all session variables once so we don't need to start PHP to get each config option
        session_config=$(PHP_INI_SCAN_DIR=/etc/php5/${conf_dir}/conf.d/ php5 -c /etc/php5/${conf_dir}/php.ini -d "error_reporting='~$
        save_handler=$(echo "$session_config" | sed -ne 's/^session\.save_handler=\(.*\)$/\1/p')
        save_path=$(echo "$session_config" | sed -ne 's/^session\.save_path=\(.*;\)\?\(.*\)$/\2/p')
        gc_maxlifetime=$(($(echo "$session_config" | sed -ne 's/^session\.gc_maxlifetime=\(.*\)$/\1/p')/60))

        if [ "$save_handler" = "files" -a -d "$save_path" ]; then
            proc_names="$proc_names $proc_name";
            printf "%s:%s\n" "$save_path" "$gc_maxlifetime"
        fi
    fi
done
# first find all open session files and touch them (hope it's not massive amount of files)
for pid in $(pidof $proc_names); do
    find "/proc/$pid/fd" -ignore_readdir_race -lname "$save_path/sess_\*" -exec touch -c {} \; 2>/dev/null
done
) | sort -rn -t: -k2,2 | sort -u -t: -k 1,1 | while IFS=: read -r save_path gc_maxlifetime; do
    # find all files older then maxlifetime and delete them
    find -O3 "$save_path/" -ignore_readdir_race -depth -mindepth 1 -name 'sess_*' -type f -cmin "+$gc_maxlifetime" -delete
done

exit 0
Ich wäre jedem mit einer Idee hierzu sehr dankbar !

MfG

Daniil

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: /usr/lib/php5/sessionclean - SEGFAULT

Beitrag von rendegast » 08.10.2018 23:10:41

Kannst du mal eine geringfügig modifizierte Version des Skriptes benutzten,
angereichert mit Meldungen derart
...
echo AA
...
echo BB
...
echo CC
...
um herauszufinden, wo der segfault auftritt.
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")

SupMap
Beiträge: 8
Registriert: 08.10.2018 09:51:47

Re: /usr/lib/php5/sessionclean - SEGFAULT

Beitrag von SupMap » 09.10.2018 11:51:21

Super Idee rendegast !

Mit dem nachfolgenden Skript erhalte ich nur die "5" nach Ausführung.

Code: Alles auswählen

SAPIS="apache2:apache2 apache2filter:apache2 cgi:php5 fpm:php5-fpm cli:php5"

# Iterate through all web SAPIs
(
proc_names=""
for sapi in ${SAPIS}; do
    conf_dir=${sapi%%:*}
    proc_name=${sapi##*:}
    if [ -e /etc/php5/${conf_dir}/php.ini ]; then
        # Get all session variables once so we don't need to start PHP to get each config option
        session_config=$(PHP_INI_SCAN_DIR=/etc/php5/${conf_dir}/conf.d/ php5 -c /etc/php5/${conf_dir}/php.ini -d "error_reporting='~E_ALL'" -r 'foreach(ini_get_all("session") as $k => $v) echo "$k=".$v["local_value"]."\n";')
        save_handler=$(echo "$session_config" | sed -ne 's/^session\.save_handler=\(.*\)$/\1/p')
        save_path=$(echo "$session_config" | sed -ne 's/^session\.save_path=\(.*;\)\?\(.*\)$/\2/p')
        gc_maxlifetime=$(($(echo "$session_config" | sed -ne 's/^session\.gc_maxlifetime=\(.*\)$/\1/p')/60))
        if [ "$save_handler" = "files" -a -d "$save_path" ]; then
            proc_names="$proc_names $proc_name";
            printf "%s:%s\n" "$save_path" "$gc_maxlifetime"
        fi
echo 1
    fi
echo 2
done
echo 3
# first find all open session files and touch them (hope it's not massive amount of files)
for pid in $(pidof $proc_names); do
    find "/proc/$pid/fd" -ignore_readdir_race -lname "$save_path/sess_\*" -exec touch -c {} \; 2>/dev/null
done
echo 4
) | sort -rn -t: -k2,2 | sort -u -t: -k 1,1 | while IFS=: read -r save_path gc_maxlifetime; do
    # find all files older then maxlifetime and delete them
    find -O3 "$save_path/" -ignore_readdir_race -depth -mindepth 1 -name 'sess_*' -type f -cmin "+$gc_maxlifetime" -delete
done
echo 5

exit 0
Sieht so aus als wenn das Problem in der ersten for Schleife auftritt, korrekt ? Leider bringt mich das auch nicht viel weiter im Moment...

MfG

Daniil

rendegast
Beiträge: 15041
Registriert: 27.02.2006 16:50:33
Lizenz eigener Beiträge: MIT Lizenz

Re: /usr/lib/php5/sessionclean - SEGFAULT

Beitrag von rendegast » 09.10.2018 22:36:11

Deine 'echo' beeinträchtigen eventuell die Funktion des Skriptes.
Ich würde vielleicht sowas vorschlagen

Code: Alles auswählen

SAPIS="apache2:apache2 apache2filter:apache2 cgi:php5 fpm:php5-fpm cli:php5"

echo 0 > /tmp/test.txt

# Iterate through all web SAPIs
(
proc_names=""
for sapi in ${SAPIS}; do
    conf_dir=${sapi%%:*}
    proc_name=${sapi##*:}
    if [ -e /etc/php5/${conf_dir}/php.ini ]; then
        # Get all session variables once so we don't need to start PHP to get each config option
        session_config=$(PHP_INI_SCAN_DIR=/etc/php5/${conf_dir}/conf.d/ php5 -c /etc/php5/${conf_dir}/php.ini -d "error_reporting='~E_ALL'" -r 'foreach(ini_get_all("session") as $k => $v) echo "$k=".$v["local_value"]."\n";')
        save_handler=$(echo "$session_config" | sed -ne 's/^session\.save_handler=\(.*\)$/\1/p')
        save_path=$(echo "$session_config" | sed -ne 's/^session\.save_path=\(.*;\)\?\(.*\)$/\2/p')
        gc_maxlifetime=$(($(echo "$session_config" | sed -ne 's/^session\.gc_maxlifetime=\(.*\)$/\1/p')/60))
        if [ "$save_handler" = "files" -a -d "$save_path" ]; then
            proc_names="$proc_names $proc_name";
            printf "%s:%s\n" "$save_path" "$gc_maxlifetime"
        fi
echo 1 >> /tmp/test.txt
    fi
echo 2 >> /tmp/test.txt
done
echo 3 >> /tmp/test.txt
# first find all open session files and touch them (hope it's not massive amount of files)
for pid in $(pidof $proc_names); do
    find "/proc/$pid/fd" -ignore_readdir_race -lname "$save_path/sess_\*" -exec touch -c {} \; 2>/dev/null
done
echo 4 >> /tmp/test.txt
) | sort -rn -t: -k2,2 | sort -u -t: -k 1,1 | while IFS=: read -r save_path gc_maxlifetime; do
    # find all files older then maxlifetime and delete them
    find -O3 "$save_path/" -ignore_readdir_race -depth -mindepth 1 -name 'sess_*' -type f -cmin "+$gc_maxlifetime" -delete
done
echo 5 >> /tmp/test.txt

exit 0
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")

SupMap
Beiträge: 8
Registriert: 08.10.2018 09:51:47

Re: /usr/lib/php5/sessionclean - SEGFAULT

Beitrag von SupMap » 10.10.2018 14:28:18

Vielen Dank für den Hinweis, mit der Methode erhalte ich trotzdem nur "0" und "5" in der Ausgabedatei.
Eine Idee ?


MfG

Daniil

Benutzeravatar
MSfree
Beiträge: 10686
Registriert: 25.09.2007 19:59:30

Re: /usr/lib/php5/sessionclean - SEGFAULT

Beitrag von MSfree » 10.10.2018 14:50:34

Setzt mal in der Konsole/Terminal das "ulimit" für Corefiles hoch, das steht per Default auf Null:

Code: Alles auswählen

ulimit -c 4194304
Dadurch dürfen bis zu 4GB große Corefiles beim Programmabsturz erzeugt werden. Keine Angst, in der Regel sind Coredumps sehr viel kleiner als 4GB.

Dann startest du dein Programm nochmal und wartest auf den Absturz. Dann wirst du in deinem Arbeitsverzeichnis einen Coredump finden mit dem Namen core.PID (PID = Process ID des abgestürzten Programmes).

mit file NameDesCoredumps kannst du nachsehen, welches Programm den Absturz erzeugt hat.

Im Prinzip könntest du den Coredump auch mit dem Debugger gdb analysieren, das macht jedoch in der Regel keine Spaß, weil den Executables die Symboltabellen fehlen und man keine Funktions- und Variablennamen sieht.

SupMap
Beiträge: 8
Registriert: 08.10.2018 09:51:47

Re: /usr/lib/php5/sessionclean - SEGFAULT

Beitrag von SupMap » 11.10.2018 10:25:54

Hallo MSFree, leider erhalte ich als Ausgabe: ELF 64-bit LSB core file x86-64, version 1 (SYSV), too many program headers (211)
Was mir nichts über das Programm sagt welches den Absturz verursacht hat. Eine Idee ?

MfG

Daniil

Benutzeravatar
MSfree
Beiträge: 10686
Registriert: 25.09.2007 19:59:30

Re: /usr/lib/php5/sessionclean - SEGFAULT

Beitrag von MSfree » 11.10.2018 10:39:51

Code: Alles auswählen

file -Pelf_phnum=10000 core
Setzt die Anzahl der zu durchsuchende ELF-Header im core-File auf 10000. Das sollte reichen, um (in deinem Fall) die 211 Header auszulesen.

SupMap
Beiträge: 8
Registriert: 08.10.2018 09:51:47

Re: /usr/lib/php5/sessionclean - SEGFAULT

Beitrag von SupMap » 11.10.2018 13:10:13

Dann erhalte ich:

Code: Alles auswählen

ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, from 'php5 -c /etc/php5/apache2/php.ini -d error_reporting='~E_ALL' -r foreach(ini_ge'

Benutzeravatar
MSfree
Beiträge: 10686
Registriert: 25.09.2007 19:59:30

Re: /usr/lib/php5/sessionclean - SEGFAULT

Beitrag von MSfree » 11.10.2018 13:31:51

Das deutet darauf hin, daß die Zeile in deinem Skript, die mit

Code: Alles auswählen

session_config=$(...
anfängt, bei der Ausführung abstürzt.

Vermutlich wird die Befehlszeile einfach zu lang, zumindest der hintere "foreach"-Teil könnte zu eine überlangen Kommandozeile führen.

Ändere die Zeile mal zu:

Code: Alles auswählen

        echo session_config=$(PHP_INI_SCAN_DIR=/etc/php5/${conf_dir}/conf.d/ php5 -c /etc/php5/${conf_dir}/php.ini -d "error_reporting='~E_ALL'" -r 'foreach(ini_get_all("session") as $k => $v) echo "$k=".$v["local_value"]."\n";') >> /tmp/test.txt 
Um, dann solltest du in /tmp/test.txt die Kommandozeilen sehen können.

SupMap
Beiträge: 8
Registriert: 08.10.2018 09:51:47

Re: /usr/lib/php5/sessionclean - SEGFAULT

Beitrag von SupMap » 11.10.2018 13:48:15

Vielen Dank für eure Hilfe !

Sobald ich im Skript sessionclean die Zeile wie empfohlen abändere, erhalte ich bei Ausführung folgenden Fehler:

Code: Alles auswählen

/usr/lib/php5/sessionclean: 39: /usr/lib/php5/sessionclean: arithmetic expression: expecting primary: "/60"
Trotzdem wird folgendes in die datei tmp.txt ausgegeben die durch echo angelegt wird:

Code: Alles auswählen

session_config=session.auto_start=0 session.cache_expire=180 session.cache_limiter=nocache session.cookie_domain= session.cookie_httponly= session.cookie_lifetime=0 session.cookie_path=/ session.cookie_secure= session.entropy_file=/dev/urandom session.entropy_length=32 session.gc_divisor=1000 session.gc_maxlifetime=1440 session.gc_probability=0 session.hash_bits_per_character=5 session.hash_function=0 session.name=PHPSESSID session.referer_check= session.save_handler=files session.save_path=/var/lib/php5/sessions session.serialize_handler=php session.upload_progress.cleanup=1 session.upload_progress.enabled=1 session.upload_progress.freq=1% session.upload_progress.min_freq=1 session.upload_progress.name=PHP_SESSION_UPLOAD_PROGRESS session.upload_progress.prefix=upload_progress_ session.use_cookies=1 session.use_only_cookies=1 session.use_strict_mode=0 session.use_trans_sid=0
Alles in einer Zeile.

Benutzeravatar
MSfree
Beiträge: 10686
Registriert: 25.09.2007 19:59:30

Re: /usr/lib/php5/sessionclean - SEGFAULT

Beitrag von MSfree » 11.10.2018 14:26:29

SupMap hat geschrieben: ↑ zum Beitrag ↑
11.10.2018 13:48:15
Sobald ich im Skript sessionclean die Zeile wie empfohlen abändere, erhalte ich bei Ausführung folgenden Fehler:
Naja, das sessionclean-Skript wurde durch das "echo" ja im Grunde ausser Betrieb gesetzt, so daß sich Folgefehler schon fast zwangsläufig ergeben müssen.
Trotzdem wird folgendes in die datei tmp.txt ausgegeben die durch echo angelegt wird:

Code: Alles auswählen

ssession_config=session.auto_start=0
   session.cache_expire=180
   session.cache_limiter=nocache
   session.cookie_domain=
   session.cookie_httponly=
   session.cookie_lifetime=0
   session.cookie_path=/
   session.cookie_secure=
   session.entropy_file=/dev/urandom
   session.entropy_length=32
   session.gc_divisor=1000
   session.gc_maxlifetime=1440
   session.gc_probability=0
   session.hash_bits_per_character=5
   session.hash_function=0
   session.name=PHPSESSID
   session.referer_check=
   session.save_handler=files
   session.save_path=/var/lib/php5/sessions
   session.serialize_handler=php
   session.upload_progress.cleanup=1
   session.upload_progress.enabled=1
   session.upload_progress.freq=1%
   session.upload_progress.min_freq=1
   session.upload_progress.name=PHP_SESSION_UPLOAD_PROGRESS
   session.upload_progress.prefix=upload_progress_
   session.use_cookies=1
   session.use_only_cookies=1
   session.use_strict_mode=0
   session.use_trans_sid=0
Ich habe die Ausgabe mal umgebrochen, das liest sich dann besser :wink:

Ehrlicherweise muß ich sagen, daß ich von diesem PHP-Zeug nicht allzu viel Ahnung habe und aus der Ausgabe nicht viel herauslesen kann. Mir fällt jedoch auf, daß einige Zeile hinter dem "="-Zeichen keinen Wert enthalten. Möglicherweise muß da noch was richtig initialisiert werden, z.B. in eine php.ini?

Ich weiß hier aber leider nicht weiter.

SupMap
Beiträge: 8
Registriert: 08.10.2018 09:51:47

Re: /usr/lib/php5/sessionclean - SEGFAULT

Beitrag von SupMap » 11.10.2018 14:55:52

Das ist mir auch aufgefallen, leider fehlt mir hier auch das Wissen um eindeutig zu sagen dass die fehlenden Werte hinter den "=" Zeichen ein Fehler sind und wie dies zu lösen ist. Trotzdem vielen Dank MSfree für deine Hilfe, wir sind hiermit schon mal ein Stück weiter ! Vielleicht findet sich einer der eine weitere Idee hat wo ich das Problem nun suchen sollte und wie ?


MfG

Daniil

SupMap
Beiträge: 8
Registriert: 08.10.2018 09:51:47

Re: /usr/lib/php5/sessionclean - SEGFAULT

Beitrag von SupMap » 16.10.2018 10:15:38

Keiner eine Idee ?

MfG

Daniil

Antworten