segfault using SWIG converted code for tcl - c++

I'm having a segmentation fault with my program.
In fact I write a library in C++ and convert it for tcl using SWIG.
The segfault occurs here:
return Tcl_NewIntObj(static_cast< int >(value));
where value=0
the gdb back trace shows:
(gdb) bt
#0 0x000054b6 in ?? ()
#1 0xb6650d5d in SWIG_From_long (value=0) at mntdisplay_wrap.cc:1712
#2 SWIG_From_int (value=0) at mntdisplay_wrap.cc:1722
#3 Testguimnt_Init (interp=0x9714e28) at mntdisplay_wrap.cc:3774
#4 0xb76748fe in Tcl_LoadObjCmd () from /opt/ActiveTcl-8.6/lib/libtcl8.6.so
#5 0xb75d02af in TclNREvalObjv () from /opt/ActiveTcl-8.6/lib/libtcl8.6.so
#6 0xb75d0859 in Tcl_EvalObjv () from /opt/ActiveTcl-8.6/lib/libtcl8.6.so
#7 0xb75d0d99 in TclEvalEx () from /opt/ActiveTcl-8.6/lib/libtcl8.6.so
#8 0xb7670045 in Tcl_FSEvalFileEx () from /opt/ActiveTcl-8.6/lib/libtcl8.6.so
#9 0xb767645f in Tcl_MainEx () from /opt/ActiveTcl-8.6/lib/libtcl8.6.so
#10 0x0804885c in main ()
In the wrapper:
line 1712:
SWIGINTERNINLINE Tcl_Obj*
SWIG_From_long (long value)
{
if (((long) INT_MIN <= value) && (value <= (long) INT_MAX)) {
return Tcl_NewIntObj(static_cast< int >(value)); //1712
} else {
return Tcl_NewLongObj(value);
}
}
1722:
SWIGINTERNINLINE Tcl_Obj *
SWIG_From_int (int value)
{
return SWIG_From_long (value); //1722
}
3774:
SWIG_Tcl_SetConstantObj(interp, "MESSAGE_NEW", SWIG_From_int(static_cast< int >(MESSAGE_NEW)));
where MESSAGE_NEW is defined in a enum and is 0.
Please, if you have any idea, please help me. Thank you!
EDIT:
I found the cause of the problem: it's an linking error.
I created a new thread for this issue:
C++: linked library disappears and gives segfault during execution

I found the problem.
Please see my other post:
C++: linked library disappears and gives segfault during execution
There was an undefined symbol of my library. I defined it and problem solved!
The confusion was, my program crashed in the middle of tcl wrapper functions (where my undefined symbol was not involved at all). I don't really know why but that's it..
Hope it will help others!

Related

curl crash on linux C++

I have coded a program that works fine on windows, then I had to use it on linux so I coded the needed things for it to work on linux. What I mainly changed was the thread creation function ;
void thread_create(void *(*threadfunc)(void *), void *u)//linux
{
#ifdef linux
pthread_t id;
pthread_create(&id, NULL, threadfunc, u);
#endif
}
void thread_create(void (*threadfunc)(void *), void *u)//windows
{
#ifndef linux
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadfunc, u, 0, NULL);
#endif
}
The program has a lot of threads. I used gdb to see where it crashes, and the crash always occures at the curl_easy_perform function. Note that I am using this function a lot of times before where I know it will crash, the program never crashes before that point. When I am using them before that point, I'm not sending any data with POST/GET methods, I'm only getting informations from pages without sending any data.
So gdb always tells me :
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffdf65c700 (LWP 26488)]
0x00007ffff6fb0360 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0 0x00007ffff6fb0360 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00000000004a1e70 in readmoredata ()
#2 0x00000000004b33d7 in Curl_fillreadbuffer ()
#3 0x00000000004b40fc in Curl_readwrite ()
#4 0x000000000049b3bc in multi_runsingle ()
#5 0x000000000049c275 in curl_multi_perform ()
#6 0x00000000004972c3 in curl_easy_perform ()
I would like to give you something you can make tests on, but I really can't. The program has thousands of lines.

How do I get more information about that error?

An Qt application is crashing and even debugger mode it's all I get:
ASSERT: "!isEmpty()" in file
C:\Qt\Qt5.5.0\5.5\mingw492_32\include\QtCore/qlist.h, line 321
That line in the file points to:
inline void removeLast() { Q_ASSERT(!isEmpty()); erase(--end()); }
But I'd like more information. Like what line exactly in the source code is using it (from search, no direct call to removeLast() done).
Is this possible?
If you run your program in a debugger, it will stop on the assertion and you'll be able to examine the stack trace. For example with this program in GDB :
#include <QList>
int main(int argc,char* argv[])
{
QList<int> my_list;
my_list.append(1);
my_list.pop_back(); // 1
my_list.pop_back(); // 2
return 0;
}
When you run it :
(gdb) r
Starting program: /home/leiaz/tmp/qttest/build/proj
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
ASSERT: "!isEmpty()" in file /usr/include/qt/QtCore/qlist.h, line 321
Program received signal SIGABRT, Aborted.
0x00007ffff61275f8 in raise () from /usr/lib/libc.so.6
The assertion stop the debugger, and you can ask for the stack trace :
(gdb) backtrace
#0 0x00007ffff61275f8 in raise () from /usr/lib/libc.so.6
#1 0x00007ffff6128a7a in abort () from /usr/lib/libc.so.6
#2 0x00007ffff6dc11e1 in QMessageLogger::fatal(char const*, ...) const () from /usr/lib/libQt5Core.so.5
#3 0x00007ffff6dbc34e in qt_assert(char const*, char const*, int) () from /usr/lib/libQt5Core.so.5
#4 0x00000000004060aa in QList<int>::removeLast (this=0x7fffffffe4d0)
at /usr/include/qt/QtCore/qlist.h:321
#5 0x0000000000405de0 in QList<int>::pop_back (this=0x7fffffffe4d0)
at /usr/include/qt/QtCore/qlist.h:337
#6 0x0000000000405ad4 in main (argc=1, argv=0x7fffffffe5d8) at /home/leiaz/tmp/qttest/main.cc:9
You can see removeLast was called by pop_back and my code start at frame 6 :
(gdb) frame 6
#6 0x0000000000405ad4 in main (argc=1, argv=0x7fffffffe5d8) at /home/leiaz/tmp/qttest/main.cc:9
9 my_list.pop_back(); // 2
Here you can examine the values of other variables in that frame.
If you are using Qt Creator see Viewing Call Stack Trace.
Like what line exactly in the source code is using it (from search, no direct call to removeLast() done). Is this possible?
Unfortunately assert() or Q_ASSERT() macros just show that the conditions were wrong, not which code was causing these conditions.
Especially if called many times and/or from many places, assertions aren't very helpful to detect what code actually was causing it.
You can set a conditional breakpoint for the isEmpty() condition, if that's well supported with your debugger.
You can also set a breakpoint in the standard abort() function, if you have access to the debug symbols.
If there's not, and if you have full access to the source code (which you have for a function inlined in a header) you can work around that deficiency. The way I'm usually going, is to change such code temporarily to
void removeLast()
{
if(isEmpty()) { // <<<<<<<<<<< Put an encapsulating if clause here
return; // <<<<<<<<<<<< set breakpoint
}
Q_ASSERT(!isEmpty()); erase(--end());
}
and set a debugger breakpoint. When the breakpoint is hit while running the code from the debugger, I'll examine the call stack to see where this came from.

same piece of C++ code works in g++ 4.6 compiler but crashes with 5.1

The following piece of code works with g++ 4.6 compiler but crashes with segmentation fault when compiled with g++ 5.1 compiler. The variable access gString is causing the segmentation fault.
#define _GLIBCXX_DEBUG 1
#define _GLIBCXX_USE_CXX11_ABI 0
#include<string>
#include<iostream>
#include<vector>
static std::string gString("hello");
static void
__attribute__((constructor))
initialize()
{
gString.assign("hello world");
return;
}
static void
__attribute__((destructor))
finalize()
{
return;
}
int main(int ac, char **av)
{
//std::cerr<<gString;
return 0;
}
GDB output:
Reading symbols from /home/rk/str...done.
(gdb) b initialize
Breakpoint 1 at 0x401419: file str.cc, line 15.
(gdb) r
Starting program: /home/rk/str
Breakpoint 1, initialize() () at str.cc:15
15 gString.assign("hello world");
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x00000000004018d6 in std::string::size() const () at /usr/include/c++/5/bits/basic_string.h:3118
3118 { return _M_rep()->_M_length; }
(gdb) bt
#0 0x00000000004018d6 in std::string::size() const () at /usr/include/c++/5/bits/basic_string.h:3118
#1 0x00000000004016ff in std::string::assign(char const*, unsigned long) () at /usr/include/c++/5/bits/basic_string.tcc:706
#2 0x000000000040166e in std::string::assign(char const*) () at /usr/include/c++/5/bits/basic_string.h:3542
#3 0x0000000000401428 in initialize() () at str.cc:15
#4 0x00000000004023dd in __libc_csu_init ()
#5 0x00007ffff71ad700 in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
#6 0x0000000000401289 in _start ()
Why are you using __attribute__((constructor)) in C++ instead of simply a global object with a constructor? Those attributes are useful in C code, but redundant in C++.
The problem is that your constructor runs before the standard iostreams have been initialized, which would not be a problem if you used a global object with a constructor.
You could try adding a priority to your constructor, but I don't think it will help in this case:
__attribute__((constructor(999)))
The runtime error also happens with gcc 4.9.2 (see ideone example).
The problem is related to the iostreams which are not yet initialized. Commenting out the cerr line, and everything works fine
Apparently, it's a known issue.
Edit: Additional remarks
This small workaround seems to work, at least with 4.9: use c stdio instead of iostreams:
fprintf(stderr, "_initialize"); // this works
But I fully agree with Jonathan's suggestion of using a global (singleton ?) object relying solely on well defined standard C++ behaviour, unless you really need the constructor being run exactly at the moment of a dynamic library load.

