Je compile actuellement une pile de données achetée en C. J'utilise leur propre outil pour le compiler, en utilisant en arrière-plan gcc. Je peux passer des drapeaux et des paramètres à gcc comme bon me semble. Je veux savoir, à partir de quel fichier est le principal() utilisé. C'est-à-dire, dans le projet, quel fichier est le point de départ. Est-il possible de dire à gcc de générer une liste de fichiers, ou similaire, étant donné que je ne sais pas de quel fichier est le fichier main()? Je vous remercie.Rechercher le point de départ, int main()
Répondre
Vous compilez le projet avec des symboles de débogage, démarrez gdb
avec l'exécutable, et écrire list main
, suivi de « break
» ou directement break main
.
'list main' ne montre même pas le nom de fichier que OP veut réellement. –
Merci pour votre réponse. En effet, cela ne montre pas le fichier exact, mais montre les premières lignes de la main utilisée, avec cela je peux faire une recherche de texte normale sur le code source entier et trouver l'endroit d'insertion. Merci beaucoup pour votre réponse à nouveau. –
Si vous voulez voir le numéro de ligne et le fichier, vous écrivez 'break main', ou vous faites 'break' après' list main', etc. Vous n'avez pas besoin de grep. – alinsoar
D'où main()
est appelé est mise en œuvre dépendant - en utilisant GCC, il sera très probablement un fichier objet stub dans/usr/lib appelé crt0.o
ou crt1.o
à partir de laquelle il est appelé. (Ce fichier contient le symbole dépendant du système d'exploitation qui est automatiquement appelé par le noyau lorsque votre application est chargée en mémoire Sous Linux et Mac OS X, cela s'appelle start
).
Vous pouvez désassembler l'exécutable final pour trouver le point de départ. Bien que vous n'ayez pas fourni d'informations supplémentaires pour vous aider davantage. J'utilise un exemple de code pour illustrer le processus.
#include <stdio.h>
int main() {
printf("hello world\n");
return 0;
}
maintenant l'objet main.o
a ce qui suit ce
[[email protected] sf]# gcc -c main.c
[[email protected] sf]# nm main.o
0000000000000000 T main
U puts
Vous pouvez voir principale n'est pas initialisé. Parce que cela va changer dans la phase de liaison. Maintenant, après la liaison:
$gcc main.o
$nm a.out
U [email protected]@GLIBC_2.2.5
0000000000600874 A _edata
0000000000600888 A _end
00000000004005b8 T _fini
0000000000400390 T _init
00000000004003e0 T _start
000000000040040c t call_gmon_start
0000000000600878 b completed.6347
0000000000600870 W data_start
0000000000600880 b dtor_idx.6349
00000000004004a0 t frame_dummy
00000000004004c4 T main
Vous voyez que la principale a une adresse maintenant. Mais ce n'est toujours pas définitif. Parce que ce principal sera appelé par C runtime dynamiquement. vous pouvez voir qui fera la part de U [email protected]@GLIBC_2.2.5
:
[[email protected] sf]# ldd a.out
linux-vdso.so.1 => (0x00007fff61de1000) /* the linux system call interface */
libc.so.6 => /lib64/libc.so.6 (0x0000003c96000000) /* libc runime , this will invoke your main*/
/lib64/ld-linux-x86-64.so.2 (0x0000003c95c00000) /* dynamic loader */
Maintenant, vous pouvez le vérifier en consultant le démontage:
00000000004003e0 <_start>:
..........
4003fd: 48 c7 c7 c4 04 40 00 mov rdi,0x4004c4 /* address of start of main */
400404: e8 bf ff ff ff call 4003c8 <[email protected]> /* this will set up the environment for main, like pushing argc and argv to stack */
...........
Si vous n'avez pas la source avec vous, vous pouvez effectuer une recherche dans l'exécutable pour les références à libc_start_main
ou main
ou start
pour voir comment votre fichier exécutable est initialisé et démarre le main
.
Maintenant, tout cela est fait lorsque la liaison est faite avec le script de l'éditeur de liens par défaut. Beaucoup de gros projets utiliseront leur propre script d'éditeur de liens. Si votre projet a un script d'éditeur de liens personnalisé, la recherche du point de départ sera différente en fonction du script d'éditeur de liens utilisé. Il existe des projets qui n'utilisent pas glibc's
runtime. Si votre binaire est stripped
à partir de symboles, alors vous devez compter sur votre compétence d'assembleur pour trouver où il commence.
J'ai supposé que vous n'aviez pas la source, c'est-à-dire que la pile est distribuée avec quelques bibliothèques et certaines définitions d'en-tête seulement (une pratique courante des vendeurs de logiciels commerciaux). Mais si vous avez une source avec vous, c'est juste trop trivial. juste grep
votre chemin à travers elle. Certaines réponses ont déjà souligné cela.
Vous pouvez utiliser objdump -t
pour lister les symboles des fichiers objets. Donc, vous êtes sur Linux en supposant, et en supposant que les fichiers objets sont toujours là quelque part, vous pouvez le faire:
find -name '*.o' -print0 \
| xargs -0 objdump -t \
| awk '/\.o:/{f=$1} /\.text\.main/{print f, $6}'
Cela affichera une liste des fichiers objets et les références à main
qu'ils contiennent. Habituellement, il devrait y avoir une simple carte des fichiers objets aux fichiers source. S'il existe plusieurs fichiers objets contenant ce symbole, cela dépend de l'un de ceux qui sont réellement liés au binaire que vous regardez, car il ne peut y avoir plus d'un main
par exécutable binaire (sauf peut-être pour un noir vraiment exotique la magie). Après que l'application est liée et que les symboles de débogage sont supprimés, il n'y a généralement aucune indication de quel fichier source une fonction spécifique est venue. L'exception à ceci sont les fichiers qui incluent les noms de fonctions en tant que littéraux de chaîne, par ex. en utilisant la macro __FILE__
. Avant de supprimer les symboles de débogage, vous pouvez utiliser le débogueur pour obtenir ces informations. Si les symboles de débogage sont inclus, c'est.
- 1. Pourquoi le C++ n'a pas de double départ main() ou similaire et seulement int/void main()?
- 2. Différence entre void main et int main
- 3. Point de départ Javascript
- 4. UIScrollView point de départ
- 5. Jcarousel comment définir le point de départ
- 6. Le point de départ UIPanGestureRecognizer est désactivé
- 7. point de départ pour le Web Chat?
- 8. Définir le point de départ pour CGAffineTransform
- 9. Autonumber - spécifiez le point de départ
- 10. Modifier le point de départ d'une animation
- 11. Obtenir le point de départ d'un UIBezierPath
- 12. Comment changer le point de départ setTimeout?
- 13. Pourquoi int main() {} compile?
- 14. Double pointeur dans int main
- 15. Racine sans point de départ
- 16. C++ - int main (int argc, char * argv [])
- 17. OpenLayers polygone à main levée sans ligne élastique jusqu'au point de départ
- 18. int main (ac int, char ** av)
- 19. StackOverFlow sur le point de départ de l'application
- 20. Contraindre le point de départ d'une correspondance regex
- 21. Codecademy Battleship Commencer le point de départ Python
- 22. Point de départ de Compass Blueprint Liquid
- 23. Pointeur + int vs point - int
- 24. migration de rails. modifier le point de départ de auto_increment
- 25. Android - Set Spinner Point de départ
- 26. problème EditText point de départ Android
- 27. Point d'entrée C++ -> main()
- 28. Géré DirectX comme point de départ
- 29. Comment trouver les coordonnées du point de départ à partir du point de départ et du point défilant
- 30. appel int main() à partir de python
Il ne doit y avoir qu'un fichier contenant la fonction 'main', sinon vous obtiendrez une erreur de l'éditeur de liens. Où votre outil met cela que nous ne pouvons pas savoir si vous ne nous dites pas de quel outil il s'agit. –
Btw c'est une très mauvaise idée d'essayer de déranger avec des détails non documentés comme celui-ci. –
pourquoi pas: grep -rni "main". ? – JohnTortugo