gperftools and pprof do not print my function names. Need advice on how to fix this - sdl

I'm currently writing a game in C++ using SDL on Ubuntu. I recently multithreaded my engine, so I switched from profiling with valgrind/callgrind to gperftools. I have gotten it to work, but it will not print my own function names. Oddly enough, it recognizes SDL function names (I've seen the reverse happening on a few threads online; shared library functions not having their names found).
kcachegrind Output
I run my program, and the execute the following two commands in order to get this:
pprof --callgrind /bin/ls ls.prof > ls.callgrind
kcachegrind ls.callgrind
I know there are several ways to use gperftools; I have done it by including "gperftools/profiler.h" and using the ProfilerStart("ls.prof") and ProfilerStop() functions.
For reference, here is part of my Makefile in case that is relevant:
OBJS = background.o gameObject.o uGrid.o main.o Timer.o sdlHandlers.o player.o handleEvents.o handleAllStateChanges.o enactAllStateChanges.o cleanLoop.o renderAll.o loadAllFiles.o loop.o inputHandler.o loopWrite.o loopDebug.o loopDebugSingleStep.o loopDebug_SDLDecoupled.o
CC = g++
CFLAGS = -std=c++11 -Wall -O3 -c -g
Aegis: $(OBJS)
$(CC) $(OBJS) -I/sdlLib -lSDL2 -I/sdlLib -lSDL2_image -I/sdlLib -lSDL2_mixer -lX11 -pthread -lprofiler -o Aegis
I removed all references to object files and the like; this is not the entire file. Upon request, I can post the entire Makefile.
Also, because people have gotten confused in the past, I AM using a copy of the SDl2 libraries in my project's folder. That is not a typo.
If anything is unclear, I am happy to answer or provide more source code if needed. Anything to get this problem fixed
Thanks!

You seem to be linking your program without debug symbols. Add -g (or I tend to add -ggdb3) to flags.

Related

Getting Cplex example to run: Undefined references

I am trying to get the Cplex basic LP example to work. The code can be found here. I am completely new with c++, but hope to be able to get this running.
I am trying to compile it on linux. I am using the following command to run it
g++ -D IL_STD -I /opt/ibm/ILOG/CPLEX_Studio1271/opl/include ilolpex1.cpp
The -D IL_STD was put there to solve an error as found here. The -I ... was put there to specify the location of the header files. I came up with this myself after a lot of trying and googling, so i am in no way sure this is correct.
Anyway, i when i run it i get errors of undefined references:
/tmp/ccl9O1YF.o: In function `populatebyrow(IloModel, IloNumVarArray, IloRangeArray)':
ilolpex1.cpp:(.text+0x18f): undefined reference to `IloNumVar::IloNumVar(IloEnv, double, double, IloNumVar::Type, char const*)'
I did not make any changes in the file, so i assume the only thing which can be wrong is how the files are linked. I have the feeling it probably just is a simple setting, but after hours of looking i still have no idea how to fix it.
The easiest way to compile the ilolpex1.cpp example is to use the Makefile that is included with the installation. For example, you should do the following:
$ cd /opt/ibm/ILOG/CPLEX_Studio1271/cplex/examples/x86-64_linux/static_pic
$ make ilolpex1
This will produce output, like the following:
g++ -O0 -c -m64 -O -fPIC -fno-strict-aliasing -fexceptions -DNDEBUG -DIL_STD -I../../../include -I../../../../concert/include ../../../examples/src/cpp/ilolpex1.cpp -o ilolpex1.o
g++ -O0 -m64 -O -fPIC -fno-strict-aliasing -fexceptions -DNDEBUG -DIL_STD -I../../../include -I../../../../concert/include -L../../../lib/x86-64_linux/static_pic -L../../../../concert/lib/x86-64_linux/static_pic -o ilolpex1 ilolpex1.o -lconcert -lilocplex -lcplex -lm -lpthread
This will tell you everything you'll need to know if you choose to compile your own application by hand in the future. The details about this are described in the documentation (e.g., here).
Obviously, the iloplex1.cpp file is just a demo how to use IloCplex.
What you yet need is IloCplex itself. This should come either as (a) further source file(s) you have to compile with the demo or as a library you link against.
Have a look at your cplex directories, you might find a lib[...].a file somewhere there, possibly in /opt/ibm/ILOG/CPLEX_Studio1271/opl/lib.
You can link against using GCC's (clang's) -l and -L options. Be aware that when using -l, you leave out lib and .a (-l [...] with above (invalid) sample name).

