Разрешение адреса памяти в косвенном обращении gdb

#c #pointers #gdb

#c #указатели #gdb

Вопрос:

После компиляции с -g , чтобы получить отладочную информацию в программе и запустить gdb ее, я могу сделать следующее, чтобы распечатать вектор аргументов:

 >>> p __libc_argv
$2 = (char **) 0x7fffffffe9f8
>>> p __libc_argv[0]
$3 = 0x7fffffffec63 "./sample.out"
  

Мой вопрос двоякий:

  • Почему __libc_argv[0] и не __libgc_argv выдает тот же адрес памяти? Выполняет gdb ли какая-то интерпретация в фоновом режиме?

  • Как я могу получить адрес памяти 0x7fffffffec63 из приведенного выше? Например:

      >>> p __libc_argv
     $2 = (char **) 0x7fffffffe9f8 
     >>> x/s 0x7fffffffec63   <-- how do figure out this memory address value?
     0x7fffffffec63:    "./sample.out"
      

Комментарии:

1. argv является указателем на указатель. argv[0] является указателем, на который он указывает. Почему вы ожидаете, что они будут одинаковыми?

2. Я не понимаю второго вопроса. Вы получаете это из __libc_argv[0] того, как именно вы это сделали.

3. Или p *__libc_argv

4. x/s *__libc_argv ?

5. @Barmar я вижу. Итак, тогда почему нет argc и argv смежны друг с другом? >>> p __libc_argv $23 = (char **) 0x7fffffffe9f8 и >>> p amp;__libc_argc $24 = (int *) 0x7ffff7fc0e78 <__libc_argc>

Ответ №1:

__libc_argv является указателем на массив указателей. __libc_argv[0] является содержимым первого элемента этого массива. Нет причин, по которым они должны быть одинаковыми, если только вы сначала не сделали __libc_argv[0] = __libc_argv это по какой-то причине. Но это было бы неразумно, поскольку элементы __libc_argv должны быть указателями на строки, а не указателями на массивы.

С другой стороны, __libc_argv == amp;__libc_argv[0] и *__libc_argv == __libc_argv[0] .

Чтобы получить нужный адрес, просто выполните косвенный переход __libc_argv .

 >>> x/s *__libc_argv