Почему отладка собственных разделяемых библиотек, используемых приложениями Android, замедляется?

#android #debugging #shared-libraries #gdbserver

#Android #отладка #общие библиотеки #gdbserver

Вопрос:

Я часто использую gdbServer для отладки удаленного приложения Android. Область, в которой я установил точки останова, — это разделяемая библиотека, написанная на c .

Пошаговое выполнение кода происходит чрезвычайно медленно. Кто-нибудь знает, почему это? Я предполагаю, что вызовы JNI в библиотеку приводят к большой задержке.

Ответ №1:

Я предполагаю, что вызовы 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 .

Таким образом, факторы, которые

  • Удаленный протокол GDB «болтливый»,
  • что каждый пакет должен передаваться на устройство и обратно по (относительно) медленной ссылке, и
  • что в одной step может быть задействовано 100 из этих

объединение приводит к очень медленному step выполнению, которое вы наблюдали.

Возможный обходной путь — избегать выполнения step s. Вместо этого установите точки останова и проверяйте состояние программы на каждой. В конечном итоге вы достигнете точки останова, которая находится «ниже по течению» от ошибки (т. Е. программа уже находится в плохом состоянии). Теперь установите новую точку останова где-нибудь «выше по течению» от этого и посмотрите на состояние там. Используя подход «разделяй и властвуй», вы довольно скоро сведете проблему к нулю.