recherche
MaisonTutoriel systèmeLinuxExtension de la pile du débogueur Linux !

Extension de la pile du débogueur Linux !

Jan 06, 2024 pm 10:25 PM
linuxlinux教程红帽linux系统linux命令certification Linuxchapeau rouge Linuxvidéo Linux

Présentation Parfois, l'information la plus importante que vous devez connaître est la manière dont l'état actuel de votre programme en est arrivé là. Il existe une commande backtrace, qui vous donne la chaîne d'appels de fonction actuelle de votre programme. Cet article vous montrera comment implémenter le déroulement de la pile sur x86_64 pour générer un tel traçage.
Index des séries

Ces liens seront mis en ligne au fur et à mesure que d'autres articles seront publiés.

  1. Préparer l'environnement
  2. Point d'arrêt
  3. Registres et mémoire
  4. ELF et NAIN
  5. Code source et signaux
  6. Exécution étape par étape au niveau du code source
  7. Points d'arrêt au niveau de la source
  8. Extension de la pile
  9. Lire les variables
  10. Prochaines étapes

Utilisez le programme suivant comme exemple :

void a() {
//stopped here
}
void b() {
a();
}
void c() {
a();
}
int main() {
b();
c();
}

Si le débogueur s'arrête à la ligne //stopped here', il existe deux manières d'y accéder : main->b->a ou main->c->a`. Si nous définissons un point d'arrêt avec LLDB, continuons l'exécution et demandons un traçage, alors nous obtenons ce qui suit :

* frame #0: 0x00000000004004da a.out`a() + 4 at bt.cpp:3
frame #1: 0x00000000004004e6 a.out`b() + 9 at bt.cpp:6
frame #2: 0x00000000004004fe a.out`main + 9 at bt.cpp:14
frame #3: 0x00007ffff7a2e830 libc.so.6`__libc_start_main + 240 at libc-start.c:291
frame #4: 0x0000000000400409 a.out`_start + 41

Cela signifie que nous sommes actuellement dans la fonction a, a saute de la fonction b, b saute de la fonction principale, etc. Les deux dernières images indiquent comment le compilateur amorce la fonction principale.

La question est maintenant de savoir comment l'implémenter sur x86_64. L'approche la plus robuste serait d'analyser la partie .eh_frame du fichier ELF et de comprendre comment dérouler la pile à partir de là, mais ce serait pénible. Vous pourriez le faire en utilisant libunwind ou similaire, mais c'est ennuyeux. Au lieu de cela, nous supposons que le compilateur a configuré la pile d'une manière ou d'une autre et nous la parcourrons manuellement. Pour ce faire, nous devons d’abord comprendre la disposition de la pile.

High
| ... |
+---------+
+24| Arg 1 |
+---------+
+16| Arg 2 |
+---------+
+ 8| Return |
+---------+
EBP+--> |Saved EBP|
+---------+
- 8| Var 1 |
+---------+
ESP+--> | Var 2 |
+---------+
| ... |
Low

Comme vous pouvez le voir, le pointeur du dernier frame de pile est stocké au début du frame de pile actuel, créant une liste chaînée de pointeurs. La pile est déroulée en fonction de cette liste chaînée. Nous pouvons trouver la fonction de la trame suivante dans la liste en recherchant l'adresse de retour dans le message DWARF. Certains compilateurs ignoreront le suivi de l'adresse de base de trame d'EBP, car celle-ci peut être exprimée sous la forme d'un décalage par rapport à ESP et libérer un registre supplémentaire. Même avec les optimisations activées, passer -fno-omit-frame-pointer à GCC ou Clang le forcera à suivre les conventions dont nous dépendons.

Nous ferons tout le travail dans la fonction print_backtrace :

