php / php/php-src

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

Open
#10,430 34 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug Status: Needs Triage
Dominant language
C
Stars
40.4k
Forks
8.1k
Avg merge
2d 13h
Merged PRs (30d)
96

Description

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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reducing the report to a short PHP reproducer, since the issue provides none. Reproduce the segfault around SG_Operation::execFonctionSansParametre, dynamic construction, SG_Nombre::__construct, and the print_r or serialize workaround under PHP 8.1/8.2 with JIT tracing. Done means a reproducible failure that can be isolated to PHP rather than the application or Apache.

Written by the indexing model from the issue text.

Assessment

Tech stack
apache, php
Domain
backend
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.