gcc 4.8.2 on Linux - Simple program using thread crashes - linux

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

Related

Visual c++ for Linux Development debugging shared library

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.

how to compile g++ app and run anywhere?

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)

Why I failed to compile a sctp program in Linux?

First I install sctp on Ubuntu 12.04
sudo apt-get install libsctp-dev lksctp-tools
Then in my .c file,I include :
#include < netinet/in.h >
#include < netinet/sctp.h >
#include < sys/socket.h >
#include < stdlib.h >
#include < unistd.h >
howerver,when I compiled with gcc,the result is:
undefined reference to `sctp_recvmsg'
undefined reference to `sctp_get_no_strms'
undefined reference to `sctp_sendmsg'
What is wrong?
If you really compile with gcc temp.c -o temp then you are not linking any libraries (except the default libc.6.so), and you need some additional argument to gcc ; perhaps try to compile with
gcc -Wall -g temp.c -lsctp -o temp
Once your program is debugged with the help of the gdb debugger and you consider it to be bug-free, you may ask the compiler to optimize it using
gcc -Wall -O2 temp.c -lsctp -o temp
The order of program arguments to gcc is important and significant.
centos: yum install lksctp-tools-devel

Building HelloWorld C++ Program in Linux with ncurses

I successfully ran sudo apt-get install libncurses5-dev
Within my Eclipse window I then try to build the following HelloWord.cpp program:
#include <ncurses.h>
int main()
{
initscr(); /* Start curses mode */
printw("Hello World !!!"); /* Print Hello World */
refresh(); /* Print it on to the real screen */
getch(); /* Wait for user input */
endwin(); /* End curses mode */
return 0;
}
I get the following error:
Invoking: GCC C++ Linker
g++ -m32 -lncurses -L/opt/lib -o "Test_V" ./src/curseTest.o ./src/trajectory.o ./src/xJus-epos.o -lEposCmd
/usr/bin/ld: cannot find -lncurses
collect2: error: ld returned 1 exit status
make: *** [Test_V] Error 1
It looks like the compiler is searching for the ncurses library and can't find it? I checked /usr/lib and the library does not exist there so do I need to manually link the ncurses library there - I thought the get-apt installer would automatically do this?
g++ HelloWorld.cpp -lncurses -o HelloWolrd
If you have a 32-bit machine, gcc compile m32 auto. If you have a 64-bit machine and you want to compile 32bits you
Your arguments are not in the correct order. You must specify all source files first and then linker search directories before specifying the libraries to link with. Your command should be like this:
g++ HelloWorld.o -L/opt/lib -lncurses -o HelloWorld
Taken from comment by #ChrisDodd:
Your options are in the wrong order -- -L must be BEFORE -l and both must be after all .o

linking libc with JNI code on embedded Linux platform (GuruPlug)

I'm trying to compile a simple JNI application on an embedded Linux platform (a GuruPlug computer), but for some reason it's not linking to libc properly. The Java program I'm compiling is called Test.java:
public class Test {
static {
System.loadLibrary("Test");
}
public static void main(String[] args) {
new Test().printMessage();
}
public native void printMessage();
}
The implementation of printMessage() is in Test.c:
#include <jni.h>
#include <stdio.h>
#include "Test.h"
JNIEXPORT void JNICALL Java_Test_printMessage(JNIEnv *env, jobject obj)
{
printf("Message 123...\n");
}
I'm compiling Test.c with the following command on a bash shell:
gcc -g -shared -static -lc -Wl,-soname,libTest.so -I${JAVA_HOME}/include/ -I${JAVA_HOME}/include/linux/ Test.c -o libTest.so
When I run the above command, I get the error message "R_ARM_TLS_LE32 relocation not permitted in shared object". The full error message is:
/usr/bin/ld: /usr/lib/gcc/arm-linux-gnueabi/4.4.5/../../../libc.a(dl-tsd.o)(.text+0x18): R_ARM_TLS_LE32 relocation not permitted in shared object
Despite the error message, the JNI .so file is still written by the compiler, but running the Java application gives the following error message:
Exception in thread "main" java.lang.UnsatisfiedLinkError: /usr/lib/jni/libTest.so: /usr/lib/jni/libTest.so: unexpected reloc type 0x03
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1750)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1675)
at java.lang.Runtime.loadLibrary0(Runtime.java:840)
at java.lang.System.loadLibrary(System.java:1047)
at Test.<clinit>(Test.java:3)
Could not find the main class: Test. Program will exit.
Does anybody have any idea how to go about fixing this? Admittedly, the above code is a toy example, but I need to get a real JNI library compiling on this platform, and the real JNI library depends on libc. I can't seem to solve this basic issue of linking libc with a JNI library. Any suggestions would be greatly appreciated.
Thanks!
gcc -g -shared -static -lc -Wl,-soname,libTest.so -I${JAVA_HOME}/include/ -I${JAVA_HOME}/include/linux/ Test.c -o libTest.so
There are several problems with the command line above:
the -shared and -static flags are mutually exclusive, and the second overrides the first
when linking shared libraries, you want -fPIC on most architectures
the -lc is in the wrong place (should follow your sources, not precede them), and is not necessary anyway: gcc will add it automatically
you don't strictly need the -soname either; it's just useless clutter
The correct command then is:
gcc -g -shared -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux \
Test.c -o libTest.so

Resources