I am trying to view the annotated source using $ valgrind --tool=callgrind ./myProgram followed by $ kcachegrind using Ubuntu 12.04 (and I'm having the same problem with $ qcachegrind using Mac OSX).
The C++ script myProgram.cpp makes calls to functions that live in a .hpp file (via #include "../include/myHeader.hpp", etc.). I compile myProgram.cpp like this:
g++ -g -o myProgram myProgram.o -l<some third party lib>
where I don't care about viewing annotated source for that third party lib.
What I would like to see is annotated source for the functions in myHeader.hpp and for myProgram.cpp.
Instead, I see kcachegrind's Flat Profile window with a list of all the functions that get called, including the functions in myHeader.hpp - this is great. Now, kcachegrind reports the location of functions from myHeader.hpp as being from myProgram - this is odd. And finally, when I select any function from the Flat Profile window and request to see Source Code, I am met with:
There is no source available for the following function
<name of the selected function>
This is because no debug information is present.
Recompile the source and redo the profile run.
The function is located in the ELF object:
<some location...>
What I've tried:
added the directory holding myHeader.hpp to the Annotations list using kcachegrind's GUI.
compiled using -O0 to remove compiler optimizations
I'm answering my own question thanks to user n.m. - I discovered this while running a simplified example. The problem was with my compilation instruction, I was compiling to an object file with -g rather than compiling to an executable with -g.
Here's a working example for how to get kcachegrind to show annotated source:
main.cpp lives in directory someDirectory/example
// main.cpp
#include <iostream>
#include <math.h>
#include "../include/header.hpp"
using namespace std;
int main() {
double a=1.0; double b=4.0;
double tol = 1E-10;
double zero = -99;
if (sin(a)*sin(b) < 0 && (b-a) >= tol)
zero = bisect_sine(a,b,tol);
cout << zero << endl;
return 0;
}
Header file header.hpp lives in someDirectory/include
// header.hpp
#include <math.h>
#include <iostream>
using namespace std;
double bisect_sine(double a, double b, double tol) {
double c;
int step = 0; int maxsteps = 100;
while (step < maxsteps) {
c = (a+b)/2.0;
if (sin(c) == 0 || (b-a)/2 < tol)
return c;
if (sin(a)*sin(c) >= 0)
a = c;
else
b = c;
step+=1;
}
}
Makefile
# Makefile
CXX = g++
main:
$(CXX) -g -o main main.cpp
chmod 700 main
clean:
rm main
After all of this, simply run make (yielding the executable main that was compiled with debugging -g), followed by valgrind --tool=callgrind ./main. This will produce the expected callgrind.out.<PID> file, which can be read by kcachegrind. Source annotation will then be available for the main() function of main.cpp as well as for bisect_sine() from the header file.
So, this turned out to be a compilation issue. If I understood more about compilation into executables, object files, shared objects, yada yada yada, I would not have gotten into this mess.
Related
Is it possible to load an extra helper .so during current gdb session?
// point.h
class Point
{
public:
int x;
int y;
Point(int x1, int y1) {x = x1; y = y1;}
};
// main.cpp
#include "point.h"
#include <stdio.h>
int main()
{
Point p(3, 4);
printf("%d\n", p.x);
return 0;
}
g++ -g -c main.cpp -o main.o
g++ -g main.o -o main
When debugging, I need to add a helper function to dump the Point object. But I don't want to recompile and rerun. (It might take a long time.) So I am trying to build another helper.so.
// helper.cpp
#include "point.h"
#include <stdio.h>
void dump_point(Point *p)
{
printf("Point(%d, %d)\n", p->x, p->y);
}
g++ -g -fPIC -shared helper.cpp -o helper.so
Is it possible to load this helper.so in gdb so I can call dump_point() without rerunning?
When debugging, I need to add a helper function to dump the Point object.
The "normal" way to do this to write a custom pretty printer in Python.
One advantage of doing that is that the pretty printer will also work for a core dump, whereas dump_point() solution will not (regardless of whether it's linked in or loaded from a separate .so).
So I am trying to build another helper.so.
If your main was linked against libdl, you could do this:
(gdb) call dlopen("./helper.so", 0)
(gdb) call dlsym($_, "dump_point")
Note: you will want to make dump_point extern "C" to avoid name mangling.
Situation is as follows: I've got a simple project consisting of two files - Calc.h and Calc.cpp.
Calc.h:
#pragma once
class Calc {
public:
int add(int,int);
static const int a = 42;
}
Calc.cpp:
#include "Calc.h"
class Calc {
public:
int add(int a,int b){
return a + b;
};
}
CalcTestSuite.h:
#pragma once
#include "Calc.h"
#include <cxxtest/TestSuite.h>
class CalcTestSuite : public CxxTest::TestSuite {
public:
void testAddition(void)
{
Calc calculator;
TS_ASSERT_EQUALS(calculator.a, 42);
TS_ASSERT_EQUALS(calculator.add(1,2), 3);
}
}
The problem
The problem being is, when I do cxxtestgen --error-printer -o runner.cpp CalcTestSuite.h && g++ -I$cxxtest -o runner.o runner.cpp && ./runner.o, an error occurs:
runner.cpp: (.text._ZN13...(many letters)): undefined reference to `Calc::add(int,int)`
Undoubtedly, the reason of that is wrong compiling as I compile code outside of Visual Studio 2019 or other IDE.
How I tried to solve the problem:
I see a couple of solutions:
1.) Leave build command as is and add #include "Calc.cpp" to TestSuite file, which will obviously work but would be a bad practice.
2.) Add Calc.cpp to g++ command: g++ -I$cxxtest -o runner.o Calc.cpp runner.cpp && ./runner.o, however, it leads to another problem:
Calc.cpp:3:7: error: redefinition of 'class Calc'
In that case I also tried changing #pragma once to #ifndef CALC_H... block in Calc.h, but the error remained.
I tried searching for real-world cxxtest code examples, but didn't find the site I've seen long ago. I would be glad to recieve any tips on what's the best way to deal with this issue.
And if you know the site where I can search for real-life code snippets I would be glad if you shared it.
There are two problems:
You are violating One Definition Rule! You can't redefine Calc like this:
#include "Calc.h"
class Calc {
public:
int add(int a,int b){
return a + b;
};
}
It must be:
#include "Calc.h"
int Calc::add(int a,int b) {
return a + b;
};
const int Calc::a;
Now this problem do not surfaces since you do not build this cpp and you should.
You didn't explain how you are building you code. Simplest way when it is done manually it can look like this:
cxxtestgen --error-printer -o CalcTestSuite.cpp CalcTestSuite.h
g++ -std=c++17 -Wall -Wextra Calc.cpp CalcTestSuite.cpp -o test
Offtopic: this cxxtest test framework is strange and has strange/complex build process of test. It would be better if you learn to use something more useful, Catch2 is great and easy to use (no funny build process) and it is supported by godbolt.
I've been working on a couple established C++ projects that use static variables from a shared library to store parameters. When compiled with g++ or clang++, the static variable is shared (has the same memory location) throughout the entire program. However, when compiled with Xcode, the main function static variable has a different memory location than the shared library static variable. Is there a way to get Xcode to compile/run the code the same as g++ or clang++, while still being able to debug with Xcode?
Please see example below:
main.cpp:
#include <iostream>
#include "Params.hpp"
int main(int argc, const char * argv[]) {
Params param = Params();
param.addParams();
std::vector<int> vi = Params::ParamsObj();
vi.push_back(10);
for(std::vector<int>::iterator it = vi.begin(); it != vi.end(); ++it) {
std::cout << "i = " << *it << std::endl;
}
return 0;
}
Params.hpp:
#ifndef Params_hpp
#define Params_hpp
#include <vector>
class Params{
typedef std::vector<int> ParamVector;
public:
static ParamVector& ParamsObj() {
static ParamVector m;
return m;
}
void addParams();
};
#endif /* Params_hpp */
Params.cpp:
#include "Params.hpp"
void Params::addParams(){
Params::ParamsObj().push_back(5);
}
Makefile:
clang:
clang++ -dynamiclib Params.cpp -o libshared_clang.dylib
clang++ main.cpp -o main_clang ./libshared_clang.dylib
gpp:
g++-mp-4.9 -Wall -shared -fPIC -o libshared_gpp.so Params.cpp
g++-mp-4.9 -Wall -o main_gpp main.cpp ./libshared_gpp.so
Output from both g++ and clang++ is:
i = 5
i = 10
While Xcode only outputs i = 10.
If I don't use a shared library and compile everything into one binary, Xcode will properly output both print statements.
My current solution is to add the project's main function into its own shared library and then create an Xcode specific file which merely calls the main function in the newly created shared library. However, I was hoping for a solution that didn't require changing the underlying project's code.
I'm pretty sure that if you turn on optimalization for gcc/clang (which you did not in your example), they will produce the same behavior as your compilation with XCode (which isn't a compiler, but an IDE).
Your problem is that the ParamsObj() function is inline (defining it in the class body adds an implicit inline keyword to it), allowing the compiler to just "paste" it into the main method instead of calling it.
With dll boundaries, this might result in the allocation of multiple static variables, if the function is used in multiple libraries (in your case, it's used in the dll, and inlined into the main executable).
Refactor the ParamsObj() method into a declaration and a separate definition in the corresponding C++ file, and you'll get the same behavior everywhere, printing both numbers.
Currently, I'm learning c++ and a question about the modularization process. Suppose I want to write a function to add two or three numbers. For that purpose I've wrote the following header file:
// Sum2.hpp
//
// Preprocessor directives; ensures that we do not include a file twice
// (gives compiler error if you do so)
#ifndef Sum2_HPP
#define Sum2_HPP
/////////// Useful functions //////////////////
// Max and Min of two numbers
double Sum2(double x, double y);
// Max and Min of three numbers
double Sum2(double x, double y, double z);
////////////////////////////////////////////////
#endif
This is just declaration. In a separate file, I specify the functions:
// Sum2.cpp
// Code file containing bodies of functions
//
#include "Sum2.hpp"
/////////// Useful functions //////////////////
// Sum of two numbers
double Sum2(double x, double y)
{
return x+y;
}
// Sum of three numbers
double Sum2(double x, double y, double z)
{
return Sum2(Sum2(x,y),z);
}
And then, in the main programm I want to use these functions:
// main.cpp
#include <iostream>
#include "Sum2.hpp"
int main()
{
double d1;
double d2;
double d3;
std::cout<<"Give the first number ";
std::cin>> d1;
std::cout<<"Give the second number ";
std::cin>> d2;
std::cout<<"Give the third number ";
std::cin>> d3;
std::cout<<"The sum is: "<<Sum2(d1,d2);
std::cout<<"The sum is: "<<Sum2(d1,d2,d3);
return 0;
}
I used g++ -c Sum2.cpp to generate the object code Sum2.o. Why is there a reference error when I want to compile and create an executable from the main code, i.e. g++ -o main main.cpp?
It is working when I compile both at same time, i.e. g++ -o main main.cpp Sum2.cpp. I thought by creating the object code Sum2.o and including the header file in main.cpp the compiler will automatically recognize the object code. Why this is not working?
// Preprocessor directives; ensures that we do not include a file twice
// (gives compiler error if you do so)
No actually, it won't give a compiler error. It just won't do anything.
As for your actual question, c++ unlike some other languages won't try to find your object files for you. You have to tell the compiler where they are at. For this application you should really compile it like so:
g++ -c main.cpp
g++ -c Sum2.cpp
g++ -o main main.o Sum2.o
The first two actually compile the code. The second links the code together to produce the executable. If you execute
g++ -o main main.cpp Sum2.cpp
The compiler will automatically run both steps for you. It works for a small project, but for larger projects you don't want to run all the steps unless something has changed.
Now, you may think that's a pain. You'd be right. That's why there are various tools like CMake, Scons, Jam, Boost.Build which are designed to make it easier to build C++ projects.
I have scenario where I have a binary that depends on library A which in turn depends on library B.
I have built library A against library B, but none of library B:s symbols leak out of library A, everything is contained in the cpp-file.
Now I only want to link the binary against library A, since all of the symbols found in the binary can be satisfied by library A. Is this possible?
In the real application, library B is an implementation of a network protocol and I have a lot of binaries who link against the intermediate library. And I don't want the binaries to be aware of the different network protocols used.
Platform: Linux / GCC
Code:
liba/liba.h:
#ifndef LIBA_H
#define LIBA_H
int getANumber();
#endif
liba/liba.cpp:
#include "liba.h"
#include "../libb/libb.h"
int getANumber(){ return getBNumber(); }
libb/libb.h:
#ifndef LIBB_H
#define LIBB_H
int getBNumber();
#endif
libb/libb.cpp:
#include "libb.h"
int getBNumber(){ return 42; }
main.cpp:
#include "liba/liba.h"
#include <iostream>
int main(int argc, char** argv) {
std::cout << getANumber() << std::endl;
return 0;
}
commands:
~/libb/ $ g++ -shared -o libb.so libb.cpp
~/liba/ $ g++ -shared -o liba.so liba.cpp -L../libb -lb
~/ $ g++ -o main main.cpp -Lliba -la # fails
~/ # These two work, but I don't want to specify libb here.
~/ $ g++ -o main main.cpp -Lliba -la -Wl,-rpath-link,libb
~/ $ LD_LIBRARY_PATH=libb g++ -o main main.cpp -Lliba -la
What is the best way to solve this? Do I have to create it as a plugin?
Best regards,
Daniel
If you want to CHANGE which library you use at runtime, then you can't link against it directly, but use a "manual" loading. In other words, call dlopen and dlsym
This probably also means that you need a slightly different architecture in "liba", since each function in "libb" becomes a function pointer, so something along these lines:
int (*getBNumber)() = NULL;
void initialize()
{
void *handle = dlopen("libb", RTLD_NOW);
getBNumber = (int (*)())dlsym(handle, "getBNumber");
}
int getANumber(){ return getBNumber(); }
You'll need to set something up to call initialize at some point - or have a if (!initialized) initialize(); in each function.