seg fault when I change local class name - c++

segment fault is gone when I change the name of my class and I don't understand. I have built a class called Environ and I create it and call it in the main. What I have found is when I change the local variable name in main from this_environ to environ i get a segment fault where none of my Environ variables have been initialized. Has anyone come into this or understand why this would be an issue? The interesting thing is that this isn't an issue when I compile on my Ubuntu machine...
#include <vector>
#include <map>
#include <iostream>
//#include "Environ.hpp"
// Namespaces
using namespace std;
class Environ {
public:
// Public objects.
vector<unsigned> years_;
void initialise() {
cerr << "entering initialsie" << endl;
years_ = {12,32,23};
}
};
int main() {
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
Environ this_environ;
this_environ.initialise();
cout << "Finished initialisation" << endl;
system("PAUSE");
return 0;
}
For reproducibility I am building on windows 10 with gcc version 5.1.0 with the following build call
g++ -std=c++0x -O2 -g3 -Wall -c -fmessage-length=0

I have just discovered that environ is a macro in stdlib so most likely not a good idea to call a variable this. The macro defined on line 633 of stdlib.h, perhaps I should mention my GCC is from here
#define sys_errlist _sys_errlist
#define sys_nerr _sys_nerr
#define environ _environ
char *__cdecl ecvt(double _Val,int _NumOfDigits,int *_PtDec,int *_PtSign) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
char *__cdecl fcvt(double _Val,int _NumOfDec,int *_PtDec,int *_PtSign) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
char *__cdecl gcvt(double _Val,int _NumOfDigits,char *_DstBuf) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
char *__cdecl itoa(int _Val,char *_DstBuf,int _Radix) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
char *__cdecl ltoa(long _Val,char *_DstBuf,int _Radix) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
int __cdecl putenv(const char *_EnvString) __MINGW_ATTRIB_DEPRECATED_MSVC2005;

Related

G++/C++Cannot link library

