Your process is faulting because dlerror()
is only valid to call in an error condition, which you never validated actually happened prior to invocation.
From the Linux docs:
The function
dlerror()
returns a human readable string describing the most recent error that occurred fromdlopen()
,dlsym()
ordlclose()
since the last call todlerror()
. It returns NULL if no errors have occurred since initialization or since it was last called.
In other words, your dlopen
succeeded, so NULL is returned from dlerror()
. That NULL is then sent as a char *
to std::cout
, and kerboom.
Bottom line: check your error conditions before invoking dlerror()
. Try this instead:
#include <iostream>
#include <dlfcn.h>
int main(int argc, char** argv)
{
typedef void* (*fptr)();
fptr func;
void *handle = dlopen(0, RTLD_NOW);
if (handle == nullptr)
{
std::cout << dlerror() << std::endl;
exit(EXIT_FAILURE);
}
func = (fptr)dlsym(handle, "__libc_start_main");
if (!func)
{
std::cout << dlerror() << std::endl;
exit(EXIT_FAILURE);
}
std::cout << handle << " " << func << "\n";
dlclose(handle);
return 0;
}