9
votes

Pourquoi je ne peux pas imprimer des variables d'environnement dans gdb?

(gdb) n
8       printf("%s\n", environ[i++]);
(gdb) p environ[i]
Cannot access memory at address 0x0
(gdb) n
LOGNAME=root
7     while(environ[i]) {

3 commentaires

Étrange. Je reproduit. Si j'ajoute un pTR = environ avant la boucle tandis que vous pouvez utiliser PTR mais Environ Séjour d'un pointeur Null.


Apparemment gdb commence le processus du programme en cours de débogage sans environnement.


@pmg, il a un environnement. J'utilise Set ENV dans GDB assez souvent pour en être sûr.


5 Réponses :


0
votes

Les variables d'environnement sont accessibles dans C / C ++ à l'aide de la fonction getenv () code> définie dans stdlib.h code>. Cependant, à l'aide du paramètre ENVP code> de la fonction principale, vous pouvez utiliser l'exemple suivant pour itérer les variables d'environnement.

#include <stdio.h>

int main(int argc, char *argv[], char *envp[])
{
  char **next = envp;

  while (*next) 
  {
    printf("%s\n", *next);
    next++;
  }
  return 0;


}


3 commentaires

Le GDB peut cependant appeler des fonctions. Par exemple: appel (char *) getenv ("chemin") (il semble supposer que le retour est un entier sans ce typast.) Bien sûr, cette fonction doit être disponible, mais si la Le programme se soucie des variables d'environnement, il doit sûrement être!


Ce n'est pas le problème, la variable _Environ / Environ n'est pas directement prise en charge sur toutes les plateformes.


Mon point était qu'il y a souvent un moyen de voir des variables d'environnement sans se soucier du tout si Environ ou _Environ est là ou non.



-1
votes

Il n'y a rien de mal avec votre code. Je l'ai essayé sur ma machine et j'ai imprimé l'environnement comme prévu. Vous ne devriez pas avoir besoin d'utiliser getenv ().

exécutez-vous cette application à partir du terminal? Sinon, vous devriez l'être. D'autres moyens d'exécution d'une application peuvent appeler votre binaire sans le transmettre l'environnement.

du terminal Quelle est votre sortie lorsque vous exécutez "env"? Il devrait émettre la même liste que votre programme. Il fait sur ma machine.


0 commentaires

0
votes

Comme Grundprinzip dit, utilisez getenv (SZ) et n'oubliez pas de choquer NULL-Vérifiez la valeur de retour em>

Alternativement, P>

#include <unistd.h>
#include <stdio.h>

int main(int argc, char *argv[], char*[] environ) { 
  int i = 0;
  while(environ[i]) {
    printf("%s\n", environ[i++]);
  }
  return 0;
}


0 commentaires

0
votes

Probablement le processus sous le débogage est lancé avec

/* #include <unistd.h> */           /* no more environ */
#include <stdio.h>

/* extern char **environ; */        /* no more environ */
int main(int argc, char *argv[]) { 
  int i = 0;
  char **ptr = argv + argc + 1;     /* points to environment, in Un*x */
  while(ptr[i]) {
    printf("%s\n", ptr[i++]);
  }
  return 0;
}


0 commentaires

10
votes

GDB résout le mauvais symbole environnement . Je ne sais pas pourquoi cependant. voir ci-dessous pourquoi.

Mais vous pouvez le tester. Modifiez le programme à: xxx

exécutons maintenant cela dans le débogueur. xxx

SO. Le programme réel a, lors de sa liaison, résolue environ à l'adresse 0x8049760. Lorsque GDB souhaite accéder au symbole environ , il est résolu à 0x46328Da0, qui est différent.

éditer. Il semble que votre symbole environ est réellement lié à l'environnement environ @@ glibc_2.0 symbole. Dans GDB, écrivez ceci: xxx

et appuyez sur la touche de tabulation (deux fois), ce sera autocompressé les symboles. Ce qui donne: xxx

environ @@ glibc_2.0 est celui qui est réellement lié au extern Char ** window

Impression Ceci cède la même adresse que le programme voit, 0x8049760: xxx

donc, à un point, GLIBC a dépréché le environ symbole et ajouté une version plus récente


2 commentaires

Cela explique-t-il pourquoi environ est différent dans printf et p ?


@nos J'ai eu une situation inversée où GDB Imprimer Environ parfaitement, mais le programme à l'intérieur d'une bibliothèque partagée ne peut pas (obtenir 0x00 pointeur), toutes idées.