[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::c_plus_plus

Title:C++
Notice:Read 1.* and use keywords (e.g. SHOW KEY/FULL KIT_CXX_VAX_VMS)
Moderator:DECCXX::AMARTIN
Created:Fri Nov 06 1987
Last Modified:Thu Jun 05 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:3604
Total number of notes:18242

3513.0. "Troubles with DEC C++ V5.4-6 on Digital UNIX V3.2G" by TAEC::GALLERI () Tue Mar 25 1997 10:13

Hi,

I have a quite amazing problem with DEC C++ V5.4-6 on Digital UNIX V3.2G
related (I guess :-) to template definitions.

I have defined a C++ wrapper for thread management that is templated on
both class owner and argument types. In my soft, this is used dynamically
(I mean, I am creating and deleting thread wrapper objects several times
during my process' life). What I have noticed is that at a specific location
in my source code, the destructor for my thread wrapper is not called, whilst
the `::delete' routine is, and I eventually came to the conclusion that there
might well be a bug in the C++ compiler.

The source looks like this:

        for ( VI_idx = 0 ; VI_idx < EI_adapter_num ; VI_idx ++ )
        {
          delete EA_talker_task   [ VI_idx ] ;
          delete EA_listener_task [ VI_idx ] ;
        }

I have first noticed that calling the `delete EA_talker_task [ VI_idx ]'
twice results in the destructor being called only the second time, !?!?
For sure, I had a look at the generated assembly code and assert the
same thing !?!?

In the end, I have found the following workaround:

        for ( VI_idx = 0 ; VI_idx < EI_adapter_num ; VI_idx ++ )
        {
          goto NEVER_CALLED ;                           // !?!
          delete EA_talker_task   [ VI_idx ] ;          // !?!
          NEVER_CALLED:                                 // !?!

          delete EA_talker_task   [ VI_idx ] ;
          delete EA_listener_task [ VI_idx ] ;
        }

This seems to make the bad assembly code being expanded for the first
statement, and then removed by some pseudo-optimisation due to the fact
that the statement is never called at run-time. So that, in the end,
only the good assembly code is present and called !?!?!?

To help you understand this issue, I have appended some interesting
output from debugging sessions that make evidence of what's going on.

Now, I would appreciate if someone can bring some light on this matter.
Is it a known problem ? Is there a fix ? Should I log a QAR ? In case,
in which database ?

Thank you very much for your attention,

Xav

======================================================================

This is the bad code sampling:

(ladebug)     352   // Exit from critical section
    353
    354   EC_peer_info_mutex.FV_rel () ;
    355
    356   // Then, stop everything currently running (if any).
    357
    358   if ( EI_adapter_num > 0 )
    359   {
    360     // First, delete service tasks.
    361
>   362     for ( VI_idx = 0 ; VI_idx < EI_adapter_num ; VI_idx ++ )
    363     {
    364 //goto NEVER_CALLED ;
    365 //delete EA_talker_task [ VI_idx ] ;
    366 //NEVER_CALLED:
    367       delete EA_talker_task   [ VI_idx ] ;
    368       delete EA_listener_task [ VI_idx ] ;
    369     }
    370
    371     // Then, send `GoodBye' messages on every adapters prior
(ladebug) >0  0x12001b668 in ((TC_failfast*)0x31008)->FV_reset_config() failfast.cc:362
#1  0x12001b884 in ((TC_failfast*)0x31008)->FV_configure() failfast.cc:453
#2  0x12001c364 in ((TC_failfast*)0x31008)->FV_signal_dispatcher() failfast.cc:825
#3  0x12001a84c in TC_argd_task_<TC_failfast,int>::FV_entry(AR_task={ ... }) task_.hh:???
#4  0x3ff80841ccc in /usr/shlib/libpthreads.so
(ladebug) *[void TC_failfast::FV_reset_config(void):362, 0x12001b668]   bis     r31, r31, r9
 [void TC_failfast::FV_reset_config(void):362, 0x12001b66c]     ldl     r1, 48(r10)
 [void TC_failfast::FV_reset_config(void):362, 0x12001b670]     cmpult  r9, r1, r1
 [void TC_failfast::FV_reset_config(void):362, 0x12001b674]     beq     r1, 0x12001b6c8
 [void TC_failfast::FV_reset_config(void):367, 0x12001b678]     ldq     r2, 72(r10)
 [void TC_failfast::FV_reset_config(void):367, 0x12001b67c]     zapnot  r9, 0xf, r3
 [void TC_failfast::FV_reset_config(void):367, 0x12001b680]     mulq    r3, 0x8, r3
 [void TC_failfast::FV_reset_config(void):367, 0x12001b684]     addq    r2, r3, r2
 [void TC_failfast::FV_reset_config(void):367, 0x12001b688]     ldq     r16, 0(r2)
 [void TC_failfast::FV_reset_config(void):367, 0x12001b68c]     beq     r16, 0x12001b6a0
 [void TC_failfast::FV_reset_config(void):367, 0x12001b690]     ldq     r27, -31904(gp)
 [void TC_failfast::FV_reset_config(void):367, 0x12001b694]     jsr     r26, (r27), 0x12001e9d0(r31)	<= ::delete
 [void TC_failfast::FV_reset_config(void):367, 0x12001b698]     ldah    gp, 8191(r26)
 [void TC_failfast::FV_reset_config(void):367, 0x12001b69c]     lda     gp, -11656(gp)
 [void TC_failfast::FV_reset_config(void):368, 0x12001b6a0]     ldq     r0, 64(r10)
 [void TC_failfast::FV_reset_config(void):368, 0x12001b6a4]     zapnot  r9, 0xf, r1
 [void TC_failfast::FV_reset_config(void):368, 0x12001b6a8]     mulq    r1, 0x8, r1
 [void TC_failfast::FV_reset_config(void):368, 0x12001b6ac]     addq    r0, r1, r0
 [void TC_failfast::FV_reset_config(void):368, 0x12001b6b0]     ldq     r16, 0(r0)
 [void TC_failfast::FV_reset_config(void):368, 0x12001b6b4]     beq     r16, 0x12001b6c0
 [void TC_failfast::FV_reset_config(void):368, 0x12001b6b8]     bis     r31, 0x5, r17
 [void TC_failfast::FV_reset_config(void):368, 0x12001b6bc]     bsr     r26,~TC_argd_task_<TC_failfast,TC_adapter*>
 [void TC_failfast::FV_reset_config(void):362, 0x12001b6c0]     addl    r9, 0x1, r9
 [void TC_failfast::FV_reset_config(void):369, 0x12001b6c4]     br      r31, 0x12001b66c
 [void TC_failfast::FV_reset_config(void):375, 0x12001b6c8]     ldah    r16, -8191(gp)
 [void TC_failfast::FV_reset_config(void):375, 0x12001b6cc]     lda     r16, -29080(r16)
 [void TC_failfast::FV_reset_config(void):375, 0x12001b6d0]     ldl     r17, 48(r10)
 [void TC_failfast::FV_reset_config(void):375, 0x12001b6d4]     ldq     r27, -31376(gp)
 [void TC_failfast::FV_reset_config(void):375, 0x12001b6d8]     jsr     r26, (r27), 0x12001e4a0(r31)
 [void TC_failfast::FV_reset_config(void):375, 0x12001b6dc]     ldah    gp, 8191(r26)
(ladebug)

======================================================================

This is the workaround code sampling:

(ladebug)     352   // Exit from critical section
    353
    354   EC_peer_info_mutex.FV_rel () ;
    355
    356   // Then, stop everything currently running (if any).
    357
    358   if ( EI_adapter_num > 0 )
    359   {
    360     // First, delete service tasks.
    361
>   362     for ( VI_idx = 0 ; VI_idx < EI_adapter_num ; VI_idx ++ )
    363     {
    364 goto NEVER_CALLED ;
    365 delete EA_talker_task [ VI_idx ] ;
    366 NEVER_CALLED:
    367       delete EA_talker_task   [ VI_idx ] ;
    368       delete EA_listener_task [ VI_idx ] ;
    369     }
    370
    371     // Then, send `GoodBye' messages on every adapters prior
(ladebug) >0  0x12001b668 in ((TC_failfast*)0x31008)->FV_reset_config() failfast.cc:362
#1  0x12001b87c in ((TC_failfast*)0x31008)->FV_configure() failfast.cc:453
#2  0x12001c35c in ((TC_failfast*)0x31008)->FV_signal_dispatcher() failfast.cc:825
#3  0x12001a84c in TC_argd_task_<TC_failfast,int>::FV_entry(AR_task={ ... }) task_.hh:???
#4  0x3ff80841ccc in /usr/shlib/libpthreads.so
(ladebug) *[void TC_failfast::FV_reset_config(void):362, 0x12001b668]   bis     r31, r31, r9
 [void TC_failfast::FV_reset_config(void):362, 0x12001b66c]     br      r31, 0x12001b6b4
 [void TC_failfast::FV_reset_config(void):367, 0x12001b670]     ldq     r1, 72(r10)
 [void TC_failfast::FV_reset_config(void):367, 0x12001b674]     zapnot  r9, 0xf, r2
 [void TC_failfast::FV_reset_config(void):367, 0x12001b678]     mulq    r2, 0x8, r2
 [void TC_failfast::FV_reset_config(void):367, 0x12001b67c]     addq    r1, r2, r1
 [void TC_failfast::FV_reset_config(void):367, 0x12001b680]     ldq     r16, 0(r1)
 [void TC_failfast::FV_reset_config(void):367, 0x12001b684]     beq     r16, 0x12001b690
 [void TC_failfast::FV_reset_config(void):367, 0x12001b688]     bis     r31, 0x5, r17
 [void TC_failfast::FV_reset_config(void):367, 0x12001b68c]     bsr     r26, ~TC_argd_task_<TC_failfast,TC_adapter*>
 [void TC_failfast::FV_reset_config(void):368, 0x12001b690]     ldq     r0, 64(r10)
 [void TC_failfast::FV_reset_config(void):368, 0x12001b694]     zapnot  r9, 0xf, r1
 [void TC_failfast::FV_reset_config(void):368, 0x12001b698]     mulq    r1, 0x8, r1
 [void TC_failfast::FV_reset_config(void):368, 0x12001b69c]     addq    r0, r1, r0
 [void TC_failfast::FV_reset_config(void):368, 0x12001b6a0]     ldq     r16, 0(r0)
 [void TC_failfast::FV_reset_config(void):368, 0x12001b6a4]     beq     r16, 0x12001b6b0
 [void TC_failfast::FV_reset_config(void):368, 0x12001b6a8]     bis     r31, 0x5, r17
 [void TC_failfast::FV_reset_config(void):368, 0x12001b6ac]     bsr     r26, ~TC_argd_task_<TC_failfast,TC_adapter*>
 [void TC_failfast::FV_reset_config(void):362, 0x12001b6b0]     addl    r9, 0x1, r9
 [void TC_failfast::FV_reset_config(void):362, 0x12001b6b4]     ldl     r0, 48(r10)
(ladebug)

T.RTitleUserPersonal
Name
DateLines
3513.1Fixed in V5.5DECCXX::RMEYERSRandy MeyersWed Mar 26 1997 21:1110
After experimenting with your sources, I was able to determine that your
problem is a duplicate of the problem reported in Note 3073.4.

Basically, if the instantiation of the destructor is pending when the
delete operator is used, then the compiler will not find the destructor.
The symptom is that the first object of that type deleted will not
use the destructor, but later objects deleted will.

This problem is fixed in V5.5 of the compiler, which is the latest field
image version of the compiler.  You might want to consider upgrading.