Я столкнулся с такой ошибкой при выполнении команды ni во время отладки gdb:
Предупреждение:
Невозможно вставить точку останова 0.
Ошибка доступа к адресу памяти 0x3ac706a: ошибка ввода/вывода.
0xf6fa4771 в siglongjmp() из /lib/libc.so. 6
Чтобы выяснить, с какой проблемой сталкивается gdb, я запускаю gdb и получаю такой вывод:
rt_sigprocmask(SIG_BLOCK, NULL, [RT_1], 8) = 0
ptrace(PTRACE_PEEKTEXT, 651, 0xcc4fdf60, [0x1cc4fe470]) = 0
ptrace(PTRACE_PEEKTEXT, 651, 0xcc4fe480, [0x3ac706a4506fa1d]) = 0
ptrace(PTRACE_PEEKTEXT, 651, 0xcc4fe480, [0x3ac706a4506fa1d] 0
rt_sigprocmask(SIG_BLOCK, NULL, [RT_1], 8) = 0
…
...
rt_sigprocmask(SIG_BLOCK, NULL, [RT_1], 8) = 0< br> rt_sigprocmask(SIG_BLOCK, NULL, [RT_1], 8) = 0
ptrace(PTRACE_GETREGS, 27781, 0, 0x7fff8990e8b0) = 0
ptrace(PTRACE_PEEKTEXT, 27781, 0x3ac7068, [0x28b]) = -1 EIO (ошибка ввода/вывода)
ptrace(PTRACE_PEEKTEXT, 27781, 0x3ac7068, [0x28b]) = -1 EIO (ошибка ввода/вывода)
Это означает, что gdb сначала выполняет трассировку по адресу памяти 0xcc4fe480 и получает значение 0x3ac706a4506fa1d (фактически 8-байтовое значение 0x03ac706a4506fa1d). Позже он получает выровненный адрес 0x3ac7068 из первых 4 байтов этого значения, что является недопустимым адресом и приводит к сбою ptrace gdb.
Содержимое /proc/[pid]/maps:
cc3f0000-cc3f6000 br> cc3f6000-cc3fe000 rw-p cc3f6000 00:00 0
cc3fe000-cc3ff000 ---p cc3fe000 00:00 0
cc3ff000-cc4ff000 rwxp cc3ff000 00:00 0
cc4ff000-cc500000 ---p cc4ff000 00:00 0
cc500000-cc600000 rwxp cc500000 00:00 0
cc62d000-cc673000 r-xp 00000000 08:03 07cc
06-br00.yyy ---p 00046000 08:03 295545 yyy.so
cc674000-cc675000 r--p 00046000 08:03 295545 yyy.so
cc675000-cc676000 rw-p 00047000 08:03 yy
5.45 295y
Он показывает, что адрес 0xcc4fe480 взят из раздела, выделенного жирным шрифтом выше. Этот раздел не связан ни с каким файлом .so или bin.
Этот вопрос на самом деле связан с другим вопросом http://stackoverflow.com/questions/9564417/gdb-cant-insert-internal- точка останова, которая еще не разрешена. Я обнаружил эти проблемы во время исследования предыдущей проблемы.
У меня есть 3 вопроса:
1. Взгляните на вывод strace для ptrace здесь:
ptrace(PTRACE_PEEKTEXT, 651, 0xcc4fe480, [0x3ac706a4506fa1d]) = 0
Почему последний параметр заключен в квадратные скобки? Означает ли это, что он представляет возвращаемое значение? На странице руководства говорится, что ptrace должен возвращать слово, прочитанное для PTRACE_PEEKTEXT, но похоже, что вывод strace не следует этому, поэтому я подозреваю, что он показывает возвращаемое значение в последнем параметре.
2. Между двумя разделами есть раздел (кто выделен жирным шрифтом). .so, но не связанный с каким-либо инодом. Что представляет такой раздел?
3. Gdb читает одно слово из этого раздела и использует это слово как адрес, но на самом деле это недопустимый адрес. Каковы возможные причины такой ошибки?
Спасибо!