I am trying to create and link a static library in C++. I have two files:
helloWorld.cpp
#include <iostream>
int main(int argc, char const *argv[]) {
std::cout << "I'm inside main." << '\n';
printHello();
return 0;
}
libraryHello.cpp
#include <iostream>
void printHello() {
std::cout << "Hello" << '\n';
}
I am running such commands (based on http://www.techytalk.info/c-cplusplus-library-programming-on-linux-part-one-static-libraries/):
g++ -Wall -c libraryHello.cpp -o libraryHello.o
ar rcs libmylib.a libraryHello.o
g++ -static helloWorld.cpp -L. -lmylib -o helloExecute
First two go well, when trying to compile main file such error appears:
helloWorld.cpp: In function ‘int main(int, const char**)’:
helloWorld.cpp:5:14: error: ‘printHello’ was not declared in this scope
It looks as though it is not loaded at all and it cannot find printHello. Is there anything I am doing wrong when compiling, linking or anything else? What I want to do is to call printHello() procedure from main using static library and linking it to helloWorld.cpp.
My compiler: g++ 5.4.0, OS: Ubuntu 16.04 32bit
You did not declare the function before use:
#include <iostream>
void printHello(); /// <-- this was missing
int main(int argc, char const *argv[]) {
std::cout << "I'm inside main." << '\n';
printHello();
return 0;
}
You have everything in place that is needed for linking, but not for compiling. The general idea is like this: The compiler needs a declaration for every function that you use. That is, it has to know its name and signature.
The compiler will now check whether a function call is valid for the given signature and leave a placeholder for the function call. It is up to the linker to resolve those placeholders and replace them with the actual address of the called function.
The linker therefore has to find a matching definition for that function, that is, an actual implementation. If you just declare the function, but forget to define it, compilation will happily succeed, but the linker will complain about an unresolved reference.
This split allows you to compile different source files in isolation: Each source file needs to know the declarations of every function that it uses, but not the definitions. This is enough for the compiler to ensure that a caller uses the function correctly. Declarations are typically placed in header files, to ensure that implementation and caller have a consistent understanding about what the function signature is, even if they reside in distinct source files.
helloWorld.cpp
#include <iostream>
#include <libraryHello.h>
using namespace std;
int main(int argc, char const *argv[])
{
cout << "I'm inside main." << '\n';
printHello();
return 0;
}
libraryHello.h (You need add this file)
#ifndef LIBRARYHELLO_H
#define LIBRARYHELLO_H
void printHello();
#endif // LIBRARYHELLO_H
libraryHello.cpp
#include <iostream>
#include <libraryHello.h>
void printHello() {
std::cout << "Hello" << '\n';
}
You still need to have a forward declaration for
void printHello();
before main().
Otherwise the compiler doesn't know how that function should be called.
The usual way is to put that into a corresponding header file, and include that in the other translation units.

error: uint64_t was not declared in this scope when compiling C++ program

I am trying out a simple program to print the timestamp value of steady_clock as shown below:
#include <iostream>
#include <chrono>
using namespace std;
int main ()
{
cout << "Hello World! ";
uint64_t now = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
cout<<"Value: " << now << endl;
return 0;
}
But whenever I am compiling like this g++ -o abc abc.cpp, I am always getting an error:
In file included from /usr/include/c++/4.6/chrono:35:0,
from abc.cpp:2:
/usr/include/c++/4.6/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the upcoming ISO C++ standard, C++0x. This support is currently experimental, and must be enabled with the -std=c++0x or -std=gnu++0x compiler options.
abc.cpp: In function âint main()â:
abc.cpp:7:3: error: âuint64_tâ was not declared in this scope
abc.cpp:7:12: error: expected â;â before ânowâ
abc.cpp:8:22: error: ânowâ was not declared in this scope
Is there anything wrong I am doing?
Obviously, I'm not following certain best practices, but just trying to get things working for you
#include <iostream>
#include <chrono>
#include <cstdint> // include this header for uint64_t
using namespace std;
int main ()
{
{
using namespace std::chrono; // make symbols under std::chrono visible inside this code block
cout << "Hello World! ";
uint64_t now = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
cout<<"Value: " << now << endl;
}
return 0;
}
and then compile using C++11 enabled (c++0x in your case)
g++ -std=c++0x -o abc abc.cpp
You should include stdint.h file.
If you really want to include, add "#define __STDC_LIMIT_MACROS"
Ref: https://stackoverflow.com/a/3233069/6728794

Segmentation Fault with Global Variable in MPICH 1.6

Consider the following simple program:
#include <mpi.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <vector>
using std::cout;
using std::string;
using std::vector;
vector<float> test;
#ifdef GLOBAL
string hostname;
#endif
int main(int argc, char** argv) {
int rank; // The node id of this processor.
int size; // The total number of nodes.
#ifndef GLOBAL
string hostname;
#endif
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
cout << "Joining the job as processor: " << rank << std::endl;
{
char buf[2048] = "HELLO";
hostname.assign(buf, 2048);
}
test.push_back(1.0f);
cout << "Hostname: " << hostname << "::" << test[0] << std::endl;
MPI_Finalize();
return 0;
}
If I compile/run this with:
mpicxx -c test.cc && mpicxx -lstdc++ test.o -o test && ./test
there is no segmentation fault, but if I run it with:
mpicxx -DGLOBAL -c test.cc && mpicxx -lstdc++ test.o -o test && ./test
then there is a segmentation fault at the hostname.assign() line. In addition, if I remove this assignment, there is a segmentation fault in the string destructor once the main method returns so the assign method isn't the actual culprit.
Notice that the only difference is where the "global" variable hostname gets declared.
I am compiling with MPICH2 version 1.6, and don't really have the option to change this since I am running this on a supercomputer.
If I remove MPI_Init, etc. the error goes away leading me to believe that there is something unexpected happening with MPI and this global variable.
I found some other examples of this happening to people online, but they all resolved their issues by installing a new version of MPICH, which again is not a possibility for me.
Moreover, I want to know WHY this happening more than just a way around it.
Thanks for your time.
Ok, after quite a bit of debugging I have found that the MVAPICH2-1.6 library defines a variable called hostname in:
mpid/ch3/channels/mrail/src/rdma/ch3_shmem_coll.c
Here is the line (55 in this version of the file):
char hostname[SHMEM_COLL_HOSTNAME_LEN];
The compiler didn't complain about the name clash here, but this is almost certainly the culprit since changing the variable name in my program removed the error. I imagine this is changed in later versions of MVAPICH2, but I will file the bug if not.

Linker Error C++ "undefined reference " [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is an undefined reference/unresolved external symbol error and how do I fix it?
Trying to compile my program via g++ -o prog1 main.cpp -std=c++0x
I get the error:
/tmp/cc1pZ8OM.o: In function `main':
main.cpp:(.text+0x148): undefined reference to `Hash::insert(int, char)'
collect2: error: ld returned 1 exit status
main.cpp
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <functional>
#include "Hash.h"
using namespace std;
int main(int argc, char *argv[]) {
//preset prime number
int prime = 101;
hash<char> h1;
int key;
Hash HashTable;
// check for Request & string parameters
if(argc != 3) {
cout << "Run program with 2 parameters. [Lower Case]" << endl;
cout << "[1] insert, find, or delete" << endl;
cout << "[2] string" << endl;
}
if(strcmp(argv[1], "insert") == 0) {
//Get Hash for argv[2] aka value
key = h1(*argv[2]);
//check 1
cout << "Hash: " << key << endl;
key = key % prime;
//check 2
cout << "Mod 101 Hash: " << key << endl;
HashTable.insert(key, *argv[2]); //PROBLEM here
}
return 0;
}
Hash.h file:
#include <iostream>
#include <cstring>
#include "LinkedList.h"
using namespace std;
class Hash {
//100 slot array for hash function
LinkedList *hashFN[100];
public:
void insert(int key, char value);
//void deleteItem(int key);
//char* find(int key);
};
Any ideas? Using this to build a hash table with set size.
Edit: Hash.cpp file
#include <iostream>
#include <cstring>
#include "Hash.h"
using namespace std;
void Hash::insert(int key, char value){
*hashFN[key]->addFront(value);
cout << "Success!" << endl;
}
Trying to compile via terminal now with:
g++ -c Hash.cpp -o Hash.o
g++ -o prog1 main.cpp Hash.o -std=c++0x
It goes into an infinite loop somehow.
Your header file Hash.h declares "what class hash should look like", but not its implementation, which is (presumably) in some other source file we'll call Hash.cpp. By including the header in your main file, the compiler is informed of the description of class Hash when compiling the file, but not how class Hash actually works. When the linker tries to create the entire program, it then complains that the implementation (toHash::insert(int, char)) cannot be found.
The solution is to link all the files together when creating the actual program binary. When using the g++ frontend, you can do this by specifying all the source files together on the command line. For example:
g++ -o main Hash.cpp main.cpp
will create the main program called "main".
This error tells you everything:
undefined reference toHash::insert(int, char)
You're not linking with the implementations of functions defined in Hash.h. Don't you have a Hash.cpp to also compile and link?
Your error shows you are not compiling file with the definition of the insert function. Update your command to include the file which contains the definition of that function and it should work.

dlopen() gives unresolved symbol error when .so tries to use a class from the main executable. Why?

I'm on Linux, the question is concerning shared objects of C++ classes.
The problem comes when my shared objects try to use resources linked into the main executable. I have the following codes:
loader.cpp:
#include <dlfcn.h>
#include <iostream>
#include "CommonInfo.h"
using namespace std;
int main(int argc, char** argv) {
for(int i=1; i<argc; ++i) {
string pth = "./";
pth.append(argv[i]);
void* dh = dlopen(pth.c_str(), RTLD_NOW);
if(dh==NULL) {
cerr << dlerror() << endl;
return 1;
}
CommonInfo::GetInfoFunc getInfo = (CommonInfo::GetInfoFunc)(dlsym(dh,"getInfo"));
if(getInfo==NULL) {
cerr << dlerror() << endl;
return 1;
}
CommonInfo* info = getInfo();
cout << "INFO: " << info->getX() << endl;
delete info;
}
return 0;
}
CommonInfo.h:
#include <string>
class CommonInfo {
public:
typedef CommonInfo* (*GetInfoFunc)();
private:
std::string x;
public:
CommonInfo(const std::string& nx);
std::string getX() const;
};
EDIT:
I accidentaly forgot to ctrl-c + ctrl-v the source of CommonInfo.cpp here. Of course, it is there during compilation, so CommonInfo.cpp:
#include "CommonInfo.h"
CommonInfo::CommonInfo(const std::string& nx) : x(nx) {
}
std::string CommonInfo::getX() const {
return x;
}
A Plugin.h header:
#include "CommonInfo.h"
extern "C" CommonInfo* getInfo();
A very simple Plugin.cpp:
#include <iostream>
#include "Plugin.h"
#include "CommonInfo.h"
using namespace std;
CommonInfo* getInfo() {
return new CommonInfo("I'm a cat!");
}
Compiling is done with:
g++ -rdynamic -ldl -Werror CommonInfo.cpp loader.cpp -o loader
g++ -shared -fPIC -Werror Plugin.cpp -o Plugin.so
Running:
./loader Plugin.so
And there goes the error:
./loader: symbol lookup error: ./Plugin.so: undefined symbol: _ZN10CommonInfoC1ERKSs
Indeed, looking inside Plugin.so with nm Plugin.so | grep -i CommonInfo it gives an 'U' for this symbol (unresolved), which is perfectly ok.
Also, looking inside the binary of loader with nm loader.so | grep -i CommonInfo I could find the symbol with 'T', which is also ok.
Question is, shouldn't dlfcn.h unresolve the symbol in question from the main binary? Without this feature it becomes quite hard to use these stuff... Do I have to write a class factory function for CommonInfo, load it with dlfcn from the plugin and call that?
Thanks in advance,
Dennis
I haven't looked closely at your code, but I have in the past found behavior like you describe in the title when I did not link the executable with -E. (Or -Wl,-E when linking with gcc rather than ld.)
Note that not all platforms let the shared libraries take symbols from the calling binary. Linux and the *BSDs allow you to. But if you ever want to port to, say, Windows, you will not be able to use this pattern. I believe there are also some Unix-type OS's that won't let you do this. (It's been a while so I don't remember... Maybe it was Solaris?)