Skip to content

Apache Segmentation fault (11) disappears after print_r on a variable. can't understand... #10430

Open
@pfrappe

Description

@pfrappe

Description

Sorry this problem appears within a big application and I didn't find a short php code reproducing the problem.
So I try to put the maximum explanations here.

In some cases I get this message in error log :
[core:notice] [pid 910] AH00051: child pid 23361 exit signal Segmentation fault (11), possible coredump in /etc/apache2

I found this message always appears twice because, when I get it, the index.php is executed a second time.
To find that, I put an errog_log('deb') at the very beginning of the index.php and an error_log('fin') at the last instruction.
In the log, I got :

[Tue Jan 24 10:50:37.515447 2023] [php:notice] [pid 23488] [client 127.0.0.1:49088] deb, referer: http://localhost/wer/index.php
[Tue Jan 24 10:50:40.193277 2023] [php:notice] [pid 23488] [client 127.0.0.1:49088] fin, referer: http://localhost/wer/index.php
[Tue Jan 24 10:50:40.856392 2023] [php:notice] [pid 23835] [client 127.0.0.1:49102] deb, referer: http://localhost/wer/index.php

[Tue Jan 24 10:50:41.479629 2023] [core:notice] [pid 910] AH00051: child pid 23488 exit signal Segmentation fault (11), possible coredump in /etc/apache2
[Tue Jan 24 10:50:43.102831 2023] [php:notice] [pid 23835] [client 127.0.0.1:49102] fin, referer: http://localhost/wer/index.php
[Tue Jan 24 10:50:43.482049 2023] [core:notice] [pid 910] AH00051: child pid 23835 exit signal Segmentation fault (11), possible coredump in /etc/apache2

So, index.php seems to be executed twice.
However, if I error_log the expected HTML result in the log, it is totally correct. (and I get it twice...)
But nothing is sent to the navigator.

Bypass

Step by step, I found a bypass : the problem disappears when I put a print_r of some object at the right place.
For example :

This caused the problem :

$ret = SG_Operation::execFonctionSansParametre($this, $o, $nom, $p2, $p1, $contexte);
//print_r($ret, true);

And this works correctly :

$ret = SG_Operation::execFonctionSansParametre($this, $o, $nom, $p2, $p1, $contexte);
print_r($ret, true);

It works too if I add :

$ret = unserialize(serialize($ret);

If the dumps of the object before and after the problem are identical.

I tried some other features which don't work :

$obj = SG_Operation::execFonctionSansParametre($this, $o, $nom, $p2, $p1, $contexte);
$ret = $obj;

or

$obj = SG_Operation::execFonctionSansParametre($this, $o, $nom, $p2, $p1, $contexte);
$ret = clone $obj;

Research notes

I found that the bypass does work if I just add the '''print_r''' as the first line of the __construct function of one of my classes :

/** SynerGaia contient la classe SG_Nombre de traitement des nombres */
defined("SYNERGAIA_PATH_TO_ROOT") or die('403.14 - Directory listing denied.');

/** Pour ajouter les méthodes et propriétés spécifiques de l'application créées par le compilateur */
if (file_exists(SYNERGAIA_PATH_TO_VAR . 'SG_Nombre_trait.php')) {
    include_once SYNERGAIA_PATH_TO_VAR . 'SG_Nombre_trait.php';
} else {
    /** trait vide par défaut */
    trait SG_Nombre_trait{};
}
/**
 * SG_Nombre : Classe SynerGaia de gestion d'un nombre
 * @since 0.0
 * @version 2.9
 */
class SG_Nombre extends SG_Objet {
    // complément de classe créée par compilation
    use SG_Nombre_trait;

    /** string Type SynerGaia '@Nombre' */
    const TYPESG = '@Nombre';
    
    /** string Type SynerGaia  */
    public $typeSG = self::TYPESG;

    /** integer|float Valeur interne du nombre (null par défaut) */
    public $valeur;
    
    /** string Unité de mesure (pas encore géré) */
    public $unite = '';

    /**
     * Construction de l'objet
     * @since 1.0.7
     * @version 2.4 si rien : 0
     * @version 2.9.1 getTexte pour unité
     * @param any $pQuelqueChose valeur à partir de laquelle le SG_Nombre est créé
     * @param any $pUnite code unité ou ou objet @Unite de la quantité
     */
    function __construct($pQuelqueChose = null, $pUnite = null)
    {
print_r($this, true); // bypass bug #10430
        $tmpTypeSG = SG_Objet::getTypeSG($pQuelqueChose);
        switch ($tmpTypeSG) {
            case 'integer' :
                $this -> valeur = (double)$pQuelqueChose;
                break;
            case 'double' :
                $this -> valeur = $pQuelqueChose;
                break;
            case 'string' :
                if ($pQuelqueChose !== '') {
                    $floatString = $pQuelqueChose;
                    $floatString = str_replace(" ", "", $floatString);
                    $floatString = str_replace(",", ".", $floatString);
                    $this -> valeur = floatval($floatString);
                } else {
                    $this -> valeur = null;
                }
                break;
            case '@Formule' :
                $tmpNombre = new SG_Nombre($pQuelqueChose -> getResult());
                $this -> valeur = $tmpNombre -> valeur;
                break;
            case '@Nombre' :
                $this -> valeur = $pQuelqueChose -> valeur;
                $this -> unite = $pQuelqueChose -> unite;
                break;
            case 'NULL' :
                $this -> valeur = 0; //null;
                break;
            default :
                // Si objet SynerGaia
                if (substr($tmpTypeSG, 0, 1) === '@') {
                    $this -> valeur = $pQuelqueChose -> toFloat();
                }
        }
        if($pUnite) {
            $this -> unite = SG_Texte::getTexte($pUnite);
        }
    }

I also remark when the bypass works, the new class has been called by an instruction like :

$class = "MyClass";
$obj = new $class();

But, I can't make a short PHP program reproducing the problem.

Environment

PHP 8.1.2-1ubuntu2.10 (cli) (built: Jan 16 2023 15:19:49) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.2, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.2-1ubuntu2.10, Copyright (c), by Zend Technologies

on Ubuntu 22.04.1 LTS

I hope I'm clear enough clear...
Pierre Frappé (France)

PHP Version

first PHP 8.1.2, and now 8.2.1 (no change)
JIT tracing

Operating System

Ubuntu 22.04.1 LTS

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions