I writed my LD_PRELOAD module and i want to add some initialization code before my overrided functions work. Maybe LD_PRELOAD have any loaded event or something like this?
Thanks!
I'm not sure about a "loaded" event, however if you're using gcc, you may find the constructor attribute useful. Take for example:
testlib.c:
#include
void testing(void) __attribute__((constructor));
void testing(void)
{
printf("It worked!\n");
}
hworld.c:
#include <stdio.h>
int main(void)
{
printf("Hello world!\n");
return 0;
}
$ gcc -o hworld hworld.c
$ gcc -shared -fPIC -o testlib.so testlib.c
$ export LD_PRELOAD=./testlib.so
$ ./hworld
It worked!
Hello world!
The constructor attribute means that the function should be executed before main(). Alternatively, if you're using C++, you could create a static global instance of a class whose constructor does the initialization, which would achieve the same effect as using constructor.
Related
I have a c++ webassembly module with several function that is called wasmExec.wasm. So far i have been exporting methods from c++ to JavaScript that are located in the cpp file where the main() method is located using the EMSCRIPTEN_KEEPALIVE keyword. That is working just fine. I do see those methods when i do
wasm-nm wasmExec.wasm
and i can call them from JavaScript and get the expected result. In order achieve clean methods name i have been disabling C++ name mangling.
Now i have tried to use EMSCRIPTEN_KEEPALIVE with static methods that are not located in the main.cpp file instead in a separate namespace and separate cpp and header files. In those classes i am also using EMSCRIPTEN_KEEPALIVE but unfortunately the produced wasm module is eliminating my method and thus i can not see them when executing wasm-nm wasmExec.wasm althout they are marked with EMSCRIPTEN_KEEPALIVE in the header as well as in the cpp file. i.e. here is an example
#ifndef API_REGISTRATION_REGISTRATIONMANAGER_H_
#define API_REGISTRATION_REGISTRATIONMANAGER_H_
#include <string>
#include <emscripten/emscripten.h>
using namespace std;
namespace api::registration {
#ifdef __cplusplus
extern "C" {
#endif
class RegistrationManager {
public:
explicit RegistrationManager();
virtual ~RegistrationManager();
static char* EMSCRIPTEN_KEEPALIVE registerClient(
char* userNameInputPtr, int userNameLength
);
};
#ifdef __cplusplus
}
#endif
}
#endif /* API_REGISTRATION_REGISTRATIONMANAGER_H_ */
I am using cmake to compile the project. In the target properties i have explicitly defined EXPORTED_FUNCTIONS to be equal to
set_target_properties(wasmExec PROPERTIES LINK_FLAGS "-std=c++17 -s WASM=1 -s TOTAL_MEMORY=512MB -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=1 -s VERBOSE=1 --pre-js /Projects/src/wasm/preModule.js -s DEMANGLE_SUPPORT=1 -s DISABLE_EXCEPTION_CATCHING=0 -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s EXPORTED_FUNCTIONS='['registerClient']' -s EXTRA_EXPORTED_RUNTIME_METHODS='['cwrap', 'getValue', 'setValue', 'registerClient' ]' " )
What could be the reason to not be able to register this the method "registerClient" within the webassembly module. I have even tired to use the option -s EXPORT_ALL=1 but that did not exported all the know methods as i was expcting it to do
I am compiling everything statically here i.e. below is the example of the registration_api cmake sub-folder
MESSAGE( STATUS "ADDING API_REGISTRATION_DIR")
set( API_REGISTRATION_SRC
RegistrationManager.h RegistrationManager.cpp
)
set(LIB_TYPE STATIC)
add_library(api_registration ${LIB_TYPE} ${API_REGISTRATION_SRC} )
target_include_directories(api_registration PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/")
the compilation process is successful with emscripten, nevertheless i do get this warrning exactly about the method i am trying to export:
em++: warning: undefined exported function: "registerClient" [-Wundefined]
if i put that method in the main.cpp it is automatically exported without any problem.
My question is what could be the reason why this export is not working when the method is located in external cp/hpp file?
Addition 15 May 2020: I was able to register the method only if i remove the class definition, change the namesapce to the one that main have. Then it seems that the underscore in the EXPORTED_FUNCTIONS is important i.e. -s EXPORTED_FUNCTIONS='['_registerClient']' . That worked for me. I was under the impression that if i use static methods that should work with classes as well, but it seems that not to be the case.
#ifndef API_REGISTRATION_REGISTRATIONMANAGER_H_
#define API_REGISTRATION_REGISTRATIONMANAGER_H_
#include <string>
#include <emscripten/emscripten.h>
using namespace std;
namespace wasm {
#ifdef __cplusplus
extern "C" {
#endif
char* EMSCRIPTEN_KEEPALIVE registerClient(
char* userNameInputPtr, int userNameLength
);
#ifdef __cplusplus
}
#endif
}
#endif /* API_REGISTRATION_REGISTRATIONMANAGER_H_ */
thus my question has changed to: Can emscripten register a static method of a class with EMSCRIPTEN_KEEPALIVE or not?
Given
void foo() {
int i = 0;
#ifdef MACRO_A
// custom behaviour
#endif
// program code
}
Is it possible to pass #define MACRO_A to clang++ when compiling to allow the 'custom behavour' statements to come into effect? I cannot find documentation which suggests this is possible in clang++, but it IS possible in other compilers (g++).
The command, thanks to pevasquez's help, is
clang++ -D MACRO_A main.cpp -o main
The function
void foo() {
int i = 0;
#ifdef MACRO_A
// custom behaviour
#endif
// program code
}
will compile with the code in the pre-processor directive section being included.
This will be an addition to my makefiles to create a debug friendly make-chain as well and the production version.
I'm using dlopen() and dlclose() to load and unload a module. The module contains some static data which needs to be destructed when dlclose() is called. However I'm finding that under certain circumstances dlclose() does not call the destructors - instead they are only called when main() exits.
I've boiled my code down to this. I have a class which contains a virtual function getType() defined inside the class, making reference to static data. I also have a StaticDestructionChecker object which just prints when the static constructors and destructors are being called. Finally I have a main() function that loads everything else via dlopen(), closes it via dlclose() and prints when main() is finished:
module1.h
#ifndef MODULE1_H
#define MODULE1_H
class MyClass
{
public:
MyClass();
virtual ~MyClass();
virtual int& getType() const
{
static int t(123);
return t;
}
};
#endif // MODULE1_H
module1.cpp
#include <stdio.h>
#include "module1.h"
MyClass::MyClass()
{
}
MyClass::~MyClass()
{
}
class StaticDestructionChecker
{
public:
StaticDestructionChecker()
{
printf("Constructing static data\n");
}
~StaticDestructionChecker()
{
printf("Destructing static data\n");
}
};
StaticDestructionChecker checker;
main:
#include <dlfcn.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
void* handle = dlopen("module1.so", RTLD_NOW);
if (!handle) printf("dlopen error: %s\n", dlerror());
dlclose(handle);
printf("end of main\n");
return 0;
}
Running all this as-is causes the static data to be destructed after main terminates, ie the output is:
Constructing static data
end of main
Destructing static data
The problem is with the virtual/static combo in getType(). If I change getType() to be non-virtual OR if I remove the "static int t", the destructors get called when expected, ie output is:
Constructing static data
Destructing static data
end of main
Is there a way to get the correct destruction order while still keeping the virtual/static code? FYI this is a simplified version of a sort of custom RTTI system, where getType() is automatically generated via a DECLARE_xxx macro, so I don't want to move the implementation into the cpp file because there would need to be a second macro call in there too.
I am using GCC 4.8 on Ubuntu 12.
Thanks
See dlclose() doesn't work with factory function & complex static in function?
If you use gold linker than passing --no-gnu-unique flag when linking module1.so fixes the problem:
]$ g++ -o module1.so -shared -fPIC -Wl,--no-gnu-unique module1.cpp
]$ g++ main.cpp -ldl
]$ LD_LIBRARY_PATH=. ./a.out
Constructing static data
Destructing static data
end of main
I don't know what are other consequences of using that flag.
I have a simple question. I want to compile the following c file:
#include <linux/kernel.h>
#include <linux/module.h>
#include <sys/syscall.h>
extern void *sys_call_table[];
asmlinkage int (*original_sys_open)(int);
asmlinkage int our_fake_open_function(int error_code)
{
/*print message on console every time we
* *are called*/
printk("HEY! sys_open called with error_code=%d\n",error_code);
/*call the original sys_exit*/
return original_sys_open(error_code);
}
/*this function is called when the module is
* *loaded (initialization)*/
int init_module()
{
/*store reference to the original sys_exit*/
original_sys_open=sys_call_table[__NR_open];
/*manipulate sys_call_table to call our
* *fake exit function instead
* *of sys_exit*/
sys_call_table[__NR_open]=our_fake_open_function;
}
/*this function is called when the module is
* *unloaded*/
void cleanup_module()
{
/*make __NR_exit point to the original
* *sys_exit when our module
* *is unloaded*/
sys_call_table[__NR_open]=original_sys_open;
}
The problem is that gcc -I/usr/src/kernels/2.6.32-279.el6.x86_64/include myfile.c generates a unsolvabe include dependency which can be found in .
Please tell me how to fix this gcc compiler problem I am encountering today. Thank you very much for your insight.
How to build external modules is documented in the documentation:
$ make -C <path_to_kernel_src> M=$PWD
I am attempting to do the following - write a wrapper for the pthreads library that will log some information whenever each of its APIs it called.
One piece of info I would like to record is the stack trace.
Below is the minimal snippet from the original code that can be compiled and run AS IS.
Initializations (file libmutex.c):
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <dlfcn.h>
static int (*real_mutex_lock)(pthread_mutex_t *) __attribute__((__may_alias__));
static void *pthread_libhandle;
#ifdef _BIT64
#define PTHREAD_PATH "/lib64/libpthread.so.0"
#else
#define PTHREAD_PATH "/lib/libpthread.so.0"
#endif
static inline void load_real_function(char* function_name, void** real_func) {
char* msg;
*(void**) (real_func) = dlsym(pthread_libhandle, function_name);
msg = dlerror();
if (msg != NULL)
printf("init: real_%s load error %s\n", function_name, msg);
}
void __attribute__((constructor)) my_init(void) {
printf("init: trying to dlopen '%s'\n", PTHREAD_PATH);
pthread_libhandle = dlopen(PTHREAD_PATH, RTLD_LAZY);
if (pthread_libhandle == NULL) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
load_real_function("pthread_mutex_lock", (void**) &real_mutex_lock);
}
The wrapper and the call to backtrace.
I have chopped as much as possible from the methods, so yes, I know that I never call the original pthread_mutex_lock for example.
void my_backtrace(void) {
#define SIZE 100
void *buffer[SIZE];
int nptrs;
nptrs = backtrace(buffer, SIZE);
printf("backtrace() returned %d addresses\n", nptrs);
}
int pthread_mutex_lock(pthread_mutex_t *mutex) {
printf("In pthread_mutex_lock\n"); fflush(stdout);
my_backtrace();
return 0;
}
To test this I use this binary (file tst_mutex.c):
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int main (int argc, char *argv[]) {
pthread_mutex_t x;
printf("Before mutex\n"); fflush(stdout);
pthread_mutex_lock(&x);
printf("after mutex\n");fflush(stdout);
return 0;
}
Here is the way all this is compiled:
rm -f *.o *.so tst_mutex
cc -Wall -D_BIT64 -c -m64 -fPIC libmutex.c
cc -m64 -o libmutex.so -shared -fPIC -ldl -lpthread libmutex.o
cc -Wall -m64 tst_mutex.c -o tst_mutex
and run
LD_PRELOAD=$(pwd)/libmutex.so ./tst_mutex
This crashes with segmentation fault on Linux x86.
On Linux PPC everything works flawlessly.
I have tried a few versions of GCC compilers, GLIBC libraries and Linux distros - all fail.
The output is
init: trying to dlopen '/lib64/libpthread.so.0'
Before mutex
In pthread_mutex_lock
In pthread_mutex_lock
In pthread_mutex_lock
...
...
./run.sh: line 1: 25023 Segmentation fault LD_PRELOAD=$(pwd)/libmutex.so ./tst_mutex
suggesting that there is a recursion here.
I have looked at the source code for backtrace() - there is no call in it to locking mechanism. All it does is a simple walk over the stack frame linked list.
I have also, checked the library code with objdump, but that hasn't revealed anything out of the ordinary.
What is happening here?
Any solution/workaround?
Oh, and maybe the most important thing. This only happens with the pthread_mutex_lock function!!
Printing the stack from any other overridden pthread_* function works just fine ...
It is a stack overflow, caused by an endless recursion (as remarked by #Chris Dodd).
The backtrace() function runs different system calls being called from programs compiled with pthread library and without. Even if no pthread functions are called explicitly by the program.
Here is a simple program that uses the backtrace() function and does not use any pthread function.
#include <stdio.h>
#include <stdlib.h>
#include <execinfo.h>
int main(void)
{
void* buffer[100];
int num_ret_addr;
num_ret_addr=backtrace(buffer, 100);
printf("returned number of addr %d\n", num_ret_addr);
return 0;
}
Lets compile it without linking to the pthread and inspect the program system calls with the strace utility. No mutex related system call appears in the output.
$ gcc -o backtrace_no_thread backtrace.c
$ strace -o backtrace_no_thread.out backtrace_no_thread
No lets compile the same code linking it to the pthread library, run the strace and look at its output.
$ gcc -o backtrace_with_thread backtrace.c -lpthread
$ strace -o backtrace_with_thread.out backtrace_with_thread
This time the output contains mutex related system calls (their names may depend on the platform). Here is a fragment of the strace output file obtained on an X86 Linux machine.
futex(0x3240553f80, FUTEX_WAKE_PRIVATE, 2147483647) = 0
futex(0x324480d350, FUTEX_WAKE_PRIVATE, 2147483647) = 0