Люди часто советуют проходить через программу, используя gdb.
Это худший возможный совет при работе с такими сложными вещами, кактекстовый процессор (сокращенно WP).
Вместо этого вы должны запустить ldd
в двоичном файле или посмотреть /proc/<pid>/maps
для работающего WP и посмотреть, какие общие библиотеки он использует.
Тогда читайте об этих библиотеках.Один из них, вероятно, связан с визуализацией текста.Скорее всего, он также поставляется с набором примеров.
Создайте эту библиотеку, создайте примеры, измените их, чтобы сделать что-то еще.
Теперь вы готовы ответитьтакие вопросы, как «как этот WP использует эту библиотеку» путем установки точек останова GDB в точках входа библиотеки и изучения того, какие части WP вызывают их и с какими параметрами.
Повторите для других библиотек ив конечном итоге вы создадите картину того, как все складывается вместе.
Поэтому я попытался открыть файл на моем текстовом процессоре (который был скомпилирован с флагами отладки) и получить обратную трассировку, но, как ни странно, все, что у меня естьполучены несколько обычных вызовов функций, ни один из которых не относится к открытию файла.
В GDB сделайте следующее: catch syscall open
.Теперь попробуйте открыть файл, и вы узнаете, какая именно часть WP отвечает за это.
РЕДАКТИРОВАТЬ:
"catch syscall open" ловит все "открытые"системные вызовы, которых много
Да.Но не должно быть столько open
с после запуска WP.Так что сделайте catch
после того, как у вас на экране WP, и непосредственно перед выполнением операции меню File->Open
.
Есть ли способ указать имя файла вместе с catch syscall open?
Да, вы можете сделать catch
условным.Детали условия зависят от ОС.Похоже, вы используете i686-linux с VDSO
.Для этой комбинации следует выполнить следующее:
(gdb) catch syscall open
Catchpoint 1 (syscall 'open' [5])
(gdb) cond 1 ((char*)$ebx)[0] == '/' && ((char*)$ebx)[1] == 'h' \
&& ((char*)$ebx)[2] =='o' && ((char*)$ebx)[3] == 'm'
Вышеуказанное условие остановит точку перехвата только при открытии файлов с префиксом "/hom"
.
Вы можете добавить больше букв вочевидный путь.
Вы также можете попробовать это:
(gdb) cond 1 0 == strcmp($ebx, "/home/nav/Doc1.doc")
, но это, скорее всего, не сработает, прежде чем вы доберетесь до main
, и может привести к сбою GDB (он разбил мой, который являетсяошибка).