I would like to trace a segmentation fault in my Rcpp code. To do so, I would like to implement a "main" C++ function and run my code with GDB. But I cannot make this main function work. Here is a minimal example:
#include <Rcpp.h>
int main (int argc, char** argv) {
Rcp::NumericVector i;
return 0;
};
I used the flags used by Rcpp to compile the code: g++ -I/usr/share/R/include -DNDEBUG -I"/home/login/R/x86_64-pc-linux-gnu-library/3.3/Rcpp/include" -fpic -g -ggdb -O0 -fdebug-prefix-map=/build/r-base-6WVosl/r-base-3.3.2=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -c main.cpp -o main.o
Then g++ -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o main main.o -L/usr/lib/R/lib -lR -g -ggdb -O0
(I have tried several flavours: removing fpic, -Wl.)
Running main gives me a segmentation fault.
GDB backtrace gives me
#0 0x00007ffff78f5ac5 in ?? () from /usr/lib/libR.so
#1 0x00007ffff78f6a17 in ?? () from /usr/lib/libR.so
#2 0x00007ffff78f70ad in Rf_allocVector3 () from /usr/lib/libR.so
#3 0x0000555555556856 in Rcpp::Vector<14, Rcpp::PreserveStorage>::Vector (this=0x7fffffffe1e0) at /home/login/R/x86_64-pc-linux-gnu-library/3.3/Rcpp/include/Rcpp/vector/Vector.h:58
#4 0x00005555555560ec in main (argc=1, argv=0x7fffffffe2f8) at main.cpp:7
Valgrind suggests Invalid read of size 8 at the same place.
Any suggestion would be welcome.
g++ is (Ubuntu 6.3.0-12ubuntu2) 6.3.0 20170406. Computer is Linux XXX 4.10.0-38-generic #42-Ubuntu SMP Tue Oct 10 13:24:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux.
You simply cannot use gdb on a main() for Rcpp code with an underlying R session: all R objects require R.
So either debug your package from R with gdb -- as described in Section 4.4 of Writing R Extensions or use RInside if you really think you need a main.
You can use gdb. Just not how you tried.
Related
I would like to debug shared library in Visual C++ Linux Development. Debugging executable file works well, but the breakpoint does not hit for shared library. How can I fix up?
Attached file is visual studio solution including .c and Makefile.
Example is very simple.
open shared library
read pointer of function in shared library
call the function.
Program works well. But Debugging shared library does not works. The breakpoint in main.c hits but the breakpoint in com.c does NOT hit.
/* main.c */
#include <stdio.h>
#include <dlfcn.h>
int main(int argc, char** argv)
{
void* dl_handle;
dl_handle = dlopen("../so/libcom.so.1", RTLD_LAZY);
if (!dl_handle) {
printf(" error : %s \n", dlerror());
return 0;
}
printf(" now call minicommon.h's function.. that is < void print_n(int n) >...\n");
void(*pFunc)(int);
pFunc = dlsym(dl_handle, "print_n");
(*pFunc)(18);
return 0;
}
/* com.c */
#include <stdio.h>
void print_n(int a)
{
printf("SO - print: [%d]\n", a);
}
/* Makefile for main.c */
all: main
main: main.o
gcc -W -Wall -gdwarf-2 -o main ../so/libcom.so.1 main.o -ldl
main.o: main.c
gcc -Wall -c -gdwarf-2 -o main.o main.c
clean:
rm -rf *.o main
/* Makefile for com.c */
all: libcom.so.1
libcom.so.1: com.o
gcc -shared -gdwarf-2 -o libcom.so.1 com.o
com.o: com.c
gcc -Wall -c -gdwarf-2 -o com.o com.c -fPIC
clean:
rm -rf *.o libcom.so.1
Before shared library is opened, can I debug it?
Environment
- Window 10
- CentOS 7 in VirtualBox
- Visual Studio 2015 update 3
- Visual C++ for linux Development 1.0.7
To be able to debug any binary (which includes shared libraries) you need the debugging symbols being available, either compiled into the binary itself, or as a separate file.
In most Linux distributions you can install the debugging symbols as separate package; Ubuntu for instance names these packages <packagename>-dbg. Check if these are available in your development environment, too.
I'm trying to compile Perl (any version) on a Linux RHEL 6.8 system. Whether I compile manually or use perlbrew, the result is the same. It dies when encountering the libgdbm.so.2.0.0 file.
Here is the tail of the transcript:
Checking your choice of C compiler and flags for coherency...
I've tried to compile and run the following simple program:
#include <stdio.h>
int main() { printf("Ok\n"); return(0); }
I used the command:
cc -o try -O2 -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -fstack-protector -L/usr/local/lib try.c -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lut
il -lc
./try
and I got the following output:
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../libgdbm.so when searching for -lgdbm
/usr/bin/ld: skipping incompatible /usr/lib/libgdbm.so when searching for -lgdbm
/usr/bin/ld: cannot find -lgdbm
collect2: ld returned 1 exit status
I can't compile the test program.
(The supplied flags or libraries might be incorrect.)
You have a BIG problem. Shall I abort Configure [y]
Ok. Stopping Configure.
Any ideas? I don't think that version of libgdbm is old.
This is the first that I noticed that my list of libraries includes both 64 bit and 32 (unmarked) versions. I eliminated the non-64 ones and now I'm compiling. Not sure if that is all of my issues, but that is it for this particular detail. – Cliff Warren
my program compiled and worked fine with:
g++ main.cpp exm1.cpp exm2.cpp -o main.o
i want to compile this app and run anywhere
how can i?
i try this code
g++ -g -Wall -I/MyApp/lib -static-libgcc -static-libstdc++ -static main.cpp exm1.cpp exm2.cpp -o main.o
but not work
in lib folder has 2 files:
exm1.h
exm2.h
main.cpp included:
#include <fstream>
#include <iostream>
#include <string>
#include <streambuf>
#include <stdlib.h>
#include "lib/exm1.h"
#include "lib/exm2.h"
my linux is kali, and i want run this app on CentOS 6
please help me,thanks
As C. bear said, use the -m32 flag so the program is able to run on 64- and 32- bit systems. In doing this, You'll also have to install the 32bit stdlibs. I'm not sure how to do this on kali, give it a google. Another thing you can do to avoid having users install external libraries (if you use them at any point) is to statically link you executable. Use the -static flag to do this. However, because all your app's dependencies (including the stdlibs) will be in a single file, it will get pretty big. On the other hand, loading times will be better, because your app doesn't have to run the dynamic linker and wait for it to link your external libraries as you call them.
So from comments one reason could be you executable is 64-bit and centOS a 32-bit sytem. Try compilation with -m32 flag.
how to compile g++ app and run anywhere?
It is not easily possible. For example, an ELF executable produced by GCC on a recent Debian/x86-64 computer won't run on a RaspberryPi (with a linux for ARM 32 bits, e.g. some Raspbian)
Read more about execve(2), elf(5) and about fat binaries
Be aware that the GCC compiler suite can be built (from its source code) as a cross-compiler (but you'll need to rebuild GCC for every different target system).
I recommend to invoke GCC as g++ -Wall -Wextra -g during the debugging phase (and use GDB). Once your software is debugged, compile it with g++ -Wall -Wextra -O2 to get an optimized binary (or even compile and link it with g++ -Wall -Wextra -O3 -flto)
I have just installed gcc 4.8.2 on Centos (I am using devtoolset-2). I wrote a very simple program using thread. It compiles fine but crashes when executed?
#include <thread>
#include <iostream>
void test()
{
std::cout << "test\n";
}
void main()
{
std::thread t(test);
t.join();
return 0;
}
I compile with:
scl enable devtoolset-2 bash
c++ -o test test.cpp -std=c++11
I am terribly surprised. I must do something wrong, not using the write libc++ etc? Do you have any idea how I could debug this. Thank you!
I compile it on Mac (Maverick) which obviously doesn't use gcc and it works fine.
On Linux, you should use the command line option -pthread with GCC and Clang for compiling and linking. In your case, the command line should look as follows:
g++ -std=c++11 -Wall -Wextra -pthread test.cpp -o test
See the following links for more information:
https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_concurrency.html
gcc - significance of -pthread flag when compiling
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52681
I have some trouble with the placement of the -l option when using gcc. Here's a stripped down version for reproduce the problem.
t.c:
#include <pthread.h>
int main() {
pthread_create(0, 0, 0, 0);
}
and in terminal:
$ gcc -lpthread t.c
/tmp/ccmkwV7B.o: In function `main':
t.c:(.text+0x29): undefined reference to `pthread_create'
collect2: ld returned 1 exit status
$ gcc t.c -lpthread
$ (compiles ok)
Why do I have to put -lpthread in the end to make it work? And it seems that this problem only occurs on 32bit linux.
My environment info is attached below:
gcc -lpthread t.c fails on this machine.
$ gcc --version
gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
$ uname -rm
3.0.0-12-generic i686
gcc -lpthread t.c works on this machine.
$ uname -rm
2.6.18-274.3.1.el5 x86_64
$ gcc --version
gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-51)
I looked up the gcc manual, and it says that "the placement of -l is significant". What exactly does it mean?
From the manual,
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.
This means it is very interesting that linking the library first works on gcc 4.1.2. This might have to do with the default libraries linked to by the compiler. I know on some installations I don't need to explicitly link to pthreads.
On further reflection, I think the issue is with the flag --as-needed, which may be on by default in your gcc 4.6 system. See this link for some discussion.