2010-09-07 2 views
6

Je travaille sur une grande base de code (héritée) en PHP, et l'erreur Exception thrown without a stack frame in Unknown on line 0 a commencé à apparaître au bas de chaque page. Je comprends ce que l'erreur signifie: une exception est jetée à un endroit où elle ne peut pas être lancée. J'ai même réussi à le localiser quelque peu - cela se produit pendant le temps où les fonctions d'arrêt sont appelées.Comment puis-je retrouver une "Exception lancée sans cadre de pile dans Unknown sur la ligne 0" en PHP?

J'ai mis la connexion dans toutes les fonctions qui sont enregistrées avec register_shutdown_function, et il ne se passe dans aucun de ceux-ci. Malheureusement, je ne peux pas avoir plus d'informations que ça; Je sais ce que la dernière fonction d'arrêt à appeler avec succès est, mais je n'ai aucune idée de ce que le code est exécuté entre cela et le point où l'erreur se produit. Je ne sais même pas quelle partie de la machinerie PHP appelle cette dernière fonction d'arrêt. Ce peut être quelque chose avec le cadre de journalisation, ou le cadre de session, ou n'importe quoi d'une demi-douzaine de choses.

Est-ce que quelqu'un sait comment localiser l'erreur?

+0

Est-ce que faire usage de code hérité des fonctions set_error_handler() ou set_exception_handler()? – Fosco

+0

Je ne pense pas. La seule référence à cette fonction est dans une docstring, dans le framework Zend. –

+1

PHP 5.3.6 corrige ce problème disons "un peu". Voir http://www.php.net/archive/2011.php#id2011-03-17-1 pour plus de détails. – eisberg

Répondre

6

Cela peut se produire dans les destructeurs et les gestionnaires d'exceptions qui n'ont pas de cadre de pile. Mais puisque le message est très utile, votre seule option est d'essayer d'utiliser echo pour trouver le bogue (et peut-être ob_end_flush()). Il se peut qu'un destructeur lève une exception ou appelle une fonction qui lève une exception. Une fois que vous avez localisé la fonction buggy, ajoutez un essai ... attrape la partie de lancement de l'exception.

Notez que si votre infrastructure utilise sa propre gestion des erreurs, vous devez désactiver les avertissements et les avis dans la configuration PHP. Surtout si vous avez quelque chose comme ErrorException, car il transforme les avertissements en exceptions.

5

Ce message apparaît lorsqu'une exception lancée au sein de votre gestionnaire d'exceptions ou de votre gestionnaire d'erreurs (et peut-être aussi dans les fonctions d'arrêt)

Vous devriez chercher des méthodes thèses de voir si appens rien étrange ici.

0

Vous venez de trouver votre question après avoir rencontré la même erreur dans une application Web déployée sur un serveur Ubuntu 11.04, sous PHP 5.3.5. Je suis d'accord avec @Eisberg que ce problème semble être un problème avec la version PHP 5.3 exclusivement, car l'erreur n'a pas été présente avec d'autres versions précédentes de PHP sur d'autres environnements, où mon application a été déployée. Comme l'indique @jmz, j'ai également utilisé un gestionnaire d'erreurs qui transforme les erreurs en exceptions pour faciliter le débogage sur mes serveurs de transfert.

Pour comprendre ce qui a causé ce comportement mystérieux, je débogués l'application à l'aide XDEBUG & mon IDE (Eclipse) et découvert que l'un de mes bibliothèques a essayé d'accéder & modifier la variable $_SESSION globale, en l'absence de données de session-ont été définies . Envelopper mon code dans une instruction if-checking isset($_SESSION) a fait disparaître le problème. Pourquoi l'exception n'a pas complètement remonté jusqu'au navigateur, comme d'autres erreurs l'ont fait en essayant d'accéder à des variables non-set, est un mystère complet pour moi, d'autant plus que je suis en dessous des paramètres d'erreur définis, mais peut-être modifier le paramètre error_reporting() aurait fait une différence.

paramètres de traitement d'erreur, pour référence:

error_reporting(E_ALL | E_STRICT); 
ini_set("display_errors", 1); 
ini_set("html_errors", 1); 
+0

J'ai le même problème et l'a décomposé à une condition if ($ foo) qui a causé l'erreur. Cela arrive parce que $ foo n'a pas été défini. Utiliser if (! Vide ($ foo)) résoudra le problème. Pour certaines raisons, le même code ne génère pas d'exception dans une application héritée sur le même serveur. La nouvelle application - avec l'erreur - se produit en utilisant les composants Symfony. Je vais jeter un oeil à la question PHP5.3 (oui, encore à l'utiliser). Mais on dirait que Symfony place aussi un error_reporting spécial ici? – webDEVILopers

0

je reçois la même erreur msg aussi. Le quota de base de données MySQL a été défini par espace de récompense en tant que 50mb.L'utilisation de PHPmyAdmin pour optimiser les fichiers a montré une taille de 34 mb mais à cPanel la taille a été montrée comme 57mb. Chaque fois que je visitais mon site Web et que cette erreur se produisait, tout ce que je devais faire était de me connecter à un espace de récompense, de choisir la base de données, la gestion et de réinitialiser les autorisations de fichiers. Ensuite, l'erreur msg disparaît, et mon site web est de retour.

0

Je recevais ce problème dans PHPUnit. J'ai ajouté le code ci-dessous dans function tearDown et m'aide à obtenir l'erreur réelle. Vous devriez envelopper le destructeur dans un bloc try-catch, car la pile-frame ne sera perdue que lorsque l'exception sortira du destructeur. Peut-être que cela peut aider quelqu'un d'autre aussi. Source

function __destruct() 
{ 
    try 
    { 
    /* 
    your code 
    */ 
    } 
    catch(Exception $e) 
    { 
    echo $e->__toString(); 
    } 
} 
Questions connexes