Насмешки во время выполнения в C?

Это уже давно находится в моем списке. Вкратце: мне нужно запустить mocked_dummy() вместо dummy() ВО ВРЕМЯ ВЫПОЛНЕНИЯ, не изменяя factorial(). Меня не волнует точка входа программного обеспечения. Я могу добавить любое количество дополнительных функций (но не могу изменить код внутри /*---- не изменять ----*/).

Зачем мне это нужно?
Чтобы выполнить модульные тесты некоторых устаревших модулей C. Я знаю, что существует множество доступных инструментов, но если возможна имитация во время выполнения, я могу изменить свой подход к UT (добавить повторно используемые компоненты), чтобы облегчить себе жизнь :).

Платформа/среда?
Линукс, ARM, gcc.

Подход, который я пытаюсь использовать?

  • Я знаю, что GDB использует trap/недопустимые инструкции для добавления точек останова (внутренние компоненты gdb).
  • Сделайте код самомодифицируемым.
  • Замените сегмент кода dummy() недопустимой инструкцией и возвратите как ближайшую следующую инструкцию.
  • Управление передается обработчику ловушек.
  • Обработчик прерываний — это повторно используемая функция, которая считывает данные из сокета домена unix.
  • Передан адрес функции mocked_dummy() (читается из файла карты).
  • Выполняется фиктивная функция.

Дальше будут проблемы.Я также обнаружил, что этот подход утомителен и требует большого количества кода, в том числе и на ассемблере.

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

Есть ли другой подход, который я мог бы использовать?

#include 
#include 

void mocked_dummy(void)
{
    printf("__%s__()\n",__func__);
}

/*---- do not modify ----*/
void dummy(void)
{
    printf("__%s__()\n",__func__);
}

int factorial(int num) 
{
    int                      fact = 1;
    printf("__%s__()\n",__func__);
    while (num > 1)
    {
        fact *= num;
        num--;
    }
    dummy();
    return fact;
}
/*---- do not modify ----*/

int main(int argc, char * argv[])
{
    int (*fp)(int) = atoi(argv[1]);
    printf("fp = %x\n",fp);
    printf("factorial of 5 is = %d\n",fp(5));
    printf("factorial of 5 is = %d\n",factorial(5));
    return 1;
}

9
задан ChrisWue 8 March 2012 в 06:22
поделиться