views:

784

answers:

6

I have a piece of code looking like this :

TAxis *axis = 0;
if (dynamic_cast<MonitorObjectH1C*>(obj))
   axis = (dynamic_cast<MonitorObjectH1C*>(obj))->GetXaxis();

Sometimes it crashes :

Thread 1 (Thread -1208658240 (LWP 11400)):
#0  0x0019e7a2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
#1  0x048c67fb in __waitpid_nocancel () from /lib/tls/libc.so.6
#2  0x04870649 in do_system () from /lib/tls/libc.so.6
#3  0x048709c1 in system () from /lib/tls/libc.so.6
#4  0x001848bd in system () from /lib/tls/libpthread.so.0
#5  0x0117a5bb in TUnixSystem::Exec () from /opt/root/lib/libCore.so.5.21
#6  0x01180045 in TUnixSystem::StackTrace () from /opt/root/lib/libCore.so.5.21
#7  0x0117cc8a in TUnixSystem::DispatchSignals ()
   from /opt/root/lib/libCore.so.5.21
#8  0x0117cd18 in SigHandler () from /opt/root/lib/libCore.so.5.21
#9  0x0117bf5d in sighandler () from /opt/root/lib/libCore.so.5.21
#10 <signal handler called>
#11 0x0533ddf4 in __dynamic_cast () from /usr/lib/libstdc++.so.6

I have no clue why it crashes. obj is not null (and if it was it would not be a problem, would it ?).

What could be the reason for a dynamic cast to crash ?

If it can't cast, it should just return NULL no ?

+1  A: 

Can the value of obj be changed by a different thread?

James Curran
Good intuition ! Another thread was freeing 'obj'.
Barth
+2  A: 

dynamic_cast will return 0 if the cast fails and you are casting to a pointer, which is your case. The problem is that you have either corrupted the heap earlier in your code, or rtti wasn't enabled.

David Nehme
+2  A: 

Are you sure that the value of 'obj' has been correctly defined?

If for example it is uninitialised (ie random) them I could see it causing a crash.

Martin York
Indeed, 'obj' was freed by another thread. Thanks for your help
Barth
+1  A: 

As it crashes only sometimes, i bet it's a threading issue. Check all references to 'obj':

grep -R 'obj.*=' .
Johannes Schaub - litb
+9  A: 

I suggest using a different syntax for this code snippet.

if (MonitorObjectH1C* monitorObject = dynamic_cast<MonitorObjectH1C*>(obj))
{
    axis = monitorObject->GetXaxis();
}

You can still crash if some other thread is deleting what monitorObject points to or if obj is crazy garbage, but at least your problem isn't casting related anymore and you're not doing the dynamic_cast twice.

bradtgmurray
Indeed, 'obj' was freed by another thread and this caused the crash. Thanks for your help !
Barth
+9  A: 

Some possible reasons for the crash:

  • obj points to an object with a non-polymorphic type (a class or struct with no virtual methods, or a fundamental type).
  • obj points to an object that has been freed.
  • obj points to unmapped memory, or memory that has been mapped in such a way as to generate an exception when accessed (such as a guard page or inaccessible page).
  • obj points to an object with a polymorphic type, but that type was defined in an external library that was compiled with RTTI disabled.

Not all of these problems necessarily cause a crash in all situations.

bk1e
I am setting this answer as the accepted one, as it lists several possiblereasons for the crash and it seems useful for other people who would have thesame problem.
Barth
A really awesome answer.
DavidG