Usermode C++ classes vtable problem: Function never returns
Posted: Sun Jan 12, 2020 7:59 am
Hi,
I am writing my own stdc/stdc++ libraries as an exercise. I have support for usermode and I have been running binary format code with no problems.
The problem arises when I started adding more template classes in my stdc++ library. I am expanding the std:vector to support a hierarchy with a vector base class and a numbert of specialization templates for different primitive types, e.g. double, float, int, ... etc.
The problem appears at random where in some random places in the code while running inside some function execution is transferred to address 0x0 and the function never returns causing a page fault.
For example I use a local variable object inside a function vector <float> f; when the specialization class template is defined the problem occurs, when I comment out the specialization template the code works. The confusing thing is that with the specialization template enabled as I add some printfs the code runs well and as soon as I comment them out the problem appears?
I am assuming that I might have some corruption in the vtables as the number of classes gets larger.
My questions are:
1. Where exactly is the vtable stored? in which section?
2. How can I make sure to enlarge the space for it ?
3. Is there anything needs to be done in the linker file?
Any ideas what it could be and how to solve it?
Thanks,
Karim.
I am writing my own stdc/stdc++ libraries as an exercise. I have support for usermode and I have been running binary format code with no problems.
The problem arises when I started adding more template classes in my stdc++ library. I am expanding the std:vector to support a hierarchy with a vector base class and a numbert of specialization templates for different primitive types, e.g. double, float, int, ... etc.
Code: Select all
template<typename T>
class basic_vector {
protected:
T *t;
size_t vec_alloc;
size_t vec_capacity;
size_t vec_size;
public:
typedef std::iterator<bidirectional_iterator_tag, T> iterator;
typedef std::iterator<bidirectional_iterator_tag, const T> const_iterator;
typedef size_t size_type;
basic_vector();
basic_vector(size_type n);
virtual void resize(size_type n);
virtual void resize(size_type n, const T &val);
virtual iterator begin() noexcept;
virtual const_iterator begin() const noexcept;
virtual iterator end() noexcept;
virtual const_iterator end() const noexcept;
virtual T &back();
virtual T &front();
virtual bool empty();
virtual void clear();
virtual T &operator[](size_type index);
virtual const T &operator[](size_type index) const;
virtual void push_back(const T &val);
virtual void push_back(T &&val);
virtual size_t size() const noexcept;
virtual size_t capacity() const noexcept;
virtual void assign(iterator first, iterator last);
virtual void assign(std::string::const_iterator first, std::string::const_iterator last);
virtual void assign(size_type n, const T &val);
virtual void swap(basic_vector &x);
virtual ~basic_vector();
};
template<typename T>
class vector: public basic_vector<T> {
public:
typedef std::iterator<bidirectional_iterator_tag, T> iterator;
typedef std::iterator<bidirectional_iterator_tag, const T> const_iterator;
typedef size_t size_type;
vector();
vector(size_type n);
void resize(size_type n);
void resize(size_type n, const T &val);
void clear();
~vector();
};
template<>
class vector <float>: public basic_vector<float> {
public:
typedef std::iterator<bidirectional_iterator_tag, float> iterator;
typedef std::iterator<bidirectional_iterator_tag, const float> const_iterator;
typedef size_t size_type;
vector();
vector(size_type n);
~vector();
};
template<>
class vector <int>: public basic_vector<int> {
public:
typedef std::iterator<bidirectional_iterator_tag, int> iterator;
typedef std::iterator<bidirectional_iterator_tag, const int> const_iterator;
typedef size_t size_type;
vector();
vector(size_type n);
~vector();
};
template<>
class vector <int *>: public basic_vector<int *> {
public:
typedef std::iterator<bidirectional_iterator_tag, int *> iterator;
typedef std::iterator<bidirectional_iterator_tag, const int *> const_iterator;
typedef size_t size_type;
vector();
vector(size_type n);
~vector();
};
template<>
class vector <double>: public basic_vector<double> {
public:
typedef std::iterator<bidirectional_iterator_tag, double> iterator;
typedef std::iterator<bidirectional_iterator_tag, const double> const_iterator;
typedef size_t size_type;
vector();
vector(size_type n);
~vector();
};
template<>
class vector <char>: public basic_vector<char> {
public:
typedef std::iterator<bidirectional_iterator_tag, char> iterator;
typedef std::iterator<bidirectional_iterator_tag, const char> const_iterator;
typedef size_t size_type;
vector();
vector(size_type n);
~vector();
};
template<>
class vector <unsigned char>: public basic_vector<unsigned char> {
public:
typedef std::iterator<bidirectional_iterator_tag, unsigned char> iterator;
typedef std::iterator<bidirectional_iterator_tag, const unsigned char> const_iterator;
typedef size_t size_type;
vector();
vector(size_type n);
~vector();
};
The problem appears at random where in some random places in the code while running inside some function execution is transferred to address 0x0 and the function never returns causing a page fault.
For example I use a local variable object inside a function vector <float> f; when the specialization class template is defined the problem occurs, when I comment out the specialization template the code works. The confusing thing is that with the specialization template enabled as I add some printfs the code runs well and as soon as I comment them out the problem appears?
I am assuming that I might have some corruption in the vtables as the number of classes gets larger.
My questions are:
1. Where exactly is the vtable stored? in which section?
2. How can I make sure to enlarge the space for it ?
3. Is there anything needs to be done in the linker file?
Any ideas what it could be and how to solve it?
Thanks,
Karim.