ld.exe: cannot find -lgtest only when using GNU make for windows

I have been trying to compile a simple C++ program with the googletest libraries. I have gotten this to work using g++, however the project will soon become large and I want to be able to automate the compilation using make. I installed GNU make for windows which I have tested on another program and it works. However when I try and use make to compile my googletest project I get the following error:
ld.exe: cannot find -lgtest
Here is the contents of my makefile:
all: test.exe
test.exe: main.cpp
g++ -o test.exe .\main.cpp .\sample1.h .\sample1.cc .\sample1_unittest.cc -ID:\...\gtest\include -LD:\D...\gtest\lib\ -lgtest_main -lgtest -Wall
clean:
rm test.o test.exe
The weird thing is that if I run the same code from the command line, as follows, it works perfectly an I end up with my test.exe.
g++ -o test.exe .\main.cpp .\sample1.h .\sample1.cc .\sample1_unittest.cc -ID:\...\gtest\include -LD:\D...\gtest\lib\ -lgtest_main -lgtest -Wall
Does anyone know what this could be caused by and how to fix it?
Ok, I managed to find the problem! I'm still not sure why this is the case but apparently in make you have to specify paths like so:
-LD:\...\gtest\lib
And not like this (note the extra ):
-LD:\...\gtest\lib\
The error message makes sense since it must have been trying to search for the library in a path that looks something like this:
-LD:\...\gtest\lib\\
Which would obviously not work. I guess what threw me off was that the code worked when executed from the command line. It took me a while to see the inconstancy in my path specification and figure out that make doesn't want the extra '\'. Hopefully this will prevent someone else for wasting as much time as I did.

Linking and using netCDF with gcc

