Методы отладки без инструментов отладки - PullRequest
6 голосов
/ 21 марта 2012

Я нахожусь в сложной ситуации, когда приходится отлаживать приложение Qt практически без какого-либо инструмента отладки: кажется, что приложение начинает использовать все больше и больше ЦП, поскольку оно выполняет одно и то же действие снова и снова; через много часов процессор полностью насыщается.

Приложение работает на встроенном устройстве ARM Linux, где GDB, похоже, не работает, возможно, трудно обнаружить проблемы с предоставленным набором инструментов. Похоже, что strace сообщает только о действиях таймера (это приложение OpenGL, так что это ожидаемо). ltrace недоступен, и его компиляция привела к трудной задаче, может быть, бесполезной. Я не писал приложение, но исходный код доступен.

Могу ли я еще что-нибудь сделать, чтобы узнать, чем занимается приложение, потребляя столько ресурсов? В любом случае мне нужно отследить все вызовы методов, которые делает приложение? Есть ли какая-то другая техника, которую я могу использовать, чтобы попытаться угадать проблему, или где я могу сосредоточить свое внимание?

РЕДАКТИРОВАТЬ: Это одна из проблем с GDB: Только вопросительные знаки в обратном следе, сообщенные GDB на ARM . Даже написание приложения из десяти строк, имитирующего segfault, приводит к этому.

Ответы [ 5 ]

4 голосов
/ 21 марта 2012

Можете ли вы включить дамп ядра на машине?Затем, когда он воспроизводится, вы можете отправить его в SIGABRT и скопировать дамп ядра на свой компьютер разработчика и проверить его с помощью кросс-отладчика, с доступным исходным кодом и разархивированным исполняемым файлом.

Также важно изучитьгорький урок в следующий раз, не используйте такой плохо поддерживаемый набор инструментов.

Если это вариант, вы можете попробовать другой набор инструментов с хотя бы gdbserver, если не поддерживает gdb.Я был очень доволен набором инструментов CodeSourcery ARM Lite.

РЕДАКТИРОВАТЬ: GDB для вашей ситуации поставляется в двух вариантах:

  • Cross-GDB, который работает на вашем хосте разработки
  • собственный gdb, который работает на вашей цели

gdbserver позволяет вам запустить свой cross-gdb на хосте разработки и подключиться к цели для удаленной отладки чего-либо, выполняющегося на нем.Таким образом, дамп ядра или gdbserver - это два способа использования кросс-gdb для проверки чего-либо на цели, но один gdbserver вам не сильно поможет.

Если ваш кросс-компилятор похож на arm-none-linux-gnueabi-gcc,проверьте, есть ли у вас на компьютере разработчика arm-none-linux-gnueabi-gdb.

3 голосов
/ 21 марта 2012

Вы можете попытаться разместить некоторый код отладки в своем приложении.

Выберите какой-нибудь сигнал, например, SIGINT.Добавьте обработчик сигнала для этого сигнала.В этом обработчике выведите трассировку стека или хотя бы значение указателя инструкции.Затем запустите приложение и отправьте SIGINT несколько раз, чтобы узнать, что делает ваше приложение.

0 голосов
/ 21 марта 2012

Предполагая, что в gcc есть что-то вроде файлового и строкового макросов MSVC, которые расширяются до текущего файла и текущей строки, вы можете создать собственную функцию псевдопрофилирования. Поместите это в заголовок:

void MyPseudoProfileLog(const char* file, int line, int* count);
#define MY_PSEUDO_PROFILE_LOG(file, line) { static int count = 0; MyPseudoProfileLog(file, line, &count); }

Это происходит в файле cpp (если вы поместите его в заголовок, вы получите несколько копий статической переменной, по одной для каждого файла cpp, в который вы включаете заголовок):

void MyPseudoProfileLog(const char* file, int line, int* count)
{
    static FILE* f = NULL;
    const int max_count = 1000;
    if (++(*count) == max_count)
    {
        *count = 0;
        if (!f)
            f = fopen("/tmp/my_pseudo_profile_log.log");
        fprintf(f, "file=\"%s\", line=%d was passed %d times\n", file, line, max_count);
        fflush(f);
    }
}

Тогда вы можете вставить

MY_PSEUDO_PROFILE_LOG(__FILE__, __LINE__);

в различные места в вашем коде, чтобы увидеть, как часто они будут вызываться. Имейте в виду, что это не потокобезопасно, поэтому используйте только в основном потоке.

0 голосов
/ 21 марта 2012

Вы можете попробовать запустить ARM-версию профилировщика Zoom - это должно сказать вам, где ваш код тратит большую часть своего времени - вы можете скачать его бесплатно на 30-дневной пробной лицензии.*

0 голосов
/ 21 марта 2012

Попробуйте записать время выполнения различных функций. Сначала запишите время выполнения наиболее вероятных кандидатов, и, если вы их исключили, продолжите выполнение других менее вероятных функций в вашей программе.

Самый простой способ зарегистрировать сообщение - использовать std :: cout (или printf) и перенаправить out в файл, чтобы вы могли увидеть журнал в более позднее время.

...