void debugger::print_backtrace() {

La première chose à décider est le format à utiliser pour imprimer les informations du cadre. J'ai utilisé un lambda pour déployer cette méthode :

auto output_frame = [frame_number = 0] (auto&& func) mutable {
std::cout 
<p>La première image imprimée est l’image en cours d’exécution. Nous pouvons obtenir des informations sur cette trame en recherchant le compteur de programme actuel dans DWARF : </p>
<pre class="brush:php;toolbar:false">auto current_func = get_function_from_pc(get_pc());
output_frame(current_func);

Ensuite, nous devons obtenir le pointeur de trame et l'adresse de retour de la fonction actuelle. Le pointeur de trame est stocké dans le registre rbp et l'adresse de retour est empilée sur 8 octets à partir du pointeur de trame.

auto frame_pointer = get_register_value(m_pid, reg::rbp);
auto return_address = read_memory(frame_pointer+8);

Nous avons maintenant toutes les informations dont nous avons besoin pour étendre la pile. Je continue de me dérouler jusqu'à ce que le débogueur atteigne main, mais vous pouvez également choisir de vous arrêter lorsque le pointeur de trame est 0x0, qui sont les fonctions que vous appelez avant d'appeler la fonction principale. Nous récupérerons le pointeur de trame et l’adresse de retour de chaque trame et imprimerons les informations.

while (dwarf::at_name(current_func) != "main") {
current_func = get_function_from_pc(return_address);
output_frame(current_func);
frame_pointer = read_memory(frame_pointer);
return_address = read_memory(frame_pointer+8);
}
}

C'est tout ! Voici l'intégralité de la fonction :

void debugger::print_backtrace() {
auto output_frame = [frame_number = 0] (auto&& func) mutable {
std::cout 
<strong>Ajouter une commande</strong>
<p>Bien sûr, nous devons exposer cette commande à l'utilisateur. </p>
<pre class="brush:php;toolbar:false">else if(is_prefix(command, "backtrace")) {
print_backtrace();
}
Test

Une façon de tester cette fonctionnalité consiste à écrire un programme de test avec un tas de petites fonctions qui s'appellent les unes les autres. Définissez quelques points d'arrêt, parcourez le code et assurez-vous que votre traçage est exact.

Nous avons parcouru un long chemin depuis un programme qui ne pouvait que générer et s'attacher à d'autres programmes. L'avant-dernier article de cette série complétera l'implémentation du débogueur en prenant en charge la lecture et l'écriture de variables. En attendant, vous pouvez trouver le code de cet article ici.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer
À quoi sert Linux?À quoi sert Linux?Apr 12, 2025 am 12:20 AM

Linux convient aux serveurs, aux environnements de développement et aux systèmes intégrés. 1. En tant que système d'exploitation de serveurs, Linux est stable et efficace, et est souvent utilisé pour déployer des applications à haute monnaie. 2. En tant qu'environnement de développement, Linux fournit des outils de ligne de commande efficaces et des systèmes de gestion des packages pour améliorer l'efficacité du développement. 3. Dans les systèmes intégrés, Linux est léger et personnalisable, adapté aux environnements avec des ressources limitées.

Outils et cadres essentiels pour maîtriser le piratage éthique sur LinuxOutils et cadres essentiels pour maîtriser le piratage éthique sur LinuxApr 11, 2025 am 09:11 AM

Introduction: sécuriser la frontière numérique avec un piratage éthique basé sur Linux Dans notre monde de plus en plus interconnecté, la cybersécurité est primordiale. Les tests de piratage et de pénétration éthiques sont essentiels pour l'identification de proactive et l'atténuation des vulnérabilités

Comment apprendre les bases de Linux?Comment apprendre les bases de Linux?Apr 10, 2025 am 09:32 AM

Les méthodes d'apprentissage Linux de base à partir de zéro incluent: 1. Comprendre le système de fichiers et l'interface de ligne de commande, 2. Master Basic Commandes telles que LS, CD, MKDIR, 3. Apprenez les opérations de fichiers, telles que la création et l'édition de fichiers, 4. Explorer une utilisation avancée telle que les pipelines et les commandes GREP, 5. Master Debugging Skills and Performance Optimimisation, 6. Amélioration continue des compétences par la pratique et l'exploration.

Quelle est la plus utilisée de Linux?Quelle est la plus utilisée de Linux?Apr 09, 2025 am 12:02 AM

Linux est largement utilisé dans les serveurs, les systèmes intégrés et les environnements de bureau. 1) Dans le domaine du serveur, Linux est devenu un choix idéal pour héberger des sites Web, des bases de données et des applications en raison de sa stabilité et de sa sécurité. 2) Dans les systèmes intégrés, Linux est populaire pour sa personnalisation et son efficacité élevées. 3) Dans l'environnement de bureau, Linux fournit une variété d'environnements de bureau pour répondre aux besoins des différents utilisateurs.

