Reputation: 349
I have a class A and a class B which is derived from A :
class A
{
public :
A() { // Some code }
virtual ~A(){}
// etc
};
And here is my class B :
class B : public A
{
public :
B():A(){//Some extra code}
~B();
// etc
};
The real code of A and B are quite long so I wouln't post it there, unless if it's necessary.
My problem is that, in my main program :
The segfault appears only when I have an instance of B.
So, to find the location of my problem, I attempt to use Valgrind, but I'm quite stuck because I don't understand what Valgrind is displaying.
The output of Valgrind is quite long, but there's a scheme in it, and here is the result :
==13512== Invalid read of size 4
==13512== at 0x852EE9D: __tcf_0 (in /usr/local/lib/libeikeotools.so)
==13512== by 0x6AE15E9: __cxa_finalize (cxa_finalize.c:56)
==13512== by 0x84C3E72: ??? (in /usr/local/lib/libeikeotools.so)
==13512== by 0x4010739: _dl_fini (dl-fini.c:252)
==13512== by 0x6AE1258: __run_exit_handlers (exit.c:82)
==13512== by 0x6AE12A4: exit (exit.c:104)
==13512== by 0x6AC6ECB: (below main) (libc-start.c:321)
==13512== Address 0x131e4d00 is 16 bytes inside a block of size 32 free'd
==13512== at 0x4C2C2BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13512== by 0x664536E: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==13512== by 0x73A3384: __tcf_0 (logwriter.cpp:32)
==13512== by 0x6AE15E9: __cxa_finalize (cxa_finalize.c:56)
==13512== by 0x7301A72: ??? (in /usr/local/lib/libeikeotoolsd.so)
==13512== by 0x4010739: _dl_fini (dl-fini.c:252)
==13512== by 0x6AE1258: __run_exit_handlers (exit.c:82)
==13512== by 0x6AE12A4: exit (exit.c:104)
==13512== by 0x6AC6ECB: (below main) (libc-start.c:321)
==13512==
==13512== Invalid free() / delete / delete[] / realloc()
==13512== at 0x4C2C2BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13512== by 0x852EEB3: __tcf_0 (in /usr/local/lib/libeikeotools.so)
==13512== by 0x6AE15E9: __cxa_finalize (cxa_finalize.c:56)
==13512== by 0x84C3E72: ??? (in /usr/local/lib/libeikeotools.so)
==13512== by 0x4010739: _dl_fini (dl-fini.c:252)
==13512== by 0x6AE1258: __run_exit_handlers (exit.c:82)
==13512== by 0x6AE12A4: exit (exit.c:104)
==13512== by 0x6AC6ECB: (below main) (libc-start.c:321)
==13512== Address 0x131e4cf0 is 0 bytes inside a block of size 32 free'd
==13512== at 0x4C2C2BC: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==13512== by 0x664536E: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==13512== by 0x73A3384: __tcf_0 (logwriter.cpp:32)
==13512== by 0x6AE15E9: __cxa_finalize (cxa_finalize.c:56)
==13512== by 0x7301A72: ??? (in /usr/local/lib/libeikeotoolsd.so)
==13512== by 0x4010739: _dl_fini (dl-fini.c:252)
==13512== by 0x6AE1258: __run_exit_handlers (exit.c:82)
==13512== by 0x6AE12A4: exit (exit.c:104)
==13512== by 0x6AC6ECB: (below main) (libc-start.c:321)
EDIT 1 : Here is my 'B' class :
HOGpython.hpp :
#ifndef HOGPYTHON_H
#define HOGPYTHON_H
#include "osell/cvaddenda/HOGDescriptor2.h"
#include <opencv2/core/core.hpp>
#include "conversion.hpp"
#define NO_IMPORT_ARRAY
class HOGpython : public eikeotools::CvAddenda::HOGDescriptor2
{
public:
// Constructeurs :
HOGpython();
HOGpython(PyObject* _winSize, PyObject* _blockSize, PyObject* _blockStride, PyObject* _cellSize, int _nbins, double _winSigma);
// Destructeur :
~HOGpython(){ std::cout << " Destroying .." << std::endl;}
// setters :
PyObject* get_winSize() const;
PyObject* get_blockSize() const;
PyObject* get_blockStride() const;
PyObject* get_cellSize() const;
int get_nbins() const;
int get_derivAperture() const;
double get_winSigma() const;
int get_histogramNormType() const;
double get_L2HysThreshold() const;
bool get_gammaCorrection() const;
int get_nlevels() const;
// Setters :
void set_winSize( PyObject* o);
void set_blockSize( PyObject* o);
void set_blockStride( PyObject* o);
void set_cellSize( PyObject* o);
void set_nbins( int o);
void set_derivAperture( int o);
void set_winSigma( double o);
void set_histogramNormType( int o);
void set_L2HysThreshold( double o);
void set_gammaCorrection( bool o);
void set_nlevels( int o);
// Méthodes d'instance :
PyObject* compute(PyObject* img, PyObject* locations);
PyObject* computeSubPix(PyObject* img, PyObject* locations);
PyObject* computeGradient(PyObject* img);
};
#endif
And HOGpython.cpp :
#include "HOGpython.hpp"
// == Constructeur sans paramètres == //
HOGpython :: HOGpython():eikeotools::CvAddenda::HOGDescriptor2()
{}
// == Constructeur avec paramètres == //
HOGpython :: HOGpython(PyObject* _winSize, PyObject* _blockSize, PyObject* _blockStride, PyObject* _cellSize, int _nbins, double _winSigma)
:eikeotools::CvAddenda::HOGDescriptor2( tupleToSize(_winSize),
tupleToSize(_blockSize),
tupleToSize(_blockStride),
tupleToSize(_cellSize),
_nbins,
1,
_winSigma,
eikeotools::CvAddenda::HOGDescriptor2::L2Hys,
0.2,
false,
eikeotools::CvAddenda::HOGDescriptor2::DEFAULT_NLEVELS)
{}
// == Getters == //
PyObject* HOGpython::get_winSize() const {return SizeToTuple(winSize); }
PyObject* HOGpython::get_blockSize() const {return SizeToTuple(blockSize); }
PyObject* HOGpython::get_blockStride() const {return SizeToTuple(blockStride); }
PyObject* HOGpython::get_cellSize() const {return SizeToTuple(cellSize); }
int HOGpython::get_nbins() const {return nbins; }
int HOGpython::get_derivAperture() const {return derivAperture; }
double HOGpython::get_winSigma() const {return winSigma; }
int HOGpython::get_histogramNormType() const {return histogramNormType; }
double HOGpython::get_L2HysThreshold() const {return L2HysThreshold; }
bool HOGpython::get_gammaCorrection() const {return gammaCorrection; }
int HOGpython::get_nlevels() const {return nlevels; }
// == Setters == //
void HOGpython::set_winSize(PyObject* o) {winSize = tupleToSize(o);}
void HOGpython::set_blockSize(PyObject* o) {blockSize = tupleToSize(o);}
void HOGpython::set_blockStride(PyObject* o) {blockStride = tupleToSize(o);}
void HOGpython::set_cellSize(PyObject* o) {cellSize = tupleToSize(o);}
void HOGpython::set_nbins(int o) {nbins = o; return;}
void HOGpython::set_derivAperture(int o) {derivAperture = o; return;}
void HOGpython::set_winSigma(double o) {winSigma = o; return;}
void HOGpython::set_histogramNormType(int o) {histogramNormType = o; return;}
void HOGpython::set_L2HysThreshold(double o) {L2HysThreshold = o; return;}
void HOGpython::set_gammaCorrection(bool o) {gammaCorrection = o; return;}
void HOGpython::set_nlevels(int o) {nlevels = o; return;}
PyObject* HOGpython::compute(PyObject* img, PyObject* locations)
{
// Déclaration d'instances :
cv::Mat im, pt;
PyObject* ret;
// Conversion :
NDArrayConverter cvt;
im = cvt.toMat(img);
pt = cvt.toMat(locations);
// Déclaration de vecteurs :
std::vector<float> desc;
std::vector<cv::Point> pts;
//Py_BEGIN_ALLOW_THREADS;
PyThreadState * m_thread_state;
m_thread_state = PyEval_SaveThread();
for(int i = 0; i < pt.rows; i++)
{
pts.push_back(cv::Point(pt.at<double>(i,0), pt.at<double>(i,1)));
}
eikeotools::CvAddenda::HOGDescriptor2::compute(im,desc,cv::Size(),cv::Size(),pts, false);
PyEval_RestoreThread(m_thread_state);
m_thread_state = NULL;
//Py_END_ALLOW_THREADS;
cv::Mat pointsMat = cv::Mat(desc);
ret = cvt.toNDArray(pointsMat);
return ret;
}
PyObject* HOGpython::computeSubPix(PyObject* img, PyObject* locations)
{
// Déclaration d'instances :
cv::Mat im, pt;
PyObject* ret;
// Conversion :
NDArrayConverter cvt;
im = cvt.toMat(img);
pt = cvt.toMat(locations);
// Déclaration de vecteurs :
std::vector<float> desc;
std::vector<cv::Point2f> pts;
//Py_BEGIN_ALLOW_THREADS;
PyThreadState * m_thread_state;
m_thread_state = PyEval_SaveThread();
for(int i = 0; i < pt.rows; i++)
{
pts.push_back(cv::Point(pt.at<double>(i,0), pt.at<double>(i,1)));
}
eikeotools::CvAddenda::HOGDescriptor2::computeSubPix(im,desc,cv::Size(),cv::Size(),pts, false);
PyEval_RestoreThread(m_thread_state);
m_thread_state = NULL;
//Py_END_ALLOW_THREADS;
cv::Mat pointsMat = cv::Mat(desc);
ret = cvt.toNDArray(pointsMat);
return ret;
}
PyObject* HOGpython::computeGradient(PyObject* img)
{
// Déclaration d'instances :
cv::Mat im, grad, angleOfs;
PyObject* listeRes;
PyObject* grad_;
PyObject* angleOfs_;
// Conversion :
NDArrayConverter cvt;
im = cvt.toMat(img);
//Py_BEGIN_ALLOW_THREADS;
PyThreadState * m_thread_state;
m_thread_state = PyEval_SaveThread();
eikeotools::CvAddenda::HOGDescriptor2::computeGradient(im, grad, angleOfs, cv::Size(), cv::Size());
PyEval_RestoreThread(m_thread_state);
m_thread_state = NULL;
//Py_END_ALLOW_THREADS;
// Conversion :
grad_ = cvt.toNDArray(grad);
angleOfs_ = cvt.toNDArray(angleOfs);
// Création d'une liste Python dans laquelle les deux résultats seront enregistrés :
listeRes = PyList_New(0);
PyList_Append(listeRes, grad_);
PyList_Append(listeRes, angleOfs_);
// Renvoie des données :
return listeRes;
}
Unfortunately, I can't show my class A (part of a framework), But I can tell that A does not cause any segmentation faults.
Just to sum up my code, I would like to make a wrapper of my class A for python, and as A contains some OpenCV objects, Boost.Python can't convert them automatically, so I created B derived from A, but with some conversion from opencv objects to Python objects.
To do the conversions, I have a conversion module that's working fine. I would like to add something : Here is my main code that give me a segfault :
int main()
{
HOGpython h;
return 0;
}
Upvotes: 0
Views: 1261
Reputation: 349
Ok I solved the problem.. and it was nothing to do with my code.
The problem came from conflicting shared libraries, the framework I used was not well installed I guess. I removed it, reinstalled completely, and everything is working fine.
Problem solved !
Upvotes: 1
Reputation: 35408
This looks like a global objects' destructor (which is possibly a std::string
or something which has some relationship with an std::string
) gets called but either that object was deleted manually, either someone took ownership of that object and deleted it.
Please share more code with us, a logwriter class's source should not contain terribly sensitive data, and its presence might help actually identify the bug.
BTW, please make sure that ~B();
is actually has an implementation.
Upvotes: 1