Я предполагаю, что вызовы JNI в библиотеку налагают большую задержку.
Когда вы находитесь в точке останова и выполняете команду step
в GDB, никаких вызовов JNI на самом деле не происходит (вы уже находитесь в собственном коде и просто продолжаете до следующей строки или переходите к следующей функции, что получил JNI при чем тут?)
К сожалению, step
может быть медленным, даже если выполняется изначально; особенно для оптимизированного кода.
Как может step
команда работать? Теоретически, GDB может исследовать инструкции для текущей строки, обнаружить, что нет CALL
s и JMP
s, установить временный разрыв первой команды в следующей строке и продолжить. Это было бы быстро, но GDB на самом деле не работает.
То, что он делает вместо этого, является чем-то более простым: он пошагово обрабатывает процессор и в каждой инструкции спрашивает: «Остановился ли я сейчас на той же строке, на которой меня останавливали в последний раз?». Если «да», повторите один шаг, пока ответ «нет». Вы можете наблюдать это поведение, установив set debug infrun 1
.
В зависимости от того, сколько инструкций содержится в вашей текущей строке, выполнение команды step
может занять 100 шагов. Это может быть медленным при встроенной отладке, но может стать намного медленнее при использовании удаленного gdbserver, поскольку каждый раз, когда выполняется один шаг, GDB должен спрашивать gdbserver «где я сейчас». Это много пакетов, летящих между GDB и gdbserver. Вы можете наблюдать эти пакеты с set debug remote 1
.
Таким образом, факторы, которые
- протокол удаленного доступа к базе данных «болтливый»,
- , что каждый пакет должен идти на устройство и обратно по (относительно) медленной линии связи, и
- , что один
step
может включать 100 из этих
объединяются, чтобы произвести очень медленные step
казни, которые вы наблюдали.
Возможный обходной путь - избегать выполнения step
s. Вместо этого установите точки останова и проверьте состояние программы на каждом. В конце концов вы получите точку останова, которая находится «ниже по потоку» от ошибки (то есть программа уже находится в плохом состоянии). Теперь установите новую точку останова где-то «вверх по течению» от этого, и посмотрите на состояние там. Используя подход «разделяй и властвуй», вы довольно скоро сосредоточитесь на проблеме.