Im trying to use netCDF library in my C++ project, but i cannot, for some reason, use it.
Here is my make file
NETCDF = -L/usr/lib -lnetcdf_c++
WILXAPP = -Lsrc src/wilxtest.cpp -o bin/Debug/WilxAstakTest
Debug:
g++ -Wall -ggdb $(NETCDF) $(WILXAPP)
In my cpp file i basically have (removed bloat)
#include <iostream>
#include <netcdfcpp.h>
int main(int argc, char* argv[])
{
NcFile dataFile("simple_xy.nc", NcFile::Replace);
}
And I get this:
undefined reference to `NcFile::NcFile(char const*, NcFile::FileMode, unsigned long*, unsigned long, NcFile::FileFormat)'|
I'm not sure that the errors you're providing match the source you're showing, since the undefined reference for the constructor signature has no relationship to the way you've invoked the constructor in your example.
Anyway, I suspect your problem is that order matters on the link line. The linker only walks through its libraries etc. one time, so if something that comes LATER on the link line needs something that comes EARLIER on the link line, you fail. You must order your link line such that things that require other things come first, and things that are required come later.
A few other tips: the -L option only gives search paths for libraries, so you don't need -Lsrc here as there's no library you're linking from the src directory. Also you don't need to add -L/usr/lib (in fact, it's a very bad idea) as the compiler already searches the system directories in the proper order, and on many systems (that support multiple architectures for example) /usr/lib won't be the right place.
Finally, when writing makefiles always remember that the recipe should create the exact filename of the target: for GNU make you can use $# for that in all cases. And you need to use the source file as a prerequisite, otherwise you might as well not bother using make and just write a shell script. Try this:
NETCDF = -lnetcdf_c++
WILXAPP = src/wilxtest.cpp
CXX = g++
CXXFLAGS = -Wall -ggdb
bin/Debug/WilxAstakTest: $(WILXAPP)
$(CXX) $(CXXFLAGS) -o $# $^ $(NETCDF)
Solved the very same problem by combining MadScientist's answer (almost complete) with a solution by "Russ" I found in an archived email in the UniData support pages (http://www.unidata.ucar.edu/support/help/MailArchives/netcdf/msg04846.html):
You need to add "-lnetcdf" to the end of your g++ invocation. If you
run "make test" in the src/cxx directory, you will see this is how
the test program is linked. So use something like:
g++ -o example -I<PATH>netcdf-3.5.1-beta13/include example.cpp -L<PATH>netcdf-3.5.1-beta13/lib -lnetcdf_c++ -lnetcdf
if you want to do the compile and link all in one step.
The default installation stores the C++ library in a different library
file than the C library, but I think you could use ld to combine them
into a single library for convenience. There were portability
problems with trying to do this on all platforms, so the interfaces
are distributed to use separate libraries.
--Russ
The point is: you need to link BOTH -lnetcdf_c++ AND -lnetcdf ... in this order.
My 'makefile' looks like this:
NETCDF = -lnetcdf_c++ -lnetcdf
APP = main.cpp
CXX = g++
CXXFLAGS = -Wall -ggdb
Example: $(APP)
$(CXX) $(CXXFLAGS) -o $# $^ $(NETCDF)
m. (MyselfAnotherMadScientist)

symbols named incompatibly in shared objects - where to look for problems

I am new to Linux. I have access to two Linux machine, one 40 core server(A) and a cluster(B). I am trying to do the same on both machines, it works on A and doesn't on B. I have sudo rights on neither. A runs on debian squeeze/sid. B runs on kernel 2.6.18-238.el5. I could not find any release info file under /etc. A has gcc 4.6.2, whereas B gcc 4.1.2.
I compiled and installed locally on both machines a given meshing software Pkg1, and Pkg2, a given solver. Both need Libtool and automake. Pkg2 is a .so file. All work fine, I could run the examples. The code was built with mpicxx. Both have different mpi compilers. A uses openmpi154, B uses qlogicmpi_gnu-0.1.0.
Now I introduce my code, say Pkg3, a few .cpp files. I built a .so out of it. I did not use Libtool and automake. A simple make file, with gcc as compiler and linker (also tried mpicxx) was used.
On A, Pkg3 runs fine. On B, Pkg3 crashes. It crashes when it tries to dynamically cast some type in Pkg3 to a type defined in Pkg2 with message St8bad_cast. For another data file, it crashes when a function in Pkg2 tries to cast a type from Pkg3, with message 'element type is N5ngfem8FE_Segm2E expected type is N5ngfem19ScalarFiniteElementILi1EEE '
Where do I look for problems? Sorry for being vague. All the software here is opensource, but the packages are too big to make a self contained repro with little amount of work. I have neither worked with automake and Libtools, nor with mpi yet, which compounds the issue. I looked into the makefiles of Pkg1 and Pkg2 and tried to map the CXX, LDFLAGS etc with my simple makefile, but the multiple indirections created by automake/libtools makes it difficult.
I understand the symbols in Pkg2 are mangled differently in the symbol table than the ones in Pkg3. But that should have been taken care of the linker?! I have tried with both with and without '-Wl,-E' options for Pkg3. -fPIC is always there. The rule to link Pkg3, points to library Pkg2 (). I have posted the body of Pkg3's makefile.
%.o : %.cpp
gcc -O2 -fopenmp -fPIC -DNETGEN_ELTRANS -DUSE_TIMEOFDAY -DLAPACK -I. -I$(NETGENDIR)/../include -c $? -o $#
libmyngsolve.so : $(objects)
gcc -shared -Wl,-E -fopenmp -fPIC $(objects) -L/home/lv70227/elan/ng/lib -lngsolve -o $#
clean:
rm *.o libmyngsolve.so
Note 1:
The ./configure command for Pkg2 has -Wl,--start-group -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -Wl,--end-group -lpthread
i.e., it does not have -E flag. But that is how it was specified to me, as reference.
Note 2:
The path defined in the link rule, -L/home/lv70227/elan/ng/lib,
has pkg2.so.0.0.0, two symbolic links to it, and pkg2.la, not pkg2.sa since it was created by libtools.
Any hint as to where the problem could lie is appreciated. I have followed the same procedure on both machine, making minimum deviations to accommodate the different mpi, gcc, mkl libraries installed in A and B.
Thank you,
Elan.
As I told you in comments, GCC 4.1 and GCC 4.6 are so different that a possible solution could be to install a GCC 4.6 (perhaps by compiling its source code, and required dependencies) on your older machine.

C++, the "Old Fashioned" way

I have been learning C++ in school to create small command-line programs.
However, I have only built my projects with IDEs, including VS08 and QtCreator.
I understand the process behind building a project: compile source to object code, then link them into an executable that is platform specific (.exe, .app, etc). I also know most projects also use make to streamline the process of compiling and linking multiple source and header files.
The thing is, although IDEs do all this under the hood, making life very easy, I don't really know what is really happening, and feel that I need to get accustomed to building projects the "old fashioned way": from the command line, using the tool chain explicitly.
I know what Makefiles are, but not how to write them.
I know what gcc does, but not how to use it.
I know what the linker does, but not how to use it.
What I am looking for, is either an explanation, or link to a tutorial that explains, the workflow for a C++ project, from first writing the code up to running the produced executable.
I would really like to know the what, how, and why of building C++.
(If it makes any difference, I am running Mac OS X, with gcc 4.0.1 and make 3.81)
Thanks!
Compiling
Let's say you want to write a simple 'hello world' application. You have 3 files, hello.cpp hello-writer.cpp and hello-writer.h, the contents being
// hello-writer.h
void WriteHello(void);
// hello-writer.cpp
#include "hello-writer.h"
#include <stdio>
void WriteHello(void){
std::cout<<"Hello World"<<std::endl;
}
// hello.cpp
#include "hello-writer.h"
int main(int argc, char ** argv){
WriteHello();
}
The *.cpp files are converted to object files by g++, using the commands
g++ -c hello.cpp -o hello.o
g++ -c hello-writer.cpp -o hello-writer.o
The -c flag skips the linking for the moment. To link all the modules together requires running
g++ hello.o hello-writer.o -o hello
creating the program hello. If you need to link in any external libraries you add them to this line, eg -lm for the math library. The actual library files would look something like libm.a or libm.so, you ignore the suffix and the 'lib' part of the filename when adding the linker flag.
Makefile
To automate the build process you use a makefile, which consists of a series of rules, listing a thing to create and the files needed to create it. For instance, hello.o depends on hello.cpp and hello-writer.h, its rule is
hello.o:hello.cpp hello-writer.h
g++ -c hello.cpp -o hello.o # This line must begin with a tab.
If you want to read the make manual, it tells you how to use variables and automatic rules to simplify things. You should be able to just write
hello.o:hello.cpp hello-writer.h
and the rule will be created automagically. The full makefile for the hello example is
all:hello
hello:hello.o hello-writer.o
g++ hello.o hello-writer.o -o hello
hello.o:hello.cpp hello-writer.h
g++ -c hello.cpp -o hello.o
hello-writer.o:hello-writer.cpp hello-writer.h
g++ -c hello-writer.cpp -o hello-writer.o
Remember that indented lines must start with tabs. Not that not all rules need an actual file, the all target just says create hello. It is common for this to be the first rule in the makefile, the first being automatically created when you run make.
With all this set up you should then be able to go to a command line and run
$ make
$ ./hello
Hello World
More advanced Makefile stuff
There are also some useful variables that you can define in your makefile, which include
CXX: c++ compiler
CXXFLAGS:
Additional flags to pass to the
compiler (E.g include directories
with -I)
LDFLAGS: Additional flags to
pass to the linker
LDLIBS: Libraries
to link
CC: c compiler (also used to
link)
CPPFLAGS: preprocessor flags
Define variables using =, add to variables using +=.
The default rule to convert a .cpp file to a .o file is
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $#
where $< is the first dependancy and $# is the output file. Variables are expanded by enclosing them in $(), this rule will be run with the pattern hello.o:hello.cpp
Similarly the default linker rule is
$(CC) $(LDFLAGS) $^ -o $# $(LDLIBS)
where $^ is all of the prerequisites. This rule will be run with the pattern hello:hello.o hello-writer.o. Note that this uses the c compiler, if you don't want to override this rule and are using c++ add the library -lstdc++ to LDLIBS with the line
LDLIBS+=-lstdc++
in the makefile.
Finally, if you don't list the dependancies of a .o file make can find them itself, so a minimal makefile might be
LDFLAGS=-lstdc++
all:hello
hello:hello.o hello-writer.o
Note that this ignores the dependancy of the two files on hello-writer.h, so if the header is modified the program won't be rebuilt. If you're interested, check the -MD flag in the gcc docs for how you can automatically generate this dependancy.
Final makefile
A reasonable final makefile would be
// Makefile
CC=gcc
CXX=g++
CXXFLAGS+=-Wall -Wextra -Werror
CXXFLAGS+=-Ipath/to/headers
LDLIBS+=-lstdc++ # You could instead use CC = $(CXX) for the same effect
# (watch out for c code though!)
all:hello # default target
hello:hello.o hello-world.o # linker
hello.o:hello.cpp hello-world.h # compile a module
hello-world.o:hello-world.cpp hello-world.h # compile another module
$(CXX) $(CXXFLAGS) -c $< -o $# # command to run (same as the default rule)
# expands to g++ -Wall ... -c hello-world.cpp -o hello-world.o
A simple example is often useful to show the basic procedure, so:
Sample gcc usage to compile C++ files:
$ g++ -c file1.cpp # compile object files
[...]
$ g++ -c file2.cpp
[...]
$ g++ -o program file1.o file2.o # link program
[...]
$ ./program # run program
To use make to do this build, the following Makefile could be used:
# main target, with dependencies, followed by build command (indented with <tab>)
program: file1.o file2.o
g++ -o program file1.o file2.o
# rules for object files, with dependencies and build commands
file1.o: file1.cpp file1.h
g++ -c file1.cpp
file2.o: file2.cpp file2.h file1.h
g++ -c file2.cpp
Sample Makefile usage:
$ make # build it
[...]
$ ./program # run it
For all the details you can look at the Gnu make manual and GCC's documentation.
I know what Makefiles are, but not how to write them.
The make syntax is horrible, but the GNU make docs aren't bad. The main syntax is:
<target> : <dependency> <dependency> <dep...>
<tab> <command>
<tab> <command>
Which defines commands to build the target from the given dependencies.
Reading docs and examples is probably how most people learn makefiles, as there are many flavors of make with their own slight differences. Download some projects (pick something known to work on your system, so you can actually try it out), look at the build system, and see how they work.
You should also try building a simple make (strip out a bunch of the harder features for your first version); I think this is one case where that will give you a much better grasp on the situation.
I know what gcc does, but not how to use it.
Again, man g++, info pages, and other documentation is useful, but the main use when you call it directly (instead of through a build system) will be:
g++ file.cpp -o name # to compile and link
g++ file.cpp other.cpp -o name # to compile multiple files and link as "name"
You can also write your own shell script (below is my ~/bin/c++ simplified) to incorporate $CXXFLAGS so you won't forget:
#!/bin/sh
g++ $CXXFLAGS "$#"
You can include any other option as well. Now you can set that environment variable ($CXXFLAGS, the standard variable for C++ flags) in your .bashrc or similar, or redefine it in a particular session, for working without a makefile (which make does do just fine, too).
Also use the -v flag to see details on what g++ does, including...
I know what the linker does, but not how to use it.
The linker is what takes the object files and links them, as I'm sure you know, but g++ -v will show you the exact command it uses. Compare gcc -v file.cpp (gcc can work with C++ files) and g++ -v file.cpp to see the difference in linker commands that often causes the first to fail, for example. Make also shows the commands as it runs them by default.
You are better off not using the linker directly, because it is much simpler to use either gcc or g++ and give them specific linker options if required.
Just to throw this out there, the complete gcc documentation can be found here: http://www.delorie.com/gnu/docs/gcc/gcc_toc.html
compiler takes a cpp and turns into an object file which contains native code and some information about that native code
a linker takes the object files and lays out an excutable using the extra information in the object file.... it finds all the references to the same things and links them up, and makes and image useful for the operating system to know how to load all the code into memory.
check out object file formats to get a better understanding of what the compiler produces
http://en.wikipedia.org/wiki/Object_file (different compilers use different formats)
also check out (for gcc)
http://pages.cs.wisc.edu/~beechung/ref/gcc-intro.html on what you type at the command line
You might also look into Autoproject, which sets up automake and autoconf files, which makes it easier for people to compile your packages on different platforms: http://packages.debian.org/unstable/devel/autoproject
I like this quirky intro to building a hello world program with gcc, Linux-based but the command-line stuff should work fine on OS/X. In particular, it walks you through making some common mistakes and seeing the error messages.
Holy Compilers, Robin, the darn thing worked!
This is what has helped me to learn the autoconf, automake, ...:
http://www.bioinf.uni-freiburg.de/~mmann/HowTo/automake.html
It is a nice tutorial progresses from a simple helloworld to more advanced structures with libraries etc.