Quels sont les inconvénients de Linux?Quels sont les inconvénients de Linux?Apr 08, 2025 am 12:01 AM

Les inconvénients de Linux incluent l'expérience utilisateur, la compatibilité des logiciels, la prise en charge matérielle et la courbe d'apprentissage. 1. L'expérience utilisateur n'est pas aussi conviviale que Windows ou MacOS, et elle s'appuie sur l'interface de ligne de commande. 2. La compatibilité logicielle n'est pas aussi bonne que les autres systèmes et manque de versions natives de nombreux logiciels commerciaux. 3. La prise en charge matérielle n'est pas aussi complète que Windows, et les pilotes peuvent être compilés manuellement. 4. La courbe d'apprentissage est raide et la maîtrise des opérations de ligne de commande nécessite du temps et de la patience.

Linux est-il difficile à apprendre?Linux est-il difficile à apprendre?Apr 07, 2025 am 12:01 AM

LinuxisnothardTolearn, maisthedifficultyDependyourbackgroundAndgoals.forthosewithosexperience, en particulier la Command-linefamiliarité, LinuxisanEasyTransition.BeginnersmayfaceasteelearningCurvebutCanManageWithProperrresources.Linux'sopen-Sourcenature, Bas, bass

Quels sont les 5 composants de base de Linux?Quels sont les 5 composants de base de Linux?Apr 06, 2025 am 12:05 AM

Les cinq composants de base de Linux sont: 1. Le noyau, gérant les ressources matérielles; 2. La bibliothèque système, fournissant des fonctions et des services; 3. Shell, l'interface pour les utilisateurs pour interagir avec le système; 4. Le système de fichiers, stockant et organisant des données; 5. Applications, en utilisant des ressources système pour implémenter les fonctions.

Ubuntu Home-Automation: Construire un espace de vie intelligent avec des outils open sourceUbuntu Home-Automation: Construire un espace de vie intelligent avec des outils open sourceApr 05, 2025 am 09:19 AM

Ouverture d'un nouveau chapitre dans Smart Home: Open Source Home-Automation System basé sur Ubuntu Smart Home Technology a révolutionné la façon dont nous interagissons avec nos espaces de vie, apportant la commodité, la sécurité et l'efficacité énergétique à notre vie quotidienne. De la télécommande des lumières et des appareils électroménagers à la surveillance des caméras de sécurité et à la climatisation automatisée, la technologie de maison intelligente devient de plus en plus populaire. Cependant, de nombreux systèmes de maisons intelligentes commerciales ont des limites: coûts élevés, problèmes de confidentialité et compatibilité limitée. Heureusement, les solutions logicielles open source combinent la puissance d'Ubuntu pour fournir une alternative - permettant aux utilisateurs de créer un écosystème de maison intelligent personnalisable, rentable et sécurisé. Ce guide explorera comment configurer un système domestique à l'aide d'outils Ubuntu et open source.

See all articles

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semainesBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semainesBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semainesBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
3 Il y a quelques semainesBy尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Télécharger la version Mac de l'éditeur Atom

Télécharger la version Mac de l'éditeur Atom

L'éditeur open source le plus populaire

MantisBT

MantisBT

Mantis est un outil Web de suivi des défauts facile à déployer, conçu pour faciliter le suivi des défauts des produits. Cela nécessite PHP, MySQL et un serveur Web. Découvrez nos services de démonstration et d'hébergement.

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Puissant environnement de développement intégré PHP

Version crackée d'EditPlus en chinois

Version crackée d'EditPlus en chinois

Petite taille, coloration syntaxique, ne prend pas en charge la fonction d'invite de code

Listes Sec

Listes Sec

SecLists est le compagnon ultime du testeur de sécurité. Il s'agit d'une collection de différents types de listes fréquemment utilisées lors des évaluations de sécurité, le tout en un seul endroit. SecLists contribue à rendre les tests de sécurité plus efficaces et productifs en fournissant facilement toutes les listes dont un testeur de sécurité pourrait avoir besoin. Les types de listes incluent les noms d'utilisateur, les mots de passe, les URL, les charges utiles floues, les modèles de données sensibles, les shells Web, etc. Le testeur peut simplement extraire ce référentiel sur une nouvelle machine de test et il aura accès à tous les types de listes dont il a besoin.