Есть ли какой-нибудь подключаемый интерфейс для замены функций во время компиляции? - PullRequest
1 голос
/ 05 марта 2019

Мне нужно отслеживать каждое сообщение журнала некоторого уровня журнала, когда разработчик добавляет коды, вызывающие функцию log_message в C и C ++.

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

Например:

file1.c:

log_message("Module:Failed to create the file %s\n", file_name);

file2.c:

log_message("Failed to create the XXXX file %s\n", file_name);

MESSAGE_1000 определяется в другом файле message.h, который генерируется из нашей базы данных сообщений. message.h:

const char* MESSAGE_1000 = “Module: Failed to create the file %s.\n”

После того, как файл предварительно скомпилирован:

file1.c становится:

#include "message.h"
...
log_message(MESSAGE_1000,file_name)

file2.c становится:

#include "message.h"
...
log_message(MESSAGE_1000,file_name)

Когда им нужно добавить новое сообщение в базу данных сообщений журнала.

Они могут использовать фиксированное имя функции, которое может быть распознано хуком.

Например:

file1.c:

log_message_new("My new message:%s", message)

Во время компиляции:

message.h обновлен до:

#defined MESSAGE_1001 "My new message:%s", message

В нашей базе данных сообщений добавлена ​​новая запись.

MESSAGE_1001="My new message:%s"

Почему существует база сообщений? Они для не-разработчиков. Они могут просматривать все сообщения журнала, которые могут видеть клиенты.

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

У вас есть идеи?

1 Ответ

2 голосов
/ 05 марта 2019

В gcc есть опция, которая иногда используется для таких случаев. Вы можете смоделировать функцию во время соединения с помощью -Wl,--wrap, см. Опции компоновщика GNU ld .

Вам потребуется простой модуль компиляции:

extern "C" void __real_log_message(...);
extern "C" void __wrap_log_message(...) { 
      .... // do something with the arguments
      __real_log_message(...); // call real function
}

Добавьте эти символы в процесс связывания и предоставьте -Wl,--wrap=log_message опцию связывания, и все готово.

...