У меня есть статическая функция, которая предназначена для получения обратных вызовов в стиле C.Проводя некоторые эксперименты с многопоточными подходами, хочу попробовать способ получения обратного вызова в функции по разным адресам, но не хочу объявлять их все в коде, а скорее копировать функцию (с ее точкой входа) по другому адресу в памяти и регистрироватьэтот адрес с обратным вызовом.Также необходимо определить адрес точки входа функции в теле функции.
Есть ли возможность достичь этого с помощью C и, в частности, с помощью gcc в Linux?
Примечание: в моем случаеобратный вызов происходит с аргументом, который является уникальным по своему источнику - поэтому у меня нет проблем с распознаванием источников обратного вызова ... однако я чувствую необходимость описанного подхода для многопоточной + разветвленной среды - даже там, обратный вызов будет распознаваться либодескриптор или процесс / форк / ID потока
Редактировать: разветвление не работает: в следующем коде realme () и testme () являются общими адресами;Я думаю о -finstrument-functions
, backtrace()
и некоторых других шансах реализовать указатель memcpy + (см. Комментарии где-то ниже) ..
#include <iostream>
#include <string>
// Required by for routine
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h> // Declaration for exit()
using namespace std;
int globalVariable = 2;
void realme()
{
cout << "Testme() is at: " << __builtin_return_address(1) << std::endl;
}
void testme()
{
realme();
}
main()
{
string sIdentifier;
int iStackVariable = 20;
pid_t pID = fork();
if (pID == 0) // child
{
// Code only executed by child process
sIdentifier = "Child Process: ";
globalVariable++;
iStackVariable++;
}
else if (pID < 0) // failed to fork
{
cerr << "Failed to fork" << endl;
exit(1);
// Throw exception
}
else // parent
{
// Code only executed by parent process
sIdentifier = "Parent Process:";
}
// Code executed by both parent and child.
cout << sIdentifier;
cout << " Global variable: " << globalVariable;
cout << " Stack variable: " << iStackVariable << endl;
testme();
}