Throwing from a C++ function called from a C function via pointer dereference

Consider the following function defined in a C library:
void f(void (*callback)(int)) { callback(0); }
which will be called from a C++11 program defining callback(), possibly throwing an exception, as below:
void callback(int) { /* can I throw ? */}
try {
f(callback);
} catch (...) {
/* can the exception be caught ? */
}
My questions are:
does the standard allows the callback to throw when called from f()? If not, must/should I declare callback() with the noexcept specifier?
If yes, does the standard allows to catch the exception object being thrown?
Below source code can be compliled.
exception.cpp:
extern "C"
void throwInCPP() {
throw 5;
}
main.c
#include <stdio.h>
void throwInCPP();
void throwExp(void (*callback)()) {
callback();
}
int main() {
throwExp(throwInCPP);
return 0;
}
When when it gets ran, exception will be thrown and the program unwind the stack try to find a catch block but it cannot. Then abort happens:
#0 0x00007ffff7238d67 in raise () from /usr/lib/libc.so.6
#1 0x00007ffff723a118 in abort () from /usr/lib/libc.so.6
#2 0x00007ffff7b2e1f5 in __gnu_cxx::__verbose_terminate_handler() ()
from /usr/lib/libstdc++.so.6
#3 0x00007ffff7b2c076 in ?? () from /usr/lib/libstdc++.so.6
#4 0x00007ffff7b2c0c1 in std::terminate() () from /usr/lib/libstdc++.so.6
#5 0x00007ffff7b2c2d8 in __cxa_throw () from /usr/lib/libstdc++.so.6
#6 0x00000000004007fa in throwInCPP ()
#7 0x00000000004007bd in throwExp (callback=0x4007d4 <throwInCPP>) at main.c:6
#8 0x00000000004007cd in main () at main.c:11
I think you can always call a cpp function which throws an expection in c, but you can never put a catch block in c since it doesn't compile.
How is the C++ exception handling runtime implemented? This explains how does the exception work in c++.
I don't really think throw exception in c will be something good since you cannot do anything with it in the "normal" way.

segmentation fault while using dynamically allocated object in shared lib loaded at runtime

