J'ai constaté que l'une des raisons courantes de l'erreur est une exception est levée depuis un gestionnaire d'exceptions . Je suis à peu près sûr que cela ne se produit pas dans l'application que j'essaie de déboguer ... Mais j'ai placé toutes les lignes de traitement d'initialisation en haut du fichier index.php dans un try/catch. *
Cela peut apparemment aussi arriver parce que certaines choses ne peuvent pas être sérialiséespour être stockées dans une session . Tout au plus cette application stocke-t-elle des tableaux dans la session (pas mal), mais je suis convaincu qu'elle ne stocke rien d'extraordinaire.
Quelqu'un a commenté que cela leur était arrivé parce que leur clé primaire devait être CHAR (32) au lieu de INT (11) . Les PK dans cette application sont tous les INT.
D'autres suggestions sont que cela pourrait être un problème avec PHP 5.3.3corrigé dans 5.3.6 , disque complet et/ besoin de transtyper une valeur SimpleXML . Il se trouve que nous utilisons PHP 5.3.3, mais la mise à niveau serait un dernier recours dans ce cas. Cela n'a pas toujours été le cas.
UPDATE/NOTE: En fait, je ne peux pas reproduire l'erreur moi-même, je la vois seulement dans les journaux, voir le paragraphe ci-dessous pour savoir où je crois que l'erreur se produit ...
* D'après les journaux d'erreurs, il semble probable qu'au moins un endroit où cela se produit est index.php. Je déduis cela uniquement parce que cela est indiqué dans certaines entrées par une URL de référence. Le code try/catch ne concerne actuellement que la partie "initiale" du script, en dessous se trouve principalement la sortie HTML. Il y a du code PHP dans la sortie (ce qui est plutôt simple, cependant), il faudra peut-être le tester. Voici la partie catch qui ne produit aucune sortie dans les journaux:
} catch (Exception $e) {
error_log(get_class($e)." thrown. Message: ".$e->getMessage(). " in " . $e->getFile() . " on line ".$e->getLine());
error_log('Exception trace stack: ' . print_r($e->getTrace(),1));
}
J'apprécierais vraiment tous les conseils à ce sujet!
EDIT: PHP est exécuté en tant que module Apache (API du serveur: gestionnaire Apache 2.0). Je ne pense pas qu'il y ait des accélérateurs PHP en cours d'utilisation, mais il se pourrait simplement que je ne sache pas comment le savoir. Aucun de ceux énumérés sur Wikipedia sont dans phpinfo ().
Autant que je sache, le MPM est préfork. C'est la première fois que j'ai examiné le MPM:
# ./httpd -l
Compiled in modules:
core.c
prefork.c
http_core.c
mod_so.c
En bref, vous faites une exception quelque part, vous ne savez pas où et jusqu’à présent, vous ne pouviez pas reproduire l’erreur: cela ne se produit que pour certaines personnes, mais pas pour vous. Vous savez que cela se produit pour d'autres personnes, car vous le voyez dans les journaux d'erreurs.
Puisque vous avez déjà éliminé les raisons courantes, vous devrez reproduire l'erreur. Si vous savez quel paramètre causera l'erreur, il devrait être facile de localiser l'erreur.
Commençons simplement: pour obtenir tous les paramètres, vous pouvez écrire au tout début du fichier php concerné, par exemple:
file_put_contents("/path/to/some/custom_error_log", date()."\n".print_r(get_defined_vars(), true), FILE_APPEND | LOCK_EX);
N'oubliez pas que le fichier custom_error_log doit être accessible en écriture pour votre application php. Ensuite, lorsque l'erreur se produit dans le journal des erreurs, recherchez les lignes correspondantes dans votre fichier custom_error_log. Espérons qu’il n’y ait pas beaucoup de requêtes à la seconde afin que vous puissiez toujours identifier la requête. Certains paramètres supplémentaires dans le journal des erreurs, tels que l'adresse IP source, peuvent vous aider à identifier la demande (si votre journal des erreurs l'indique) . À partir de ces données, reconstruisez une demande avec les mêmes paramètres POST/GET.
L’option suivante, très simple également, mais qui nécessite un accès root sur votre ordinateur cible, consiste à installer tcpflow. Ensuite, créez un dossier, cd dans ce dossier et exécutez simplement (en tant que root) tcpflow "port 80"
. L'option (port 80) est une expression de filtre pcap. Pour voir tout ce que vous pouvez faire avec cela, voir man pcap-filter
. Il y a beaucoup de choses que ces expressions de filtre peuvent faire.
Maintenant, tcpflow va enregistrer toutes les connexions TCP sur le port 80, reconstruire l’échange complet de données en combinant les paquets appartenant à une connexion et vider ces données dans un fichier, créant deux nouveaux fichiers par connexion, un pour les données entrantes et un pour les données sortantes. Recherchez maintenant les fichiers pour une connexion ayant provoqué une erreur, toujours en vous basant sur l'horodatage de votre journal des erreurs et sur le dernier horodatage modifié des fichiers. Ensuite, vous obtenez les en-têtes complets de la requête http. Vous pouvez maintenant reconstruire complètement la requête HTTP, y compris en définissant le même encodage d'acceptation, le même agent d'utilisateur, etc. Vous pouvez même diriger la requête directement dans netcat, en réexécutant la requête exacte. Attention cependant, certains arguments, comme un identifiant de session, pourraient vous gêner. Si php découvre qu'une session a expiré, vous pouvez simplement obtenir une redirection vers un identifiant ou quelque chose d'inattendu. Vous devrez peut-être échanger des choses comme l'identifiant de session.
Si cela ne vous aide pas et que vous ne pouvez pas reproduire l'erreur sur votre ordinateur, vous pouvez essayer de simuler tout ce qui est difficile à simuler. Par exemple l'adresse IP source. Cela peut rendre certaines cascades nécessaires, mais c'est possible: Vous pouvez vous connecter à votre serveur en utilisant ssh avec l'option "-w", créant ainsi une interface de tunnel. Attribuez ensuite l'adresse IP incriminée à votre propre ordinateur et définissez les règles de routage (route add Host) pour utiliser le tunnel pour l'adresse IP spécifique. Si vous pouvez câbler directement les deux ordinateurs, vous pouvez même le faire sans tunnel.
Ne pas oublier de se moquer de la session qui devrait être la plus facile. Vous pouvez lire toutes les variables de session à l'aide de la méthode print_r (get_defined_vars ()). Ensuite, vous devez créer une session avec exactement les mêmes variables.
Une autre option serait de demander à l'utilisateur ce qu'il faisait. Peut-être que vous pouvez suivre les mêmes étapes que lui et peut reproduire.Si rien de tout cela ne vous aide.
Entourez le problème une fois que vous pouvez reproduire
Dites-nous ce que vous avez trouvé. Je suis curieux ;-).
Tell us what you found. I am curious ;-).
J'ai eu une telle erreur aussi. J'ai découvert que j'avais retourné un objet SQL dans ma classe de session (utilisée par le gestionnaire de session) au lieu de ne rien renvoyer ou du moins pas l'objet SQL. Commencez par examiner vos méthodes _write et _read, si vous retournez également des éléments incorrects.
Avis: ... Inconnu sur la ligne 0 - Comment trouver la bonne ligne, ce n'est pas "la ligne 0"
Au lieu d'encapsuler le code dans un bloc try/catch, que se passe-t-il lorsque vous enregistrez un gestionnaire d'exceptions? Il est clair que votre bloc try/catch n'intercepte pas l'exception, ce qui entraîne les erreurs consignées dans Apache. En enregistrant un gestionnaire, vous pouvez être sûr que toute exception non capturée est gérée.
De même, si vous utilisez des espaces de nom dans votre application, veillez à écrire\Exception dans votre bloc catch (ou à inclure la classe Exception via une instruction use).
Pour nous, cette erreur était due à la sérialisation par inadvertance d'objets SimpleXML.
Si vous utilisez des objets SimpleXML avec 5.3.3, assurez-vous de convertir les valeurs de nœud selon vos besoins (chaîne, par exemple) si vous sérialisez les valeurs dans la session.
Avant :
$token = $response->Token->Value;
/* token saved in session, results in line 0 error */
Après :
$token = (string) $response->Token->Value;
/* token saved in session, no error */
Je me rends compte que cette question a déjà été posée, mais j'ajouterai ceci car cela peut aider quelqu'un:
J'ai réussi à produire (involontairement) des erreurs sans un cadre de pile à partir d'une fonction qui utilisait son propre gestionnaire d'erreurs pour garder le contrôle de l'exécution tout en appelant une fonction potentiellement "dangereuse", comme ceci:
// Assume the function my_error_handler() has been defined to convert any
// PHP Errors, Warnings, or Notices into Exceptions.
function foo() {
// maintain control if danger() crashes outright:
set_error_handler('my_error_handler');
try {
// Do some stuff.
$r = danger();
} catch (Exception $e) {
$r = 'Bad Stuff, Man!';
}
restore error_handler();
return $r;
}
L '"échec introuvable" se produirait à la fin de l'exécution du programme si la logique de "Do some stuff" est renvoyée directement par foo (), en ignorant l'appel de restore_error_handler (). Voici ce que j'ai retenu de l'expérience:
C'était un problème difficile à isoler - j'ai essentiellement réduit le problème à la fonction ci-dessus, puis je l'ai observé jusqu'à ce que mes yeux saignent.
Alors, comment aurais-je pu retrouver cette information, sachant ce que je sais maintenant? Comme je ne connais aucun moyen d'inspecter directement le "gestionnaire" d'erreurs PHP, je pense qu'il serait peut-être judicieux d'utiliser un objet Singleton pour encapsuler toutes les opérations set/restore pour PHP. gestionnaires d'erreur. Au moins, il serait alors possible d'inspecter l'état du Singleton avant de quitter le programme normalement, et si des gestionnaires d'erreur "pendants" sont détectés pour générer un message d'erreur/avertissement sensible avant que PHP ne s'effraie.
C'est peut-être un peu tard mais un problème que j'ai découvert lors du déplacement d'un site d'un serveur local vers un serveur distant. J'utilisais Concrete5 cms avait développé mon site localement (Windows 8 dans xampp), puis téléchargé sur un serveur distant exécutant Cent 0S.
Windows mysql par défaut est insensible à la casse et a créé une base de données en minuscules. Une fois que cela a été téléchargé sur le serveur distant, j'ai reçu le message "Exception levée sans trame de pile dans Unknown sur la ligne 0?"
J'ai ensuite corrigé le cas des tables de base de données et mon site a recommencé à fonctionner.
J'ai eu complètement la même erreur. Un cas très particulier: si vous connectez un hook de fonction non nommé (fermeture) à un point de hook d'instances d'objet. Après cela, vous essayez de sérialiser cet objet.
Ce problème s'est produit pour moi lorsque j'ai modifié l'espace de noms de plusieurs bundles Symfony. La suppression des fichiers du répertoire de cache de symfony a résolu le problème.
Vous avez probablement une table corrompue/incohérente dans la base de données. Essayez de vider la base de données. Si vous obtenez une erreur, c'est le moment. Réparez cette table et le problème devrait disparaître.
C'est pour cette raison que l'installation propre fonctionne. L'installation propre est juste que propre.
mysqlcheck devrait fonctionner mais s'il ne s'affiche pas et que le problème persiste, comme indiqué ci-dessus.
un moyen simple de générer cette erreur est d'utiliser un ancien serveur avec register_globals = On
. alors vous n'avez besoin que de deux lignes de code:
<?php
$_SESSION["my_var"] = "string";
$my_var = new MyClass(); //could be any class, i guess
?>
dès que vous rechargez cette page une fois, vous obtenez l'erreur Exception thrown without a stack frame in Unknown on line 0
-. semble être un conflit entre l’instance de la classe et la variable (session).
du moins c’est comme ça que j’ai eu cette erreur ennuyeuse qui est si difficile à déboguer.
J'ai eu la même erreur, il est apparu mettre à niveau le serveur de centos 5 à centos 6 et déclasser PHP de 5.4 à 5.3. Le problème réel était PHP apc, non configuré correctement. Vérifiez votre APC. J'utilisais Symfony2, vous pouvez donc trouver de l'aide sur Symfony Impossible d'allouer de la mémoire pour le pool