variable una permanentes imprimir hat entorno crear configurar agregar c linux gdb environment-variables

c - una - ¿Por qué no puedo imprimir variables de entorno en gdb?



variable path linux (5)

Como grundprinzip dijo, use getenv (sz) y recuerde anular la verificación del valor de retorno

Alternativamente,

#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; }

#include <unistd.h> #include <stdio.h> extern char **environ; int main(int argc, char *argv[]) { int i = 0; while(environ[i]) { printf("%s/n", environ[i++]); } return 0; }

Aquí está mi ops:

(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]) {

Como puede ver, printf puede imprimir environ[i] , pero p environ[i] me da Cannot access memory at address 0x0 , ¿por qué?


No hay nada malo con tu código. Lo probé en mi máquina e imprimió el entorno como se esperaba. No debería necesitar usar getenv ().

¿Está ejecutando esta aplicación desde la terminal? Si no, deberías serlo. Otros medios para ejecutar una aplicación podrían ser invocar su binario sin pasarle el entorno.

Desde el terminal, ¿cuál es su salida cuando ejecuta "env"? Debería generar la misma lista que su programa. Lo hace en mi máquina.


Probablemente, el proceso de depuración se inicia con

execve(binary, NULL, NULL);

y el entorno extern char **environ obtiene ese 2nd NULL a pesar de que hay un entorno disponible.

Con un pequeño cambio, su programa funciona tanto de forma independiente como bajo gdb .

/* #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; }

Por qué y cómo, ese NULL se convierte al valor correcto dentro de gdb no tengo ni idea.


Se accede a las variables de entorno en C / C ++ utilizando la función getenv() definida en stdlib.h . Sin embargo, usando el parámetro envp de la función principal, puede usar el siguiente ejemplo para iterar sobre variables de entorno.

#include <stdio.h> int main(int argc, char *argv[], char *envp[]) { char **next = envp; while (*next) { printf("%s/n", *next); next++; } return 0; }

Probado en una Mac


gdb resuelve el símbolo de environ incorrecto. No obstante, no sé por qué. Vea a continuación por qué.

Pero puedes probarlo. Cambiar el programa a:

#include <unistd.h> #include <stdio.h> extern char **environ; int main(int argc, char *argv[]) { int i = 0; printf("%p/n", &environ); while(environ[i]) { printf("%s/n", environ[i++]); } return 0; }

Ahora ejecutemos esto en el depurador.

(gdb) n 7 printf("%p/n", &environ); (gdb) n 0x8049760 8 while(environ[i]) { (gdb) p &environ $1 = (char ***) 0x46328da0 (gdb)

Asi que. El programa real tiene, durante su vinculación, resuelto environ a la dirección 0x8049760. Cuando gdb quiere acceder al símbolo de entorno, se resuelve en 0x46328da0, que es diferente.

Editar. Parece que su símbolo de environ está realmente vinculado al símbolo environ@@GLIBC_2.0 . En gdb escribe esto:

(gdb) p environ

Y presiona la tecla tab (dos veces), autocompletará los símbolos. Cuyos rendimientos:

(gdb) p environ environ environ@@GLIBC_2.0

environ@@GLIBC_2.0 es el que en realidad está vinculado al environ@@GLIBC_2.0 extern char **environ

Imprimir esto produce la misma dirección que el programa ve, 0x8049760:

(gdb) p &''environ@@GLIBC_2.0'' $9 = ( *) 0x8049760 (gdb) p ((char**)''environ@@GLIBC_2.0'')[i] $10 = 0xbffff6ad "XDG_SESSION_ID=1"

Entonces, en un momento, glibc dejó de environ símbolo del environ y agregó una versión más nueva