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
Post a Comment