For a project I'm writing I need to write a custom Lua module loading system, and I've done it before on my Raspberry Pi, but not on my Mac. The problem is that as soon as I try to access the lua_State in the shared object, the program segfaults.
main.cpp
#include <lua.hpp>
#include <dlfcn.h>
#include <iostream>
typedef void Register(lua_State*);
int main(){
lua_State* L = luaL_newstate();
void* lib = dlopen("module.so", RTLD_NOW);
if(!lib){
std::cerr << "Error opening module \"" << "\": " << dlerror() << std::endl;
return;
}
Register* loadFunc = (Register*)dlsym(lib, "RegisterModule");
if(!loadFunc){
std::cerr << "Error loading symbols from module \"" << "\": " << dlerror() << std::endl;
return;
}
loadFunc(L);
for(;;){}
return 1;
}
module.cpp
#include <lua.hpp>
#include <iostream>
static int Foo(lua_State* L){
std::cout << "Hello World!" << std::endl;
}
extern "C" void RegisterModule(lua_State* L){
lua_pushcfunction(L, Foo);
lua_setglobal(L, "Foo");
}
Makefile
lua = -L /usr/lib/lua5.2 -I /usr/include/lua5.2 -llua
luaHeaders = -I /usr/include/lua5.2
all: main module.so
rm -f main.o
main: main.o
clang++ main.o -o main $(lua) -ldl
main.o: main.cpp
clang++ -c main.cpp $(luaHeaders)
module.so: module.cpp
clang++ -fPIC -shared module.cpp -o module.so $(lua)
My setup is:
Mac OS X 10.9 Mavericks, and Elementary OS Luna
Lua 5.2
Clang
Output from the debugger (lldb)
Process 19943 stopped
* thread #2: tid = 0x23ec1c, 0x0000000100295c31 myModule.so`luaH_newkey + 913, stop reason = EXC_BAD_ACCESS (code=2, address=0x100073db0)
frame #0: 0x0000000100295c31 myModule.so`luaH_newkey + 913
myModule.so`luaH_newkey + 913:
-> 0x100295c31: movq %rax, 16(%r12)
0x100295c36: movl 8(%rbx), %eax
0x100295c39: movl %eax, 24(%r12)
0x100295c3e: testb $64, 8(%rbx)
Related
I have a project with the following structure:
Item.cpp
Item.h
main.cpp
Makefile
The following source code is in the Item.h file:
class Item {
public:
Item();
~Item();
};
The following source code is in the Item.cpp file:
#include <iostream>
#include "Item.h"
Item::Item() {
std::cout << "Item created..." << std::endl;
}
Item::~Item() {
std::cout << "Item destroyed..." << std::endl;
}
The following source code is the content of the main.cpp file:
#include "Item.h"
#include <iostream>
int main() {
std::cout << "Initialize program..." << std::endl;
Item item_1();
std::cout << "Hello world!" << std::endl;
return 0;
}
And finally, the following source code is the Makefile file:
CXX = g++
all: main item
$(CXX) -o sales.o main.o Item.o
main:
$(CXX) -c main.cpp
item:
$(CXX) -c Item.cpp
clean:
rm -rf *.o
When I run the make command and then I run the compiled code with the command ./sales.o, I get the following output:
Initialize program...
Hello world!
Why is the output of the constructor method of the class Item not printed in the console? I found in some web pages that you can compile the source codes in steps and then you can link it with the -o option when using g++ but it does not work in this case. How can I compile this source codes step by step and then link it in the Makefile?
I'm surely you ignored this warning :
warning: empty parentheses were disambiguated as a function declaration [-Wvexing-parse]
#include "Item.h"
#include <iostream>
int main() {
std::cout << "Initialize program..." << std::endl;
Item item_1;
std::cout << "Hello world!" << std::endl;
return 0;
}
just remove parentheses it will be work
test : https://godbolt.org/z/KrdrhvsrW
I have a problem with openssl and the EVP-functions:
When I execute the following code
#include <openssl/evp.h>
#include <openssl/engine.h>
#include <array>
#include <iostream>
void hash(ENGINE* eng) {
EVP_MD_CTX *_mdctx(EVP_MD_CTX_create());
int ret = EVP_DigestInit_ex(_mdctx, EVP_sha512(), eng);
EVP_MD_CTX_destroy(_mdctx);
if(1 == ret) {
std::cout << "Finished successfully (with eng=" << eng << ")" << std::endl;
return;
} else {
std::array<char, 256> err_str;
ERR_error_string_n(ERR_get_error(), err_str.data(), err_str.size());
std::cout << "Error at Digest (engine: " << ENGINE_get_id(eng) << "): " << err_str.data() << std::endl;
}
}
int main(void) {
ENGINE_load_builtin_engines();
hash(nullptr);
for(ENGINE *eng = ENGINE_get_first(); eng != nullptr; eng = ENGINE_get_next(eng)) {
hash(eng);
}
}
I get the following output:
Finished successfully (with eng=0)
Error at Digest (engine: rdrand): error:260BA093:engine routines:ENGINE_get_digest:unimplemented digest
Error at Digest (engine: dynamic): error:06080086:digital envelope routines:EVP_DigestInit_ex:initialization error
I understand, that rdrand doesn't support digest, but why do I get an initialization error, when I use the dynamic engine? In particular why does it work, when I call EVP_DigestInit_ex with eng=nullptr?
The code can be compiled with g++ example.cpp -std=c++17 -Wall -Wextra -Werror -pedantic -O2 -lssl -lcrypto. I am using g++, version 6.3.0 and openssl 1.1.0f.
I have next some project:
main.cpp
#include <iostream>
#include <cstddef>
#include <dlfcn.h>
int main()
{
void* handle = dlopen("./shared_libs/libshared.so", RTLD_LAZY);
if (NULL == handle)
{
std::cerr << "Cannot open library: " << dlerror() << '\n';
return -1;
}
typedef int (*foo_t)(const std::size_t);
foo_t foo = reinterpret_cast<foo_t>(dlsym(handle, "foo"));
const char* dlsym_error = dlerror();
if (dlsym_error)
{
std::cerr << "Cannot load symbol 'foo': " << dlsym_error << '\n';
dlclose(handle);
return -2;
}
std::cout << "call foo" << std::endl;
foo(10);
dlclose(handle);
return 0;
}
shared.cpp:
#include <cstddef>
#include <iostream>
extern "C"
{
int foo(const std::size_t size)
{
int b = size / size;
int* a = new int[size];
std::cout << "leaky code here" << std::endl;
}
}
and Makefile:
all:
g++ -fPIC -g -c shared.cpp
g++ -shared -o shared_libs/libshared.so -g shared.o
g++ -L shared_libs/ -g main.cpp -ldl
I use tcmalloc for debug this test program, which load dynamically libshared.so:foo and execute it.run command:
LD_PRELOAD=/usr/local/lib/libtcmalloc.so HEAPCHECK=normal ./a.out
The 1 largest leaks:
Using local file ./a.out.
Leak of 40 bytes in 1 objects allocated from:
# 7fe3460bd9ba 0x00007fe3460bd9ba
# 400b43 main
# 7fe346c33ec5 __libc_start_main
# 400999 _start
# 0 _init
Why I get address 0x00007fe3460bd9ba instead of line in foo function?
please help
P.s. I tried to use gdb with LD_PRELOAD=.../tcmalloc.so, but I get:
"Someone is ptrace()ing us; will turn itself off Turning perftools heap leak checking off"
Try removing dlclose call.
It's known issue that heap checker & profilers can't handle unloaded
shared objects.
Currently I test a shared library vendor provided in linux ,
the following is the simple source :
#include <iostream>
using namespace std;
extern int test1();
extern int test2();
int main()
{
cout << "hello world" << endl ;
return 0 ;
cout << "Test 1" << endl;
test1();
cout << "Test 2" << endl;
test2();
return 0;
}
I have compile and link like :
g++ -g -Wall -fPIC -D_DEBUG -o test -I./include32 src/xxx.cpp src/yyy.cpp src/test.cpp
-L./lib32 -lshare1 -lshared2
I have the following output while run :
hello world
***glibc detected *** ./test: double free or corrution (!prev) 0x00000000077ec30 ***
What I don't get is , since I only do print "hello world" and then return 0 ,
that mean I don't call any function in libshared1.so and libshared2.so ,
why error like glibc detected happen ? does it mean that shared library has
problem to be loaded to memory ? since the main function never call test1() , test2()
which really call functions in libshared1.so and libshared2.so !!
And suggestions , comments are most appreciated !!
Edit :
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
using namespace std;
int main()
{
cout << "hello world 3 " << endl ;
void *handle2;
handle2 = dlopen ("/usr/local/lib/xxx.so", RTLD_LAZY);
if (!handle2) {
fprintf (stderr, "%s\n", dlerror());
exit(1);
}
cout << "hello world 1 " << endl ;
void *handle3;
handle3 = dlopen ("/usr/local/lib/yyy.so", RTLD_LAZY);
if (!handle3) {
fprintf (stderr, "%s\n", dlerror());
exit(1);
}
cout << "hello world" << endl ;
}
Compile :
g++ -g -Wall -rdynamic -o test src/test.cpp -ldl
Output :
hello world 3
hello world 1
Segmentation fault (core dumped)
The Vendor really provide damaged shared library ?!
I need help! How to compile c++ mongo project in linux?
I'm doing this:
1) Install boost
2) Compile mongodb driver
3) Try to compile example (fail)
My compile mongodb drivers exist in /home/developer/documents/drivers/mongo-cxx-driver-v2.4/build
I'm trying to compile this file
#include <cstdlib>
#include <iostream>
#include "mongo/client/dbclient.h"
void run() {
mongo::DBClientConnection c;
c.connect("localhost");
}
int main() {
try {
run();
std::cout << "connected ok" << std::endl;
} catch( const mongo::DBException &e ) {
std::cout << "caught " << e.what() << std::endl;
}
return EXIT_SUCCESS;
}
And execute this command: g++ tutorial.cpp -pthread -lmongoclient -lboost_thread-mt -lboost_filesystem -lboost_program_options -lboost_system -o tutorial
This command fail. Error message - "mongo/client/dbclient.h" not found. How to compile this example? Help me, please!
You need to use -I and -L to specify where you have installed your mongo header(s) and library(ies):
g++ tutorial.cpp -I/path/to/mongo/include/ -pthread -L/path/to/libmongoclient
-lboost_thread-mt -lboost_filesystem -lboost_program_options
-lboost_system -o tutorial