Load shared lib in c++ causes segmentation fault - c++

I am learning c++, and am experimenting with loading a shared lib on linux (.so).
I get a segmentation fault when I run the below code.
When I try to run the console app using valgrind, I get the following:
valgrind ./TestLoadSo --leak-check=full -v
==26828== Memcheck, a memory error detector
==26828== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==26828== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==26828== Command: ./TestLoadSo --leak-check=full -v
==26828==
!!!Hello World!!!
==26828== Jump to the invalid address stated on the next line
==26828== at 0x0: ???
==26828== by 0x53E63F0: (below main) (libc-start.c:291)
==26828== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==26828==
==26828==
==26828== Process terminating with default action of signal 11 (SIGSEGV)
==26828== Bad permissions for mapped region at address 0x0
==26828== at 0x0: ???
==26828== by 0x53E63F0: (below main) (libc-start.c:291)
==26828==
==26828== HEAP SUMMARY:
==26828== in use at exit: 3,126 bytes in 9 blocks
==26828== total heap usage: 13 allocs, 4 frees, 76,998 bytes allocated
==26828==
==26828== LEAK SUMMARY:
==26828== definitely lost: 0 bytes in 0 blocks
==26828== indirectly lost: 0 bytes in 0 blocks
==26828== possibly lost: 0 bytes in 0 blocks
==26828== still reachable: 3,126 bytes in 9 blocks
==26828== suppressed: 0 bytes in 0 blocks
==26828== Rerun with --leak-check=full to see details of leaked memory
==26828==
==26828== For counts of detected and suppressed errors, rerun with: -v
==26828== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
[1] 26828 segmentation fault (core dumped) valgrind ./TestLoadSo --leak-check=full -v
C++ Main class
extern "C" typedef char* (*helloWorld_t)();
int main() {
void* handle = dlopen("./libMyLib.dll.so", RTLD_LAZY);
if (!handle) {
cerr << "Cannot open library: " << dlerror() << '\n';
return 1;
}
helloWorld_t hello = (helloWorld_t)dlsym( handle, "helloWorld" );
const char * tmp = hello();
printf("\n%s",tmp);
return 0;
}
The extern function is:
extern "C++" char* helloWorld() {
char str[25];
strcpy(str, "HelloWorld");
}
If I use extern "C" I get a compilation error:
error: conflicting declaration of ‘char* helloWorld()’ with ‘C’ linkage
extern "C" char* helloWorld() {
Its really not clear to me where I am going wrong.

A function cannot have both C and C++ linkage, and a function pointer type must match its target function's linkage.
You cannot dlsym an extern "C++" function by its unadorned name. You have to either use extern "C" in both cases (recommended), or use extern "C++" throughout and replace the string in dlsym(handle, "helloWorld") with the mangled name of your function (not recommended).
Always check the result of dlsym and report an error if it returns a null pointer (use dlerror() like you've done for dlopen).
Don't use character arrays or pointers to represent strings. There is a type for string, called std::string.
Last but not least, always compile with -Wall -Werror so things like a non-void function that doesn't actually return a value will be caught.

Many problems here:
extern "C++" char* helloWorld() {
char str[25];
strcpy(str, "HelloWorld");
}
It should use "C" linkage. And it should return something. And it copies the string to local variable, so value gets lost when it returns. So probably
extern "C" char* helloWorld() {
static char str[25]; // will keep its value accross calls, not thread safe
return strcpy(str, "HelloWorld"); // return pointer to start of str
}
Note that multiple calls all return same static buffer. If you need copies, you need to let caller provide a buffer, or return buffer allocated with malloc.

Related

Why isn't this program crashing? (shallow copy)

I am learning about copy constructor and shallow and deep copy. I was following this video: Copying and Copy Constructors in C++
The following code is copied directly from the video and demonstrates shallow copying... (at 9:30 in the video)
This code is supposed to crash after running because the deconstructor will try to deallocate the same memory twice (first for string and later for string2). The first deletion should work fine but the second one should cause the program to crash as we are trying to delete unallocated memory.
Surprisingly, this doesn't happen in my case. I complied code in my command prompt using g++ copying_and_copy_constructor.cpp and it compiled fine and ran it using a.exe. No errors.
#include<iostream>
#include<cstring>
#include<string>
using std::endl;
using std::cout;
class String
{
private:
char* m_Buffer;
unsigned int m_size;
public:
String(const char* string)
{
m_size = strlen(string);
m_Buffer = new char[m_size+1];
memcpy(m_Buffer,string,m_size);
m_Buffer[m_size] = 0;
}
~String()
{
delete [] m_Buffer;
}
friend std::ostream& operator << (std::ostream& stream, const String& string);
};
std::ostream& operator<<(std::ostream& stream, const String& string)
{
stream<< string.m_Buffer;
return stream;
}
int main()
{
String string = "My string";
String string2 = string;
cout<<string2<<endl;
cout<<string;
return 0;
}
I even tried checking in the debugger. I compiled the code using g++ -g copying_and_copy_constructor.cpp and then gdb a.exe. Here is the output of that:
GNU gdb (GDB) 7.6.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from D:\a.exe...done.
(gdb) start
Temporary breakpoint 1 at 0x401446: file copying_and_copy_constructor.cpp, line 43.
Starting program: D:\a.exe
[New Thread 44892.0x8258]
[New Thread 44892.0x6df8]
[New Thread 44892.0xadd8]
[New Thread 44892.0x9658]
Temporary breakpoint 1, main () at copying_and_copy_constructor.cpp:43
43 String string = "My string";
(gdb) c
Continuing.
My string
My string[Inferior 1 (process 44892) exited normally]
(gdb)
The program is not being run.
(gdb) q
This line confuses me My string[Inferior 1 (process 44892) exited normally]. How is this code is exiting normally?
The person in the video is using VS-Code... How can I get the same error in the command prompt?
Crash as shown in the video:
(I don't have vs code as of now (might install it later))
For me (Fedora 32 x86_64) it does crash:
$ g++ -o q q.C -Wall -g;./q
My string
free(): double free detected in tcache 2
Aborted
But I definitely agree such code may look running fine. This is why there is ASAN:
$ g++ -o q q.C -Wall -g -fsanitize=address;./q
My string
=================================================================
==3388436==ERROR: AddressSanitizer: attempting double-free on 0x602000000010 in thread T0:
#0 0x7fb76f262cd7 in operator delete[](void*) (/lib64/libasan.so.6+0xb2cd7)
#1 0x4016e9 in String::~String() /home/jkratoch/t/q.C:25
#2 0x40144b in main /home/jkratoch/t/q.C:42
#3 0x7fb76ecbc041 in __libc_start_main ../csu/libc-start.c:308
#4 0x40120d in _start (/quad/home/jkratoch/t/q+0x40120d)
0x602000000010 is located 0 bytes inside of 10-byte region [0x602000000010,0x60200000001a)
freed by thread T0 here:
#0 0x7fb76f262cd7 in operator delete[](void*) (/lib64/libasan.so.6+0xb2cd7)
#1 0x4016e9 in String::~String() /home/jkratoch/t/q.C:25
#2 0x40143e in main /home/jkratoch/t/q.C:43
#3 0x7fb76ecbc041 in __libc_start_main ../csu/libc-start.c:308
previously allocated by thread T0 here:
#0 0x7fb76f2621d7 in operator new[](unsigned long) (/lib64/libasan.so.6+0xb21d7)
#1 0x4015d6 in String::String(char const*) /home/jkratoch/t/q.C:18
#2 0x4013a0 in main /home/jkratoch/t/q.C:42
#3 0x7fb76ecbc041 in __libc_start_main ../csu/libc-start.c:308
SUMMARY: AddressSanitizer: double-free (/lib64/libasan.so.6+0xb2cd7) in operator delete[](void*)
==3388436==ABORTING
In the case you do not want or even cannot recompile the program with -fsanitize=address you can use Valgrind (but it is slower and it does not detect everything):
$ g++ -o q q.C -Wall -g;valgrind ./q
==3388447== Memcheck, a memory error detector
==3388447== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3388447== Using Valgrind-3.16.0 and LibVEX; rerun with -h for copyright info
==3388447== Command: ./q
==3388447==
My string
==3388447== Invalid free() / delete / delete[] / realloc()
==3388447== at 0x483C59C: operator delete[](void*) (vg_replace_malloc.c:649)
==3388447== by 0x40139E: String::~String() (q.C:25)
==3388447== by 0x401277: main (q.C:42)
==3388447== Address 0x4db5c80 is 0 bytes inside a block of size 10 free'd
==3388447== at 0x483C59C: operator delete[](void*) (vg_replace_malloc.c:649)
==3388447== by 0x40139E: String::~String() (q.C:25)
==3388447== by 0x40126B: main (q.C:43)
==3388447== Block was alloc'd at
==3388447== at 0x483B582: operator new[](unsigned long) (vg_replace_malloc.c:431)
==3388447== by 0x401334: String::String(char const*) (q.C:18)
==3388447== by 0x40121B: main (q.C:42)
==3388447==
My string==3388447==
==3388447== HEAP SUMMARY:
==3388447== in use at exit: 0 bytes in 0 blocks
==3388447== total heap usage: 3 allocs, 4 frees, 73,738 bytes allocated
==3388447==
==3388447== All heap blocks were freed -- no leaks are possible
==3388447==
==3388447== For lists of detected and suppressed errors, rerun with: -s
==3388447== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Memory leak while handling exceptions

I just move to C++ from C, and currently slicing my path through exceptions.
I'm having a hard time figuring out why am I getting a memory leak in this simple program:
#include <iostream> /* I/O */
#include <exception> /* exception */
#include <cstdlib> /* stdlib */
using namespace std;
void Bar()
{
throw exception();
}
void Foo()
{
int *ip = new int;
try
{
Bar();
}
catch(exception &e)
{
cerr << "Foo: Exception caught: " << e.what() << endl;
delete ip;
exit(1);
}
delete ip;
}
int main()
{
Foo();
return 0;
}
I feel like I'm missing something crucial here, but can't point at it. Any idea?
Valgrind's output:
==21857== Memcheck, a memory error detector
==21857== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==21857== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==21857== Command: ./a.out
==21857==
Foo: Exception caught: std::exception
==21857==
==21857== HEAP SUMMARY:
==21857== in use at exit: 136 bytes in 1 blocks
==21857== total heap usage: 3 allocs, 2 frees, 72,844 bytes allocated
==21857==
==21857== 136 bytes in 1 blocks are possibly lost in loss record 1 of 1
==21857== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21857== by 0x4ECD8FF: __cxa_allocate_exception (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==21857== by 0x108CCC: Bar() (ex33.cpp:9)
==21857== by 0x108D0C: Foo() (ex33.cpp:18)
==21857== by 0x108DBD: main (ex33.cpp:31)
==21857==
==21857== LEAK SUMMARY:
==21857== definitely lost: 0 bytes in 0 blocks
==21857== indirectly lost: 0 bytes in 0 blocks
==21857== possibly lost: 136 bytes in 1 blocks
==21857== still reachable: 0 bytes in 0 blocks
==21857== suppressed: 0 bytes in 0 blocks
==21857==
==21857== For counts of detected and suppressed errors, rerun with: -v
==21857== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
You should't call exit in C++ really. Local objects destructors will not be called. And cause stack will not be unwounded, looks like destructor of exception also will not be called.
From standard:
18.1.2 When an exception is thrown, control is transferred to the nearest handler with a matching type (18.3); “nearest” means the
handler for which the compound-statement or ctor-initializer following
the try keyword was most recently entered by the thread of control and
not yet exited
18.1.3 Throwing an exception copy-initializes (11.6, 15.8) a temporary object, called the exception object. An lvalue denoting the temporary
is used to initialize the variable declared in the matching handler
(18.3). If the type of the exception object would be an incomplete
type or a pointer to an incomplete type other than cv void the program
is ill-formed.
Stack is not unwound: destructors of variables with automatic storage duration are not called. Quote from here
As it turned out, replacing exit(1) from within Foo() to return; fixed the memory leak.
So, my follow-up question, why can't I call exit() from Foo()?

Valgrind tool for GDB

int main()
{
char *p;
p = malloc(10);
delete(p);
return;
}
what will be appropriate error detected by Valgrind?
First of all this code snippet gives two compilation errors,
In function ‘int main()’:
error: invalid conversion from ‘void*’ to ‘char*’ [-fpermissive]
p = malloc(10);
^
error: return-statement with no value, in function returning ‘int’ [- fpermissive]
return;
Correct the code with these changes,
Type cast while allocating memory using malloc, as shown here.
p = (char*) malloc(10);
The return type of main function is int, so change the return value accordingly, as mentioned here.
return 0; // Use return 0, instead of just return.
Before using delete operation, do a validity check on the pointer, as shown here.
if(p)
delete(p);
With the above changes, and upon successful compilation of the above code. Use the valgrind tool to run the above sample.
As such there is no issue in the code, so valgrind did not find any issue. Below is sample valgrind output.
Valgrind output:
==30050== Memcheck, a memory error detector
==30050== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==30050== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==30050== Command: ./valgrindtest
==30050==
main Start
==30050== Mismatched free() / delete / delete []
==30050== at 0x4C2C18D: operator delete(void*) (vg_replace_malloc.c:576)
==30050== by 0x4006E0: main (valgrindtest.cpp:16)
==30050== Address 0x5a1b040 is 0 bytes inside a block of size 10 alloc'd
==30050== at 0x4C2ABE3: malloc (vg_replace_malloc.c:299)
==30050== by 0x4006C2: main (valgrindtest.cpp:11)
==30050==
main End
==30050==
==30050== HEAP SUMMARY:
==30050== in use at exit: 0 bytes in 0 blocks
==30050== total heap usage: 1 allocs, 1 frees, 10 bytes allocated
==30050==
==30050== All heap blocks were freed -- no leaks are possible
==30050==
==30050== For counts of detected and suppressed errors, rerun with: -v
==30050== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Cannot find memory leak detected by Valgrind

I'm running and analyzing with Valgrind this code:
int main() {
Set<int> c;
return 0;
}
So the output is:
jscherman#jscherman:~/ClionProjects/algo2-t3-bts$ g++ set.hpp tests.cpp && valgrind --leak-check=yes --show-leak-kinds=all ./a.out
==3528== Memcheck, a memory error detector
==3528== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==3528== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==3528== Command: ./a.out
==3528==
test_mleak...ok
==3528==
==3528== HEAP SUMMARY:
==3528== in use at exit: 72,704 bytes in 1 blocks
==3528== total heap usage: 2 allocs, 1 frees, 73,728 bytes allocated
==3528==
==3528== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==3528== at 0x4C2DC10: malloc (vg_replace_malloc.c:299)
==3528== by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==3528== by 0x40104E9: call_init.part.0 (dl-init.c:72)
==3528== by 0x40105FA: call_init (dl-init.c:30)
==3528== by 0x40105FA: _dl_init (dl-init.c:120)
==3528== by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==3528==
==3528== LEAK SUMMARY:
==3528== definitely lost: 0 bytes in 0 blocks
==3528== indirectly lost: 0 bytes in 0 blocks
==3528== possibly lost: 0 bytes in 0 blocks
==3528== still reachable: 72,704 bytes in 1 blocks
==3528== suppressed: 0 bytes in 0 blocks
==3528==
==3528== For counts of detected and suppressed errors, rerun with: -v
==3528== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Apparently, i'm loosing memory at the constructor of Set, but i can't find the actual reason. This is how i implemented Set (in a BTS):
template<class T>
class Set {
public:
Set() : root_(NULL), cardinal_(0) {}
~Set() {delete root_;}
void insert(const T &);
bool belongs(const T &) const;
void remove(const T &);
const T &min() const;
const T &max() const;
unsigned int cardinal() const;
private:
struct Node {
Node(const T &v) : value(v), left(NULL), right(NULL) {}
~Node() {delete right; delete left;}
T value;
Node *left;
Node *right;
};
Node *root_;
int cardinal_;
}
Any idea how to solve this leak? Thanks!
You're not leaking anything--you're just misunderstanding what valgrind is telling you.
It thinks there may be some problem underneath _dl_init(), but this is a red herring. You can safely add it to your valgrind suppressions file (which is always a good thing to have, so you aren't bothered by false alarms from system libraries).

Segmentation fault issue during creation new thread using activemq-cpp library

My environment is opensuse, gcc5, clion, active-mq 3.10.0.
Am my missing something? I got Segmentation fault after launch program.
class MyTask : public CompositeTask{
public:
MyTask() { }
public:
virtual bool isPending() const override {
cout<<"MyTask()::isPending\n";
return true;
}
virtual bool iterate() override {
cout<<"MyTask()::iterate\n";
return false;
}
};
class RR{
CompositeTaskRunner compositeTaskRunner;
public:
RR(){
CompositeTask* m = new MyTask();
compositeTaskRunner.addTask(m);
}
void start(){
compositeTaskRunner.start();
}
};
main(){
RR* runner = new RR();
runner->start();
}
output from valgrind
==12202== Memcheck, a memory error detector
==12202== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==12202== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==12202== Command: ./CppMicroServicesExampleDriver
==12202== Parent PID: 9602
==12202==
==12202== Invalid read of size 8
==12202== at 0x5BDCD29: createThreadInstance (Threading.cpp:365)
==12202== by 0x5BDCD29: decaf::internal::util::concurrent::Threading::createNewThread(decaf::lang::Thread*, char const*, long long) (Threading.cpp:920)
==12202== by 0x5C21BB3: decaf::lang::Thread::initializeSelf(decaf::lang::Runnable*, std::string const&, long long) (Thread.cpp:123)
==12202== by 0x5C21F7A: decaf::lang::Thread::Thread(decaf::lang::Runnable*, std::string const&) (Thread.cpp:102)
==12202== by 0x5A5AC36: activemq::threads::CompositeTaskRunner::CompositeTaskRunner() (CompositeTaskRunner.cpp:70)
==12202== by 0x40F5E1: RR::RR() (nano.hpp:32)
==12202== by 0x40BEAD: main (main.cpp:56)
==12202== Address 0x60 is not stack'd, malloc'd or (recently) free'd
==12202==
==12202==
==12202== Process terminating with default action of signal 11 (SIGSEGV)
==12202== Access not within mapped region at address 0x60
==12202== at 0x5BDCD29: createThreadInstance (Threading.cpp:365)
==12202== by 0x5BDCD29: decaf::internal::util::concurrent::Threading::createNewThread(decaf::lang::Thread*, char const*, long long) (Threading.cpp:920)
==12202== by 0x5C21BB3: decaf::lang::Thread::initializeSelf(decaf::lang::Runnable*, std::string const&, long long) (Thread.cpp:123)
==12202== by 0x5C21F7A: decaf::lang::Thread::Thread(decaf::lang::Runnable*, std::string const&) (Thread.cpp:102)
==12202== by 0x5A5AC36: activemq::threads::CompositeTaskRunner::CompositeTaskRunner() (CompositeTaskRunner.cpp:70)
==12202== by 0x40F5E1: RR::RR() (nano.hpp:32)
==12202== by 0x40BEAD: main (main.cpp:56)
==12202== If you believe this happened as a result of a stack
==12202== overflow in your program's main thread (unlikely but
==12202== possible), you can try to increase the size of the
==12202== main thread stack using the --main-stacksize= flag.
==12202== The main thread stack size used in this run was 8388608.
==12202==
==12202== HEAP SUMMARY:
==12202== in use at exit: 126,122 bytes in 577 blocks
==12202== total heap usage: 1,031 allocs, 454 frees, 152,249 bytes allocated
==12202==
==12202== LEAK SUMMARY:
==12202== definitely lost: 0 bytes in 0 blocks
==12202== indirectly lost: 0 bytes in 0 blocks
==12202== possibly lost: 0 bytes in 0 blocks
==12202== still reachable: 126,122 bytes in 577 blocks
==12202== of which reachable via heuristic:
==12202== stdstring : 15,204 bytes in 453 blocks
==12202== suppressed: 0 bytes in 0 blocks
==12202== Rerun with --leak-check=full to see details of leaked memory
==12202==
==12202== For counts of detected and suppressed errors, rerun with: -v
==12202== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Before using the library you must call its initialization method in order to prepare all the internal constructs necessary to manage the resources.
activemq::library::ActiveMQCPP::initializeLibrary();