c++ - Understanding AddressSanitizer global-buffer-overflow error -


edit i

the original error below came when compiling g++ 4.8 (installed devtoolset-2 on 32-bit centos 6).

because __attribute__((no_sanitize_address)) doesn't work in cases on g++ 4.8, spent day compiling gcc 4.9 source.

there no longer errors addresssanitizer!

does mean gcc 4.8 produced defective code in first place? or addresssanitizer under 4.8 reported non-existent errors? or gcc 4.9 produces better code? or addresssanitizer under gcc 4.9 can't find errors?

original

addresssanitizer complains of global-buffer-overflow, don't understand why: aborts when calling method of object (via pointer base class):

const char *typename = key->gettypename();  // <<<=== boom! 

i've ready many posts global-buffer-overflow being wrongly detected. 1 of them? how tell? (could vtable dvdbipstreaminfo object being corrupted? if so, wouldn't addresssanitizer catch that?)

code outline: factory used create multiple objects via template. many other objects created prior without problem. why one?

(edit ii)

//! mixin class objects can save , restore state. class dvcsrserializable { public:     //! name of type of serializable object.     virtual dvcsr::tname gettypename(void) const = 0; protected:     virtual ~dvcsrserializable() {} };  class dvdbdatabaseobject : public dvcsrserializable { public:     virtual ~dvdbdatabaseobject() {}     //! unique object type id derived database object class.     virtual dvdb::tobjecttype getdbobjecttype() const = 0;  protected:     //! ctor abstract base class.     dvdbdatabaseobject() : mchanged(false) {}      //! copy ctor.     dvdbdatabaseobject(const dvdbdatabaseobject&) :         dvcsrserializable(), mchanged(false)  {}      typedef std::tr1::unordered_set<dvdbdatabaseobject*, hash, equalp<dvdbdatabaseobject> > ttable;      #define dvdb_declare_table(objclass) \         dvdbdatabaseobject::ttable objclass::m_table(dv::max_num_of_slots + 1);  protected:     //! flag indicating database object has changed.     bool mchanged;     };   static dvdbobjectfactory<dvdb::ipstreaminfo, dvdbipstreaminfo> ipstreaminfofactory;  class dvdbipstreaminfo : public dvdbdatabaseobject { public:     dvdbipstreaminfo() { printf("dvdbipstreaminfo ctor: this=%p\n", this); }     virtual ~dvdbipstreaminfo() { }     const char *gettypename() const { return "ipstreaminfo"; } } 

the factory template

//! base class database object factory. class dvdbobjectfactorybc { public:     virtual dvdbdatabaseobject* createdbobject() = 0; protected:     virtual ~dvdbobjectfactorybc() {} };        template <dvdb::tobjecttype ot, class t > class dvdbobjectfactory : public dvdbobjectfactorybc { public:     typedef t                       tobject;     static const dvdb::tobjecttype  tobjecttype = ot;      dvdbobjectfactory() { dvdbdatabasemanager::instance()->registerdbobjclass(tobjecttype, this); }     virtual ~dvdbobjectfactory() {}     tobject*       createdbobject()     { return new tobject; } }; 

and "database manager" creates , maintains list of objects:

void dvdbdatabasemanager::registerdbobjclass(     dvdb::tobjecttype    objectid,     dvdbobjectfactorybc* factory) {     trace(("%n registerdbobjclass objectid %d. factory = 0x%x\n", objectid, factory));      dvdbdatabaseobject* key = factory->createdbobject();     printf("object %d created key=%p. calling gettypename()...\n", objectid, key);     const char *typename = key->gettypename();  // <<<=== boom!      trace(("%n register database id[%d] '%s' key=%x. \n", objectid, typename, key));     mkeyfornamemap[typename] = key; } 

addresssanitizer aborts calling key->gettypename() (for object only). error below, don't it.

it says error reading address

ipbandwidth gettypename. tn=0x0xb5ffcc60 *tn=ipbandwidth dvdbdatabasemanager.cpp register database id[350] 'ipbandwidth' key=b1a00cd0. =================================================================  ==10596== error: addresssanitizer: global-buffer-overflow on address 0x08230ca8 @ pc 0xb54ddf08 bp 0xbfb96988 sp 0xbfb9697c read of size 4 @ 0x08230ca8 thread t0     #0 0xb54ddf07 (/usr/local/dvstation/lib/libdvdb.so.6.0-38b15+0xe3f07)     #1 0xb5f4fee6 (/usr/local/dvstation/lib/libdvdbip.so.6.0-38b15+0x11cee6)     #2 0xb5f4f7e7 (/usr/local/dvstation/lib/libdvdbip.so.6.0-38b15+0x11c7e7)     #3 0xb5f4f89f (/usr/local/dvstation/lib/libdvdbip.so.6.0-38b15+0x11c89f)     #4 0x42de7046 (/lib/ld-2.12.so+0xf046)     #5 0x42dd888e (/lib/ld-2.12.so+0x88e)  0x08230ca8 located 36 bytes right of global variable 'mpinstance (dviptimers.cpp)' (0x8230c80) of size 4   'mpinstance (dviptimers.cpp)' ascii string ''  shadow bytes around buggy address:    0x21046140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    0x21046150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    0x21046160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    0x21046170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    0x21046180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x21046190: 04 f9 f9 f9 f9[f9]f9 f9 00 00 00 00 00 00 00 00 

according addr2line, libdvdb.so.6.0-38b15+0xe3f07 resolves const char *typename = key->gettypename();


Comments

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -