Im doing a project that works with ELF files. Right now Im using the following as a sample input -
class C {
public:
C();
C(int x, int y);
int getX();
private:
int x;
int y;
};
class SubC : public C {
int z;
};
int f() {return 0;}
C c;
SubC subC;
int i;
double d;
I then run
gcc test.cpp -g -c -o test.o
and I get test.o as expected. I then feed test.o into a library I found called peter-dwarf. My problem is that the library says "no section .debug_str found in test.o"
Am I doing something wrong during compilation? Or is the library not working?
Edit: should have been a -g in there
Use -g in gcc to generate the debug symbols. You may also refer to the documentation of debugging options of gcc here.
The -g alone might not include DWARF information if your system is configured in some way. There is a number of switches related to DWARF specifically, so if -g alone does not work, you may need to go there and mangle with other switches.
Probably you need to compile with debugging information enabled. Try:
gcc -g test.cpp -c -o test.o
Related
Considering the following piece of code :
extern int var;
void foo(int & param)
{
(void) param;
}
int main(void)
{
foo(*(&var));
return 0;
}
Compiled this way :
$ g++ -Os -o test.o -c test.cpp
$ g++ test.o
But when I remove the -Os flag, there is an undefined reference to var.
What kind of optimization are enabled by -Os to skip this undefined reference ? (I tried to replace the flag by all the optimizations it enable according to the GCC documentation but I can't reproduce without -Os.
Another question, when I compile the sample in one go :
$ g++ -c test.c
There is no error even though there is no optimization flag, why ?
After performing some binary search on the flags, the relevant one appears to be -fipa-pure-const, demo here. The description is "Discover which functions are pure or constant. Enabled by default at -O1 and higher.", which presumably includes noticing that foo doesn't actually do anything with param.
I have the program which needs v2xmvtest.so. When i try to build it via make i get undefined reference to *
Seems like that function from libssl1.0. (If i install it, it's built fine)
But i do not see the place where these function are used. More than that, when i try ldd v2xmvtest.so it does show only libvssl1.1 dependency.
Summary:
Is there a way to find out where those finctions from libvssl1.0 are used in the program ? (i have source code of the v2xmvtest.so and try to search, but there no any of these)
I need a description why ldd does not show me libssl1.0 dependency, but during linkning it's needed
Thank you!
Libraries are not required to fully define used symbols. For instance you can have lib.cpp:
int foo();
int bar(int x)
{
return x + foo();
}
and it compiles even foo is actually not defined yet:
g++ lib.cpp -shared -o lib.so
Then you can have main.cpp:
#include <iostream>
int bar(int);
int foo()
{
return 10;
}
int main()
{
std::cout << bar(42) << std::endl;
}
which defines foo and compiles successfully with lib.so:
g++ main.cpp lib.so -o main
The foo function in lib.so is expected just to be provided when the application is linked and is not specified where exactly from, even not necessary from a library.
You can check for undefined symbols in a library using nm tool:
nm -C -u lib.so
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
U foo()
w __cxa_finalize##GLIBC_2.17
w __gmon_start__
And finally you can force gcc to ensure no undefined symbols are used by the object files by compiling with -Wl,-z,defs linker flag:
g++ lib.cpp -shared -Wl,-z,defs -o lib.so
...
lib.cpp:(.text+0x24): undefined reference to `foo()'
I have this header file:
weather.h
#ifndef _WEATHER_H_
#define _WEATHER_H_
#include <string>
using namespace std;
class Weather {
private:
int temp;
public:
Weather();
string announce();
};
#endif
When I compile the related source file, I want to make announce and Weather (the default constructor) weak during compile time.
To do so, the flow looks something like:
g++ -std=c++11 -g -Wall -c weather.cpp
objcopy --weaken-symbol=announce --weaken-symbol=Weather weather.o weather.o
However, when I then compile another version of weather without the weakening? I still get a duplicate symbol error.
I know --weaken exists, but this is just a sample and I do not want to blanket weaken every method in the class.
Weakening the symbols in the one file and linking all the objects together works for me. Make sure you are relinking all the objects (including all constructors).
weather1.cpp
Weather::Weather() {}
string Weather::announce()
{
return string("Bad weather");
}
weather2.cpp
Weather::Weather() {}
string Weather::announce()
{
return string("Bad weather 2");
}
build.sh
g++ weather1.cpp -c -o weather1.o
g++ weather2.cpp -c -o weather2.o
g++ test.cpp -c -o test.o
objcopy --weaken-symbol=_ZN7Weather8announceEv --weaken-symbol=_ZN7WeatherC2Ev --weaken-symbol=_ZN7WeatherC1Ev weather2.o weather2.o
g++ *.o -o test.out
Depending on whether I weaken weather1.o or weather2.o, I see different outputs from my test main function:
int main()
{
Weather w;
std::cout << w.announce() << "\n";
return 0;
}
In Visualstudio by trying to cross compile to a raspberry pi, I get the following error:
VisualGDB: Run "make CONFIG=Debug" in directory "/tmp/VisualGDB/c/Users/Revius/Desktop/usbtest/conversiecsc++/LinuxProject12/LinuxProject12" on pi#raspberrypi (SSH)
g++ -ggdb -ffunction-sections -O0 -DDEBUG -c LinuxProject12.cpp -o Debug/LinuxProject12.o -MD -MF Debug/LinuxProject12.dep
g++ -o Debug/LinuxProject12 -Wl,-gc-sections -L/home/pi/libssd1306/build/ArduiPi_OLED -Wl,--start-group Debug/LinuxProject12.o -Wl,--rpath='$ORIGIN' -Wl,--end-group
Debug/LinuxProject12.o: In function `Adafruit_GFX::~Adafruit_GFX()':
C:\Users\Revius\AppData\Local\VisualGDB\RemoteSourceCache\raspberrypi\0003\include\Adafruit_GFX.h(35): error VGDB1000: undefined reference to `vtable for Adafruit_GFX'
The part off Adafruit_GFX.H where the compiler is pointing to is
"virtual ~Adafruit_GFX() {};"
in:
#ifndef _ADAFRUIT_GFX_H
#define _ADAFRUIT_GFX_H
#define swap(a, b) { int16_t t = a; a = b; b = t; }
//class Adafruit_GFX : public Print {
class Adafruit_GFX {
public:
//Adafruit_GFX();
// i have no idea why we have to formally call the constructor. kinda sux
void constructor(int16_t w, int16_t h);
virtual ~Adafruit_GFX() {};
// this must be defined by the subclass
virtual void drawPixel(int16_t x, int16_t y, uint16_t color) = 0;
virtual void invertDisplay(boolean i);
The weird part is that I use "make" on the raspberry pi and in works, I can start so it works the code is alright? But not by Visualstudio?
So my question is:
Due I am cross compilling could i be the compiler is missing some file or are there options i could manipulate to get it working?
In which direction do I have to look to find the answer?
Setting for the Makefile in MSVS-GDB for oled display
By adjusting (or correct filling in te settings) i got it working.
I've read multiple posts here relating to dynamic libraries on os x and debugging with gdb. But I still can't figure out why I can't debug a simple test case.
The main issue is that when I start up GDB it never loads any shared libraries.
Update: I've tried this with GDB from macports, from homebrew, and built from source and the behavior is the same.
I have a class that I compile into a library.
Test.hpp
class Test {
public:
void set(int i);
void out() const;
private:
int i;
};
Test.cpp
#include "Test.hpp"
#include <iostream>
void Test::set(int ii) { i = ii; }
void Test::out() const {
auto j = i * 100;
std::cout << i << ", " << j << "\n";
++j;
std::cout << i << ", " << j << "\n";
}
I compile it and create a library with g++. Note: the behavior is the same with macports gcc and the gcc from xcode.
/opt/local/bin/g++-mp-4.8 -O0 -g -ggdb -Wall -c -std=c++11 -o Test.o Test.cpp
/opt/local/bin/g++-mp-4.8 -dynamiclib -o libTest.dylib Test.o
Then I test it with this simple main
#include "Test.hpp"
int main() {
Test t;
auto x = 4;
t.set(x);
t.out();
return 0;
}
This is compiled and linked with
/opt/local/bin/g++-mp-4.8 -O0 -g -ggdb -Wall -c -std=c++11 -o main.o main.cpp
/opt/local/bin/g++-mp-4.8 -L . -o testing main.o -lTest
Everything compiles and runs as expected. But when I try to debug this with gdb (installed from macports, or installed from source, the behavior is the same), I have problems.
As I step through main, if I call info sharedlibrary it always says "No shared libraries loaded at this time.", so it apparently never loads libTest.dylib. Therefore, I can't step into any of the Test member functions or create breakpoints anywhere in libTest.dylib.
Indeed ggdb installed from macports for some reason does not respect the DYLD_LIBRARY_PATH. However, if you "patch" your executable with the correct paths for the .dylibs you should be able to debug with ggdb. Take a look at this question and especially the answer by Akos Cz.