GDB разрешает неправильный символ environ
. Хотя я не знаю почему. См. Ниже, почему.
Но вы можете проверить это.Измените программу на:
#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;
}
Теперь давайте запустим это в отладчике.
(gdb) n
7 printf("%p\n", &environ);
(gdb) n
0x8049760
8 while(environ[i]) {
(gdb) p &environ
$1 = (char ***) 0x46328da0
(gdb)
Итак.Фактическая программа во время связывания разрешает environ
по адресу 0x8049760.Когда GDB хочет получить доступ к символу environ
, он разрешается в 0x46328da0, что отличается.
Редактировать.Кажется, ваш символ environ
действительно связан с символом environ@@GLIBC_2.0
.В gdb напишите это:
(gdb) p environ
и нажмите клавишу табуляции (дважды), она автоматически завершит символы.Который дает:
(gdb) p environ
environ environ@@GLIBC_2.0
environ@@GLIBC_2.0
- это тот, который на самом деле связан с extern char **environ
. При печати это дает тот же адрес, который видит программа, 0x8049760:
(gdb) p &'environ@@GLIBC_2.0'
$9 = ( *) 0x8049760
(gdb) p ((char**)'environ@@GLIBC_2.0')[i]
$10 = 0xbffff6ad "XDG_SESSION_ID=1"
Итак, в какой-то момент glibc устарел символ environ
и добавил более новую версию