Почему медленная отладка собственных общих библиотек, используемых приложениями Android? - PullRequest
1 голос
/ 08 ноября 2011

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

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

1 Ответ

1 голос
/ 10 ноября 2011

Я предполагаю, что вызовы 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. Вместо этого установите точки останова и проверьте состояние программы на каждом. В конце концов вы получите точку останова, которая находится «ниже по потоку» от ошибки (то есть программа уже находится в плохом состоянии). Теперь установите новую точку останова где-то «вверх по течению» от этого, и посмотрите на состояние там. Используя подход «разделяй и властвуй», вы довольно скоро сосредоточитесь на проблеме.

...