Repository navigation
Apache Segmentation fault (11) disappears after print_r on a variable. can't understand... #10430
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
Activity
damianwadley commentedon Jan 24, 2023
Are you able to get and inspect that core dump? Do you have any third-party PHP extensions installed?
pfrappe commentedon Jan 24, 2023
ndossche commentedon Jan 24, 2023
Are you using the JIT, if yes, does the bug also occur with JIT disabled?
pfrappe commentedon Jan 24, 2023
pfrappe commentedon Jan 24, 2023
pfrappe commentedon Jan 24, 2023
ndossche commentedon Jan 24, 2023
It would be ideal if we could get a stacktrace. Are you able to attach gdb to the child process that crashes (well... before it actually crashes)?
pfrappe commentedon Jan 24, 2023
alecpl commentedon Jan 25, 2023
8.1.2 is quite old, I suggest an update.
pfrappe commentedon Jan 25, 2023
smokefire69 commentedon Jan 25, 2023
pfrappe commentedon Jan 25, 2023
pfrappe commentedon Jan 25, 2023
6 remaining items
ndossche commentedon Jan 28, 2023
I see you updated your OP to say you're using tracing JIT, I thought you weren't using the JIT. Are you able to try if the bug still occurs after disabling the JIT?
pfrappe commentedon Jan 28, 2023
ndossche commentedon Jan 28, 2023
The debug info isn't there with the way you did it.
What I meant with "in bash" is to execute the export command on the command line.
To be fully clear I'll give the full steps here:
On the command line execute the following commands one after another:
export DEBUGINFOD_URLS="https://debuginfod.ubuntu.com"ps -elf | grep apache2to find the process ID of apachesudo gdbso you get into gdb, everything from now on will be entered in gdbset debuginfod enabled onset follow-fork-mode childattach PROCESS_ID_OF_APACHE_HEREcontinuebtpfrappe commentedon Jan 28, 2023
ndossche commentedon Jan 28, 2023
Weird that it doesn't respond to
bt. Did you dobtafter the crash? Is it showing any error at all?pfrappe commentedon Jan 28, 2023
ndossche commentedon Jan 28, 2023
It's hard to say, I feel like you're attaching to the wrong process, or I'm missing something.
I'm guessing your application is closed source so I can't test it on my own machine?
pfrappe commentedon Jan 28, 2023
pfrappe commentedon Jan 28, 2023
pfrappe commentedon Jan 30, 2023
pfrappe commentedon Jan 30, 2023
ndossche commentedon Jan 30, 2023
Thank you for all the effort you put into this, I really appreciate that a lot. I'm not going to ask anything more from you, like as you said you already put alot of time into it.
I'll see what I can do with the info I have, there are certainly some clues even though there isn't a full reproducer.
Thanks
crrodriguez commentedon Feb 14, 2023
Can you reproduce it using the FPM sapi .. it should be pretty easy to setup in Ubuntu 22.04.1 LTS as it ships with an apache config file for that..
pfrappe commentedon Feb 15, 2023
crrodriguez commentedon Feb 15, 2023
Yes.
In recent ubuntu releases it should be a matter of installing php-fpm
a2enconf php8.2-fpm
a2dismod php8.2
systemctl restart php8.2-fpm
systemctl restart apache2
You probably want something to catch you core dumps. you need to install systemd-coredump package and reboot.. then with coredumpctl see all crashes and get backtraces.