I am compiling some code for leftist heaps, and I want to step through my levelorder traversal function. However, whenever I reach a breakpoint at "theheap.levelorder()" and type "step", gdb passes over the code.
I am compiling with the -g flag and have tried -fno-inline to no avail. Why is this happening?
My makefile is as follows:
all:LeftistHeap.o lab10.o
g++ LeftistHeap.o lab10.o -g -o lab10
lab10.o:LeftistHeap.h
g++ -fno-inline -g -c lab10.cpp
LeftistMax.o:LeftistHeap.h LeftistHeap.cpp
g++ -fno-inline -g -c LeftistHeap.cpp
clean:
rm *.o *~ lab10
EDIT:
I have two levelorder() functions: one private, one public. i know this is probably unnecessary, but it shouldn't result in gdb acting like this.
levelorder is declared as follows in the .h file:
public:
void levelorder();
private:
void levelorder(LNode* node);
levelorder is defined as follows in the .cpp file:
void LeftistHeap::levelorder()
{
levelorder(root);
}
void LeftistHeap::levelorder(LNode* node)
{
queue<LNode*> currentLevel, nextLevel;
currentLevel.push(root);
while(!currentLevel.empty())
{
LNode* temp = currentLevel.front();
currentLevel.pop();
if(temp)
{
cout << temp->key << " ";
if(temp->lchild != NULL)
nextLevel.push(temp->lchild);
if(temp->lchild != NULL)
nextLevel.push(temp->rchild);
}
if(currentLevel.empty())
{
cout << endl;
swapq(currentLevel, nextLevel);
}
}
}
Related
i want to compile this small program:
#include <iostream>
#include <SDL.h>
using namespace std;
int main() {
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
cout << "SDL init failed" << endl;
return 1;
}
cout << "Hello World" << endl;
return 0;
}
which I can do successfully with:
g++ -o SDL_basic SDL_basic.cpp -I/opt/local/include/SDL2/ -l SDL2 -L/opt/local/lib/
I spent the last hour trying to modify the makefile I usually use to do the same:
CXX=g++
INC=-I/opt/local/include/SDL2/
LIBSEARCHPATH=-L/opt/local/lib/
LIBS=-l SDL2
OBJECTS=$(PROJECT).o
PROJECT=SDL_basic
$(PROJECT) : $(OBJECTS)
${CXX} $(CPFLAGS) $(OBJECTS) -o $# ${INC} ${LIBSEARCHPATH} ${LIBS}
.cpp.o :
${CXX} -c ${CPFLAGS} $? ${INC} ${LIBSEARCHPATH} ${LIBS}
clean :
rm -f $(OBJECTS)
Running make finally works now, but if I run it a second time after a small change in the .cpp, I get the following warning:
clang: warning: -lSDL2: 'linker' input unused [-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '-L/opt/local/lib/' [-Wunused-command-line-argument]
Therefore my question. Does this make sense what I did in the makefile? Do the arguments ${INC} ${LIBSEARCHPATH} ${LIBS} really belong after both .cpp.o : and $(PROJECT) : $(OBJECTS) (Otherwise it does not seem to work)?
I hope somebody can help me.
Thank you a lot and best regards!!
F
I am attempting to generate code coverage for a small test library. The library only consists of two files.
calculator.cpp:
#include "calculator.h"
Calculator::Calculator()
{
}
Calculator::~Calculator()
{
}
void Calculator::addNumbers(int x, int y)
{
this->result = x + y;
}
calculator.h:
#ifndef CALCULATOR_H
#define CALCULATOR_H
class Calculator
{
public:
Calculator();
~Calculator();
void addNumbers(int x, int y);
};
#endif
I have a unit test for this library that is being executed. It includes the library and runs fine. I have set the cmake_cxx_flags to include -fprofile-arcs and -ftest-coverage in the top level CMakeLists.txt.
cmake_minimum_required(VERSION 2.8.11)
set(CMAKE_CXX_FLAGS "-std=c++11")
include_directories("${PROJECT_BINARY_DIR}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 --coverage")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 --coverage -ftest-coverage -fprofile-arcs")
add_subdirectory(src)
add_subdirectory(test)
I am using a script to take the gcno and gcda files that are generated on build to generate a human readable report.
#!/bin/bash
OUTPUT_DIR="$1/bin/ExecutableTests/Coverage"
mkdir -p "$OUTPUT_DIR"
component=Calculator
dependency=calculator
script=test_calculator.sh
unit_test=unit_test_calculator
mkdir $OUTPUT_DIR/$component
cd "$1"/bin/
make clean || exit 1
make || exit 1
# Create baseline coverage
lcov -c -i -d "$1"/bin/src/"$component"/CMakeFiles/"$dependency".dir -o "$1/Coverage/$component"_"$dependency".coverage.base
# Run the test
$1/scripts/$script $1
# Create test coverage
lcov -c -d "$1"/bin/test/$component/CMakeFiles/"$unit_test".dir -o "$1/Coverage/$component"_"$dependency".coverage.run
lcov -d "$1/test/$component" -a "$1/Coverage/$component"_"$dependency".coverage.base -a "$1/Coverage/$component"_"$dependency".coverage.run -o "$1/Coverage/$component"_"$dependency".coverage.total
genhtml --branch-coverage -o "$OUTPUT_DIR/$component" "$1/Coverage/$component"_"$dependency".coverage.total
rm -f "$1/Coverage/$component"_"$dependency".coverage.base "$1/Coverage/$component"_"$dependency".coverage.run "$1/Coverage/$component"_"$dependency".coverage.total
I can see that the data files are being generated for the library; however when I view the report that is generated from the script it shows that the library is never touched. This is clearly wrong as illustrated by my unit test.
#include "lest_basic.hpp"
#include "calculator.h"
#include <memory>
#include <iostream>
int addResult(int x, int y)
{
Calculator calc1;
return calc1.addNumbers(x, y);
}
const lest::test specification[] =
{
CASE( "Addition" )
{
std::cout << "Starting Addition testing..." << std::endl;
std::cout << "Adding 1 and 2..." << std::endl;
EXPECT(addResult(1, 2) == 3);
std::cout << "Adding 2 and 8..." << std::endl;
EXPECT(addResult(2, 8) > 1);
std::cout << "Adding 7 and 4..." << std::endl;
EXPECT(addResult(7, 4) < 12);
},
};
int main(int argc, char **argv) {
return lest::run( specification );
}
Here is the CMakeLists.txt for my unit test:
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/ExecutableTests/)
include_directories(${CMAKE_SOURCE_DIR}/externalinclude/)
include_directories(${CMAKE_SOURCE_DIR}/src/Calculator/)
add_executable (unit_test_calculator test_calculator.cpp)
target_link_libraries(unit_test_calculator -Wl,--whole-archive calculator -Wl,--no-whole-archive)
My question is why is the report saying that the library code isn't be covered? Are the data files the problem?
I have fixed my issue. The problem was that I wasn't running lcov against the source code after running the unit test. I had the wrong directory.
lcov -c -d "$1"/bin/test/$component/CMakeFiles/"$unit_test".dir -o "$1/Coverage/$component"_"$dependency".coverage.run
Needed to be:
lcov -c -d "$1"/bin/src/$component/CMakeFiles/"$dependency".dir -o "$1/Coverage/$component"_"$dependency".coverage.run
I have two main functions that use a common C++ class.
File1: main.cpp
#include <iostream>
#include "HelloAnother.h"
int main() {
HelloAnother::sayHello1();
return 0;
}
File2: main2.cpp
#include <iostream>
#include "HelloAnother.h"
int main() {
HelloAnother::sayHello2();
return 0;
}
File3: HelloAnother.h
#pragma once
class HelloAnother {
public:
static void sayHello1();
static void sayHello2();
};
File4: HelloAnother.cpp
#include <iostream>
#include "HelloAnother.h"
void HelloAnother::sayHello1() {
std::cout << "Hello 1!!!" << std::endl;
}
void HelloAnother::sayHello2() {
std::cout << "Hello 2 !!!" << std::endl;
}
Now I compile two executables:
clang-3.8 -o main -fprofile-arcs -ftest-coverage --coverage -g -fPIC -lstdc++ main.cpp HelloAnother.cpp
clang-3.8 -o main2 -fprofile-arcs -ftest-coverage --coverage -g -fPIC -lstdc++ main2.cpp HelloAnother.cpp
Now, I run ./main
Hello 1!!!
When I rerun ./main
Hello 1!!!
profiling: /media/sf_ubuntu-shared/test-profiling/main.gcda: cannot map: Invalid argument
profiling: /media/sf_ubuntu-shared/test-profiling/HelloAnother.gcda: cannot map: Invalid argument
One second run, I get this error (above) in trying to create/merge .gcda files.
Now, If I try to run ./main2
Hello 2 !!!
profiling: /media/sf_ubuntu-shared/test-profiling/HelloAnother.gcda: cannot map: Invalid argument
When I generate the code coverage report, the call to second function doesn't show up as if the call wasn't made.
Can anyone help me debug this issue pls? The issue seems to be related to merging of .gcda files on multiple runs, but not sure how to solve it.
I also tried clang-3.5 but with same results.
After a lot of searching and trial/error this is what works for me:
Compile first executable, run it. This generates HelloAnother.gcda and main.gcda files.
Execute lcov --gcov-tool=gcov-4.4 --directory . --capture --output-file coverage.main.info
rm -rf *.gcda; rm -rf *.gcno
Compile second executable (main2.cpp), run it. This generates another HelloAnother.gcda and a main2.gcda file.
Execute lcov --gcov-tool=gcov-4.4 --directory . --capture --output-file coverage.main2.info
Now to generate nice looking html report do: genhtml -o coverage coverage.main.info coverage.main2.info
Your problem is that you compile the shared file (HelloAnother.cc) twice and gcov fails to understand that two copies of HelloAnother.o inside main1 and main2 need to be shared.
Instead, compile the shared code once and link it into each executable:
$ g++ --coverage -c HelloAnother.cc
$ g++ --coverage main1.cc HelloAnother.o -o main1
$ g++ --coverage main2.cc HelloAnother.o -o main2
$ ./main1
Hello 1!!!
$ ./main2
Hello 2 !!!
$ gcov --stdout HelloAnother.gcno
...
1: 4:void HelloAnother::sayHello1() {
1: 5: std::cout << "Hello 1!!!" << std::endl;
1: 6:}
-: 7:
1: 8:void HelloAnother::sayHello2() {
1: 9: std::cout << "Hello 2 !!!" << std::endl;
1: 10:}
-: 11:
I am trying to understand why using -O2 -march=native with GCC gives a slower code than without using them.
Note that I am using MinGW (GCC 4.7.1) under Windows 7.
Here is my code :
struct.hpp :
#ifndef STRUCT_HPP
#define STRUCT_HPP
#include <iostream>
class Figure
{
public:
Figure(char *pName);
virtual ~Figure();
char *GetName();
double GetArea_mm2(int factor);
private:
char name[64];
virtual double GetAreaEx_mm2() = 0;
};
class Disk : public Figure
{
public:
Disk(char *pName, double radius_mm);
~Disk();
private:
double radius_mm;
virtual double GetAreaEx_mm2();
};
class Square : public Figure
{
public:
Square(char *pName, double side_mm);
~Square();
private:
double side_mm;
virtual double GetAreaEx_mm2();
};
#endif
struct.cpp :
#include <cstdio>
#include "struct.hpp"
Figure::Figure(char *pName)
{
sprintf(name, pName);
}
Figure::~Figure()
{
}
char *Figure::GetName()
{
return name;
}
double Figure::GetArea_mm2(int factor)
{
return (double)factor*GetAreaEx_mm2();
}
Disk::Disk(char *pName, double radius_mm_) :
Figure(pName), radius_mm(radius_mm_)
{
}
Disk::~Disk()
{
}
double Disk::GetAreaEx_mm2()
{
return 3.1415926*radius_mm*radius_mm;
}
Square::Square(char *pName, double side_mm_) :
Figure(pName), side_mm(side_mm_)
{
}
Square::~Square()
{
}
double Square::GetAreaEx_mm2()
{
return side_mm*side_mm;
}
main.cpp
#include <iostream>
#include <cstdio>
#include "struct.hpp"
double Do(int n)
{
double sum_mm2 = 0.0;
const int figuresCount = 10000;
Figure **pFigures = new Figure*[figuresCount];
for (int i = 0; i < figuresCount; ++i)
{
if (i % 2)
pFigures[i] = new Disk((char *)"-Disque", i);
else
pFigures[i] = new Square((char *)"-Carré", i);
}
for (int a = 0; a < n; ++a)
{
for (int i = 0; i < figuresCount; ++i)
{
sum_mm2 += pFigures[i]->GetArea_mm2(i);
sum_mm2 += (double)(pFigures[i]->GetName()[0] - '-');
}
}
for (int i = 0; i < figuresCount; ++i)
delete pFigures[i];
delete[] pFigures;
return sum_mm2;
}
int main()
{
double a = 0;
StartChrono(); // home made lib, working fine
a = Do(10000);
double elapsedTime_ms = StopChrono();
std::cout << "Elapsed time : " << elapsedTime_ms << " ms" << std::endl;
return (int)a % 2; // To force the optimizer to keep the Do() call
}
I compile this code twice :
1 : Without optimization
mingw32-g++.exe -Wall -fexceptions -std=c++11 -c main.cpp -o main.o
mingw32-g++.exe -Wall -fexceptions -std=c++11 -c struct.cpp -o struct.o
mingw32-g++.exe -o program.exe main.o struct.o -s
2 : With -O2 optimization
mingw32-g++.exe -Wall -fexceptions -O2 -march=native -std=c++11 -c main.cpp -o main.o
mingw32-g++.exe -Wall -fexceptions -O2 -march=native -std=c++11 -c struct.cpp -o struct.o
mingw32-g++.exe -o program.exe main.o struct.o -s
1 : Execution time :
1196 ms (1269 ms with Visual Studio 2013)
2 : Execution time :
1569 ms (403 ms with Visual Studio 2013) !!!!!!!!!!!!!
Using -O3 instead of -O2 does not improve the results.
I was, and I still am, pretty convinced that GCC and Visual Studio are equivalents, so I don't understand this huge difference.
Plus, I don't understand why the optimized version is slower than the non-optimized version with GCC.
Do I miss something here ?
(Note that I had the same problem with genuine GCC 4.8.2 on Ubuntu)
Thanks for your help
Considering that I don't see the assembly code, I'm going to speculate the following :
The allocation loop can be optimized (by the compiler) by removing the if clause and causing the following :
for (int i=0;i <10000 ; i+=2)
{
pFigures[i] = new Square(...);
}
for (int i=1;i <10000 ; i +=2)
{
pFigures[i] = new Disk(...);
}
Considering that the end condition is a multiple of 4 , it can be even more "efficient"
for (int i=0;i < 10000 ;i+=2*4)
{
pFigures[i] = ...
pFigures[i+2] = ...
pFigures[i+4] = ...
pFigures[i+6] = ...
}
Memory wise this will make Disks to be allocated 4 by 4 an Squares 4 by 4 .
Now, this means they will be found in the memory next to each other.
Next, you are going to iterate the vector 10000 times in a normal order (by normal i mean index after index).
Think about the places where these shapes are allocated in memory.You will end up having 4 times more cache misses (think about the border example, when 4 disks and 4 squares are found in different pages, you will switch between the pages 8 times... in a normal case scenario you would switch between the pages only once).
This sort of optimization (if done by the compiler, and in your particular code) optimizes the time for Allocation , but not the time of access (which in your example is the biggest load).
Test this by removing the i%2 and see what results you get.
Again this is pure speculation, and it assumes that the reason for lower performance was a loop optimization.
I suspect that you've got an issue unique to the combination of mingw/gcc/glibc on Windows because your code performs faster with optimizations on Linux where gcc is altogether more 'at home'.
On a fairly pedestrian Linux VM using gcc 4.8.2:
$ g++ main.cpp struct.cpp
$ time a.out
real 0m2.981s
user 0m2.876s
sys 0m0.079s
$ g++ -O2 main.cpp struct.cpp
$ time a.out
real 0m1.629s
user 0m1.523s
sys 0m0.041s
...and if you really take the blinkers off the optimizer by deleting struct.cpp and moving the implementation all inline:
$ time a.out
real 0m0.550s
user 0m0.543s
sys 0m0.000s
Please help me, How to access run time varibale's data(att) in stub.exe of att variable that is defined in proc.so,
I have created proc.so and linked with attol.exe and stub.exe and
attol.exe updates 'att' variable and stub.exe is accessing 'att' variable and prints att's value.
I have used below commands to compile the code :
g++ -Wall -c attol.cc proc.cc stub.cc
g++ -shared -dynamiclib -fPIC -o libproc.so proc.o -ldl
g++ -rdynamic -o attol.exe attol.o /users/hbharti/DLOPEN/proc/libproc.so -ldl
g++ -rdynamic -o stub.exe stub.o /users/hbharti/DLOPEN/proc/libproc.so -ldl
When i am running both .exe at different terminal then attol.exe showing 'att:4' value but stub.exe is showing incorrect value,
But stub.exe should display '4' value or updated value.
out put attol.exe:
./attol.exe
Value of att is : 4
Enter the value of att :
out put stub.exe:
./stub.exe
Att : 0
----Complete Code Details----
proc.h:
#ifndef __X_H_INCLUDED__
#define __X_H_INCLUDED__
extern int att;
int fun();
#endif
proc.cc:
#include<iostream.h>
#include "proc.h"
int att;
int fun ()
{
att=4;
return 0;
}
Above code is generating proc.o and then this proc.o will converted into proc.so with below commands:
g++ -Wall -c attol.cc proc.cc stub.cc
g++ -shared -dynamiclib -fPIC -o libproc.so proc.o -ldl
attol.cc:
#include <iostream.h>
#include "proc.h"
using namespace std;
int main ()
{
int ch=1;
fun();
cout<<"\n Value of att is : "<<att;
do{
cout<<"\n Enter the value of att : ";
cin>>att;
cout<<"\n Do you want to continue the : ";
cin>>ch;
}while(ch!=0);
return 0;
}
attol.cc file creates attol.exe by using below command
g++ -rdynamic -o attol.exe attol.o /users/hbharti/DLOPEN/proc/libproc.so -ldl
out put:
Value of att is : 4
Enter the value of att :
stub.cc:
#include <iostream.h>
#include <dlfcn.h>
int main ()
{
void *handle;
char *error;
handle = dlopen ("/users/hbharti/DLOPEN/proc/libproc.so", RTLD_LAZY);
if (!handle) {
fputs (dlerror(), stderr);
exit(1);
}
int *att =(int*) dlsym(handle, "att");
if ((error = dlerror()) != NULL) {
fputs(error, stderr);
exit(1);
}
cout<<"\n Att : " <<*att;
cout<<"\n " ;
dlclose(handle);
}
stub.cc file creates stub.exe by using below command
g++ -rdynamic -o stub.exe stub.o /users/hbharti/DLOPEN/proc/libproc.so -ldl
Judging by the code, there seems to be a fundamental issue with the core-logic.
A shared-object (*.so) is loaded into the executing process's memory address space.
However it is NOT shared across multiple processes. When 2 or more executables attempt to access the same shared-object (*.so), they both get independent copies of it mapped into their respective memory address spaces.
Data (even globals) within a shared-object (*so) are NOT shared across 2 or more executables.