I have static library linked to executable file. Executable file itself don't use library symbols. But this executable loads some shared libraries at runtime, one of which uses symbols from library. Below is very simplified version of library source files.
ParentClass.h
#include <iostream>
using namespace std;
class ParentClass {
ParentClass() {}
// some functionality
};
ChildClass.h
#include <ParentClass.h>
struct StaticData {
static const char *staticString;
};
class ChildClass : public ParentClass, public StaticData {
ChildClass() {}
// some extended functionality here
};
ChildClass.cpp
#include "ChildClass.h"
const char * StaticData::staticString = "string";
// functionality implementation
Here is several facts:
1.code like this:
ChildClass test;
//extended use of test functionality
works quite well.
2.code like this:
ChieldClass *test = new ChieldClass();
test->some_func(); // some func don't use dynamic memory
test->some_other_func(); // dynamic memory used (in my case malloc in gethostbyname system function)
works quite well when used in binary directly linked with library, but fails with segfault "path_to_exec malloc(): memory corruption: some_address" when used in shared library loaded in runtime (see description in the beginning).
3.code like this:
ParentClass *test = new ParentClass();
test->some_func();
test->some_other_func();
Works well everywhere.
I'm having trouble understanding why code in item 2 causes segmentation fault, but I am suspecting that trouble is in the use of static data in ChildClass (besides that difference ChildClass only defines some new functions with extended functionality that uses ParenClass functions. Segmentation fault occures even when I am using not overloaded ParentClass functions). But I can't link this single difference with the fact that segnemtation fault occures only while using ChildClass in shared library dynamically loaded to executable my library was linked with.
I'l be glad to hear any ideas to get rid of this seg fault.
Update: bt when using logger function with std::cout (some names are omitted). Call sequence:
ChildClass *test = new ChildClass();
test->printInfo();
test->connect();
connect fnction isn't redefined in ChildClass.
(gdb) bt
#0 0x00007f756f67e165 in raise () from /lib/libc.so.6
#1 0x00007f756f680f70 in abort () from /lib/libc.so.6
#2 0x00007f756f6b427b in ?? () from /lib/libc.so.6
#3 0x00007f756f6bdad6 in ?? () from /lib/libc.so.6
#4 0x00007f756f6c0b6d in ?? () from /lib/libc.so.6
#5 0x00007f756f6c2930 in malloc () from /lib/libc.so.6
#6 0x00007f756f6af35b in ?? () from /lib/libc.so.6
#7 0x00007f756f7291de in ?? () from /lib/libc.so.6
#8 0x00007f756f72aa65 in __res_maybe_init () from /lib/libc.so.6
#9 0x00007f756f72ca70 in __nss_hostname_digits_dots () from /lib/libc.so.6
#10 0x00007f756f731fe4 in gethostbyname_r () from /lib/libc.so.6
#11 0x0000000000507929 in underlaying_c_code_connect (client=0x7f7564017348) at /home/beduin/???/lib/???/UnderlayingCCode.cpp:1477
#12 0x0000000000504a24 in ParentClass::connect (this=0x7f7564017340) at /home/beduin/???/lib/???/ParentClass.cpp:216
#13 0x00007f7569342f68 in Plugin::Start (this=0x7f75640208c0) at /home/beduin/???/plugins/???/Plugin.cpp:84
#14 0x00000000004c7d45 in ???::PluginHolder::StartPlugin (this=0x7fffed7dc5e0, it=#0x7fffed7dbad0) at /home/beduin/???/plugins.cpp:317
#15 0x00000000004c8656 in ???::PluginHolder::Start (this=0x7fffed7dc5e0) at /home/beduin/mrvs/framework/base/plugins.cpp:401
#16 0x00000000004c7935 in ???::PluginHolder::LockNLoad (this=0x7fffed7dc5e0) at /home/beduin/???/plugins.cpp:284
#17 0x00000000004afe6f in main (argc=3, argv=0x7fffed7dd978) at /home/beduin/???/main.cpp:148
Using custom logger:
#0 0x00007f824aa12165 in raise () from /lib/libc.so.6
#1 0x00007f824aa14f70 in abort () from /lib/libc.so.6
#2 0x00007f824aa4827b in ?? () from /lib/libc.so.6
#3 0x00007f824aa51ad6 in ?? () from /lib/libc.so.6
#4 0x00007f824aa54b6d in ?? () from /lib/libc.so.6
#5 0x00007f824aa56930 in malloc () from /lib/libc.so.6
#6 0x00007f824b2a46bd in operator new () from /usr/lib/libstdc++.so.6
#7 0x00007f824b280b29 in std::string::_Rep::_S_create () from /usr/lib/libstdc++.so.6
#8 0x00007f824b281aeb in std::string::_Rep::_M_clone () from /usr/lib/libstdc++.so.6
#9 0x00007f824b28205c in std::string::reserve () from /usr/lib/libstdc++.so.6
#10 0x00007f824b27c021 in std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::overflow () from /usr/lib/libstdc++.so.6
#11 0x00007f824b280215 in std::basic_streambuf<char, std::char_traits<char> >::xsputn () from /usr/lib/libstdc++.so.6
#12 0x00007f824b2763b5 in std::__ostream_insert<char, std::char_traits<char> > () from /usr/lib/libstdc++.so.6
#13 0x00007f824b27662f in std::operator<< <std::char_traits<char> > () from /usr/lib/libstdc++.so.6
#14 0x00000000004f4fb0 in ???::Logger::LogWriter::operator<< <char [25]> (this=0x7fff8e241fc0, str=#0x52b2fd)
at /home/beduin/???/log:184
#15 0x0000000000500388 in ChildClass::printInfo (this=0x7f8240017470) at /home/beduin/???/ChildClass.cpp:480
#16 0x00007f82446d6f5c in Plugin::Start (this=0x7f82400208a0) at /home/beduin/???/plugins/???/Plugin.cpp:83
#17 0x00000000004c7d35 in ???::PluginHolder::StartPlugin (this=0x7fff8e243b30, it=#0x7fff8e243020) at /home/beduin/???/plugins.cpp:317
#18 0x00000000004c8646 in ???::PluginHolder::Start (this=0x7fff8e243b30) at /home/beduin/???/plugins.cpp:401
#19 0x00000000004c7925 in ???::PluginHolder::LockNLoad (this=0x7fff8e243b30) at /home/beduin/???/plugins.cpp:284
#20 0x00000000004afe5f in main (argc=3, argv=0x7fff8e244ec8) at /home/beduin/???/main.cpp:148
Run your program under valgrind (rather than gdb). It will show you the first place where invalid memory access occurs, which may be different from the place where the crash ultimately happens.
Regarding the fact that it's broken when linked as a shared library, are you using -fPIC or not? If not, try it.