Est-il possible qu'un programme C/C++ peut faire planter l'avant main()?
Est-il de toute façon un programme peut faire planter l'avant main()?
- Je sais que j'ai vu cela avant, mais c'était il y a si longtemps que je ne suis pas sûr si je me souviens de la cause.
- Thi dit qu'il est intéressé par les réponses pour le C++. J'ai utilisé la question pour représenter cette. Merci.
- Je peux dire avec confiance que je peux causer rien de crash à tout moment. 🙂
- Allen: j'ai ri très fort! Renversé mon thé sur mon portable! Et donc, dis-nous tout!
- Allen: pardonner la faute d'orthographe de votre nom; encore le nettoyage de thé!
- désolé à ce sujet! J'espère que votre ordinateur portable est ok.
- Si vous exécutez windows, il peut tomber en panne à tout moment, sans raison explicable.
- Oui, bien sûr, car il n'est jamais Windows qui plante de façon inexpliquée. Le terme de "kernel panic" n'existe pas dans le monde de Linux à tous.</sarcasme>
Vous devez vous connecter pour publier un commentaire.
Avec gcc, vous pouvez attribuer une fonction avec la constructeur attribut (ce qui provoque de la fonction à exécuter avant
main
). Dans la fonction suivante,premain
sera appelée avantmain
:Donc, si il ya un bug dans
premain
vous plantera avantmain
.Oui, au moins sous Windows. Si le programme utilise les Dll qu'ils peuvent être chargés avant
main()
commence. LeDllMain
fonctions de ces Dll sera exécutée avant lamain()
. S'ils rencontrent une erreur qu'ils pourraient occasionner l'ensemble du processus d'interrompre ou de crash.Si vous avez un programme en C++ il est possible d'initialiser les variables et les objets à travers les fonctions et les constructeurs avant-main est entré. Un bug dans l'un de ces pourrait provoquer un programme crash.
certainement en c++; objets statiques avec contructors seront appelés avant les principaux - ils peuvent mourir
pas sûr au sujet de c
voici un exemple de
cela va se planter avant les principaux
La réponse est simple: Oui.
Plus précisément, on peut différencier les deux causes de cette. Je vais les appeler dépend de l'implémentation et mise en œuvre indépendante de.
Le seul cas qui ne dépend pas de votre environnement à tous les est que des objets statiques en C++, ce qui a été mentionné ici. Le code suivant meurt avant
main()
:Plus intéressantes sont les dépend de la plateforme, les causes. Certains ont été mentionnés ici. Celui qui a été mentionné ici une couple de fois a été l'utilisation de la dynamique des librairies (Dll dans windows, SOs dans Linux, etc.) - si votre OS loader de charge avant de
main()
, ils pourraient causer à votre application ne meurent avantmain()
.Une manière plus générale, la version de cette cause est de parler de toutes les choses votre binaire du point d'entrée du ne avant d'appeler votre point d'entrée(
main()
). Habituellement, lorsque vous construisez votre binaire il y a de très graves bloc de code qui est appelé lors de votre système d'exploitation chargeur commence à exécuter le binaire, et quand c'est fait, il appelle votremain()
. Une chose commune ce code n'est en cours d'initialisation du C/C++ de la bibliothèque standard. Ce code peut échouer pour diverses raisons (manque de tout type de système de ressource qu'il tente d'allouer pour l'un).Un moyen intéressant sur un binaire à exécuter du code avant
main()
sur windows à l'aide de TLS rappels (google vous en dira plus à ce sujet). Cette technique est généralement trouvé dans les logiciels malveillants comme une base anti-débogage truc (ce truc de fou ollydbg à l'époque, ne sais pas si cela ne fonctionne toujours).Le point est que votre question est en fait équivalent à "est-il possible que le chargement d'un binaire serait la cause de l'utilisateur d'exécuter du code avant le code dans
main()
?", et la réponse est enfer, ouais!Tout programme qui s'appuie sur les objets partagés (Dll) doit être chargé avant principal peut ne pas principal.
Sous Linux code dans l'éditeur de liens dynamique de la bibliothèque (ld-*.donc) est organisé pour fournir une bibliothèque de dépendances bien avant les principaux. Si les bibliothèques ne sont pas en mesure d'être situés, ont des autorisations qui ne vous permettra pas d'accéder à eux, ne sont pas des fichiers normaux, ou n'ont pas un symbole que l'éditeur de liens dynamique qui lié à votre programme de pense que l'on devrait avoir quand elle liée à votre programme, alors cela peut provoquer une défaillance.
En outre, chaque bibliothèque obtient d'exécuter du code lorsqu'il est lié. C'est surtout parce que la bibliothèque peut avoir besoin de lien plus de bibliothèques ou peut-être besoin d'exécuter certains constructeurs (même dans un programme C, les bibliothèques pouvais avoir un peu de C++ ou quelque chose d'autre qui utilise constroctors).
En outre, la norme C, des programmes ont déjà créé la stdio Fichiers stdin, stdout, et stderr. Sur beaucoup de systèmes, ceux-ci peuvent également être fermé. Cela implique qu'elles sont aussi libres()ed, ce qui implique qu'ils (et leurs zones tampons) ont été malloc()ed, qui peut échouer. Il suggère également qu'ils peuvent avoir fait quelques autres trucs pour les descripteurs de fichier que ceux des structures de FICHIERS représentent, qui pourraient échouer.
D'autres choses qui pourraient éventuellement se produire si les OS étaient à gâcher la configuration du respect de variables et/ou les arguments de ligne de commande qui ont été passés au programme. Code avant principal est susceptible d'avoir quelque chose avec ces données, avant l'appel principal.
Beaucoup de choses se passent avant les principaux. L'un d'eux peut concievably échouer dans un fatal façon.
Je ne suis pas sûr, mais si vous avez une variable globale comme ceci :
Le " SomeClass constructeur pourrait planter le programme avant de le principal cours d'exécution.
Il y a beaucoup de possibilités.
Tout d'abord, nous avons besoin de comprendre ce qui se passe réellement sur l'avant-main est exécuté:
Maintenant, tout cela peut provoquer une panne de plusieurs façons:
catch
,terminate
est appelé et la fin du programmeC'est vraiment ennuyeux de cours et, éventuellement, difficile à déboguer, et c'est pourquoi vous devriez vous abstenir d'exécuter du code avant
main
autant que possible, et de préférer l'initialisation tardive si vous le pouvez, ou l'initialisation explicite dansmain
.Bien sûr, quand c'est une DLL défaut et vous ne pouvez pas le modifier, vous êtes dans un monde de douleur.
Sorte de:
http://blog.ksplice.com/2010/03/libc-free-world/
Si vous compilez sans bibliothèque standard, comme ceci:
gcc-nostdlib -o bonjour bonjour.c
ne pas savoir comment faire pour exécuter main() et va se planter.
Globale et statique des objets dans un programme C++ auront leurs constructeurs appelé avant la première instruction dans main() est exécutée, donc un bug dans l'un des constructeurs peut provoquer une panne.
Cela ne peut pas arriver dans les programmes en C, si.
Cela dépend de ce que tu veux dire par "avant de main", mais si vous voulez dire "avant tout de votre code principal est réellement exécuté", alors je pense à un exemple: si vous déclarez un grand tableau comme une variable locale dans la principale, et la taille de ce tableau dépasse la pile de l'espace, alors vous pouvez ainsi obtenir un
stack overflow
sur l'entrée principale, avant la première ligne de code s'exécute.char big[-1U / 2U];
au fichier-champ d'application provoque un crash de trop ici.Un peu artificiel exemple serait:
Il est peu probable que vous auriez jamais faire quelque chose comme cela, mais si vous faites beaucoup de macro-magie, il est tout à fait possible.
t.c:3: error: initializer element is not constant
Sûr, si il y a un bug dans le système d'exploitation ou l'exécution de code. C++ est particulièrement notoire pour ce comportement, mais il peut encore se passer dans C.
Vous n'avez pas dit quelle plate-forme/libc. Dans le monde embarqué il y a souvent beaucoup de choses qui s'exécutent avant
main()
- en grande partie à faire avec plate-forme de l'installation - qui peut aller mal. (Ou même si vous utilisez un funky linker script régulièrement OS, tous les paris sont éteints, mais je suppose que c'est assez rare.)certains plate-forme de l'abstraction des bibliothèques de substitution (personnellement, je ne sais de bibliothèques C++ comme Qt ou ACE, qui le faire, mais peut-être que certaines bibliothèques C faire quelque chose comme ça aussi) "principal", de sorte qu'ils spécifient une plate-forme spécifique principal comme un
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow );
et de configuration d'une bibliothèque de trucs, convertir de la ligne de commande args à la normaleint argc, char* argv[]
, puis d'appeler la normaleint main(int argc, char* argv[])
Bien sûr, ces bibliothèques peut conduire à un plantage quand ils n'ont pas été mis en oeuvre correctement (peut-être à cause de la malformation de ligne de commande args).
Et pour les personnes qui ne savent pas à ce sujet, cela peut ressembler à un crash avant
main
J'avais été confrontés à la même question. L'origine et la cause a été trouvé.. Trop de variables locales(tableaux énormes) ont été initialisé dans le processus principal leader local des variables de taille de plus de 1,5 mo.
Il en résulte un grand saut que le pointeur de pile est assez grande et le système d'exploitation détecte ce saut comme invalide et bloque le programme tel qu'il pourrait être malveillant.
De débogage.
1. Feu GDB
2. Ajouter un point d'arrêt au principal
3. démonter principale
4. Vérifiez pour sous $0xGGGGGGG,%esp
Si cette GGGGGG valeur est trop élevé, alors vous verrez le même problème que moi.
Afin de vérifier la taille totale de toutes les variables locales dans la main.