In our application we observe a crash after its execution. The stack trace shows that the crash is because of the global variable pres开发者_开发百科ent in the cpp file. The valgrind report generated shows the invalid free/read/write error, which means that it is trying to delete a memory which is no longer valid.
File: crash.cpp
namespace abc
{
MutexClass obj; //A is a class
// remaining code
ChildClass::ChildClass():Parent(obj){}
}
We then placed the given variable in an unnamed namespace, and we no longer get the crash and the valgrind does not report an invalid read/write/error:
File: nocrash.cpp
namespace
{
MutexClass obj;
}
namespace abc
{
// remaining code
ChildClass::ChildClass():Parent(obj){}
}
The above examples are a stripped down version of the class causing the problem.
We are not sure why placing the variable in unnamed namespace removes this problem. Does it change the clean-up order? We tried writing simple code but the clean-up order we observed were same for both the cases.
The Mutex object is passed as parameter to base class constructor. The only purpose of the Mutex object is to used in the base class constructor. The Mutex object is not used anywhere else in the code.
The valgrind report for the crash
=================================================
Thread 1:
Invalid read of size 1
at 0x3A24C08260: pthread_mutex_destroy (in /lib64/libpthread-2.5.so)
by 0x5ABE3DD: osl_destroyMutex (libuno_sal.so.3)
by 0xECD69D1: osl::Mutex::~Mutex() (mutex.hxx:65)
by 0xEF207F5: __tcf_0 (Dispose.cpp:27)
by 0x3A24033354: exit (in /lib64/libc-2.5.so)
by 0x3A2401D97A: (below main) (in /lib64/libc-2.5.so)
Address 0xeb6bb88 is 16 bytes inside a block of size 40 free'd
at 0x4A05B3E: free (vg_replace_malloc.c:323)
by 0x3A24033354: exit (in /lib64/libc-2.5.so)
by 0x3A2401D97A: (below main) (in /lib64/libc-2.5.so)
Invalid write of size 4
at 0x3A24C08272: pthread_mutex_destroy (in /lib64/libpthread-2.5.so)
by 0x5ABE3DD: osl_destroyMutex (in libuno_sal.so.3)
by 0xECD69D1: osl::Mutex::~Mutex() (mutex.hxx:65)
by 0xEF207F5: __tcf_0 (Dispose.cpp:27)
by 0x3A24033354: exit (in /lib64/libc-2.5.so)
by 0x3A2401D97A: (below main) (in /lib64/libc-2.5.so)
Address 0xeb6bb88 is 16 bytes inside a block of size 40 free'd
at 0x4A05B3E: free (vg_replace_malloc.c:323)
by 0x3A24033354: exit (in /lib64/libc-2.5.so)
by 0x3A2401D97A: (below main) (in /lib64/libc-2.5.so)
Invalid free() / delete / delete[]
at 0x4A05B3E: free (vg_replace_malloc.c:323)
by 0xECD69D1: osl::Mutex::~Mutex() (mutex.hxx:65)
by 0xEF207F5: __tcf_0 (Dispose.cpp:27)
by 0x3A24033354: exit (in /lib64/libc-2.5.so)
by 0x3A2401D97A: (below main) (in /lib64/libc-2.5.so)
Address 0xeb6bb78 is 0 bytes inside a block of size 40 free'd
at 0x4A05B3E: free (vg_replace_malloc.c:323)
by 0x3A24033354: exit (in /lib64/libc-2.5.so)
by 0x3A2401D97A: (below main) (in /lib64/libc-2.5.so)
=================================================
The Dispose.cpp :27 line has the mutex variable defined.
We would appreciate any help on this matter
Thanks,
Sudeep
Check your other files. You probably have another global variable named obj in the namespace abc. Changing to the unnamed namespace have the same effect to static in C, which avoid name collisions (and if this is the problably, any other namespace different from abc will also stop the problem). This kind of error usually result in a link error, but sometimes weird things happen.
Note that global variables, which won't be used by other files, should be in the unnamed namespace, to avoid name collisions.
There are no issues with the code you've shown us.
Perhaps the issue is with the class A
?
Is your variable using a name with a starting underscore?
If this is the case then it's normal that you found troubles.
Global names with an initial underscore are reserved and should not be used. Also names with an initial underscore followed by a capital letter in any context, or names with multiple contiguous underscores.
This is a rule that for reasons I don't really understand are often broken by many programmers just for the fun of doing it...
Moving the code like you did will re-order the construction and destruction of A
relative to other globals in the same Translation Unit. If you created A earlier, it will be deleted later. (LIFO principle). Other objects may now be able to rely on A
. Check which objects were previously created before A
, and now after A
.
精彩评论