[ace-users] Possible bug in ACE_Task_Base::cleanup.

Steve Huston shuston at riverace.com
Wed Jul 11 16:13:27 CDT 2007


That's why we added ACE_Task::last_thread() - please see the June 2006
issue of the ACE News and Tips newsletter
(http://www.riverace.com/newsletters/June2006.htm)

What?! You're not subscribed?! Subscribe to be sure you get future
issues delivered right to your Inbox at
http://www.riverace.com/newsletters/

-Steve

--
Steve Huston, Riverace Corporation
Would you like ACE to run great on your platform?
See http://www.riverace.com/sponsor.htm


> -----Original Message-----
> From: ace-users-bounces at cse.wustl.edu 
> [mailto:ace-users-bounces at cse.wustl.edu] On Behalf Of Douglas 
> C. Schmidt
> Sent: Wednesday, July 11, 2007 4:38 PM
> To: Johnny Willemsen
> Cc: ace-users at cse.wustl.edu; krivenok.dmitry at gmail.com
> Subject: Re: [ace-users] Possible bug in ACE_Task_Base::cleanup.
> 
> 
> 
> Hi Folks,
> 
>    This seems like it's becoming a FAQ ;-)  Dmitry, please 
> take a look at
> chapter 9 of C++NPv1 <www.cs.wustl.edu/~schmidt/ACE/book1> 
> and chapter 6
> of C++NPv2 <www.cs.wustl.edu/~schmidt/ACE/book2> for information on
> how/why to wait for threads before exiting main().
> 
>       Thanks,
>       
>       Doug
> 
> > Hi,
> > 
> > Thanks for using the PRF form. The thread exits when svc 
> returns, so the
> > thread count could be correct. Before exiting main you 
> should wait until all
> > threads have finished.
> > 
> > Regards,
> > 
> > Johnny Willemsen
> > Remedy IT
> > Postbus 101
> > 2650 AC  Berkel en Rodenrijs
> > The Netherlands
> > www.theaceorb.nl / www.remedy.nl  
> > 
> > *** Integrated compile and test statistics see
> > http://scoreboard.theaceorb.nl ***
> > *** Commercial service and support for ACE/TAO/CIAO
***
> > *** See http://www.theaceorb.nl/en/support.html
***
> > 
> > "Krivenok Dmitry" <krivenok.dmitry at gmail.com> wrote in message
> > news:<1184179813.151737.56650 at g4g2000hsf.googlegroups.com>...
> > >     ACE VERSION: 5.5.8
> > > 
> > >     HOST MACHINE and OPERATING SYSTEM:
> > >     1) Machine : AMD Athlon 64 3500+, 512Mb RAM
> > >     2) OS: Gentoo Linux
> > >     Kernel : 2.6.20
> > >     Glibc  : 2.5-r3
> > > 
> > >     COMPILER NAME AND VERSION (AND PATCHLEVEL):
> > >     olimpico ~ # gcc --version
> > >     gcc (GCC) 4.1.2 (Gentoo 4.1.2)
> > > 
> > >     AREA/CLASS/EXAMPLE AFFECTED:
> > > I've wrote very simple program that demonstrates the problem:
> > > 
> > > ################## Simple  example #########################
> > > 
> > > #include "ace/Task.h"
> > > #include <list>
> > > 
> > > // Active object.
> > > class Job : public ACE_Task_Base
> > > {
> > >   public:
> > >     Job()
> > >       {
> > >         // Do nothing
> > >       }
> > > 
> > >     virtual ~Job()
> > >       {
> > >         // Do nothing
> > >       }
> > > 
> > >     virtual int svc(void)
> > >       {
> > >         // Do nothing
> > >       }
> > > };
> > > 
> > > 
> > > int main()
> > > {
> > >   std::list<Job*> jobs;
> > > 
> > >   const int threads_number = 10000;
> > > 
> > >   for(int k=0; k<threads_number; ++k)
> > >     {
> > >       // Deleting all jobs that have already finished.
> > >       typedef std::list<Job*>::iterator IT;
> > >       for(IT i=jobs.begin(); i!=jobs.end(); /* NOP */)
> > >         {
> > >           // This condition isn't the same that active
> > >           // object has become passive ...
> > >           if( (*i)->thr_count() == 0 )
> > >             {
> > >               delete *i;       // and hence BOOM !!!
> > >               jobs.erase(i++);
> > >             }
> > >           else ++i;
> > >         }
> > > 
> > >       // Creating new job.
> > >       Job* job = new Job;
> > >       jobs.push_back(job);
> > > 
> > >       // Activating job (note: detached mode).
> > >       assert(job->activate(THR_NEW_LWP |
> > >                            THR_DETACHED |
> > >                            THR_INHERIT_SCHED) != -1);
> > >     }
> > >   return 0;
> > > }
> > > 
> > > ####################### Makefile ###########################
> > > BINARY=trouble
> > > 
> > > all:
> > >         g++ -g  main.cpp -lACE -pthread -o $(BINARY)
> > > clean:
> > >         rm -f $(BINARY)
> > > ############################################################
> > > 
> > > 
> > >     DOES THE PROBLEM AFFECT:
> > >         Execution only.
> > > 
> > >     SYNOPSIS:
> > > Sometimes ACE_Task_Base::thr_count() returns 0 even if the
> > > object is still active!
> > > 
> > >     DESCRIPTION:
> > > Documentation says about ACE_Task_Base::thr_count():
> > > Returns the number of threads currently running within a task.
> > > If we're a passive object this value is 0, else it's 
> greater than 0.
> > > 
> > > The problem lies in that sometimes ACE_Task_Base::thr_count()
> > > returns 0 even if the object is still active!
> > > 
> > > Look at the code of ACE_Task_Base::cleanup (with my comments):
> > > 
> > > 00227 {
> > > 00228   ACE_Task_Base *t = (ACE_Task_Base *) object;
> > > 00229
> > > 00230   // The thread count must be decremented first in case
the
> > > <close>
> > > 00231   // hook does something crazy like "delete this".
> > > 00232   {
> > > 00233     ACE_MT (ACE_GUARD (ACE_Thread_Mutex, ace_mon, 
> t->lock_));
> > > Threads counter is decremented here!
> > > 00234     t->thr_count_--;
> > > 00235     if (0 == t->thr_count_)
> > > 00236       t->last_thread_id_ = ACE_Thread::self ();
> > > After this line the lock will be released.
> > > 00237   }
> > > Suppose that another thread (for example main thread in 
> my program)
> > > is checking object's state (active or passive) right now.
> > > It calls thr_count() that returns 0, since we have just 
> decremented
> > > the value of thr_count_.
> > > So, if the object is in passive mode it's safe to delete them.
> > > Am I right?
> > > And another thread deletes active object using delete operator.
> > > 00238
> > > 00239   // @@ Is it possible to pass in the exit status somehow?
> > > However this object is still active.
> > > The problem is that it has been already destroyed by 
> another thread!!!
> > > What happens at this line?
> > > 00240   t->close ();
> > > Segmentation fault in my case!!!
> > > 00241   // t is undefined here. close() could have deleted it.
> > > 00242 }
> > > 
> > >     REPEAT BY:
> > > I run my test program several times as follows:
> > > for ((i=1;i<100;i++)) do echo $i ; ./trouble ; done
> > > 1
> > > 2
> > > 3
> > > ...
> > > ...
> > > ...
> > > 91
> > > 92
> > > 93
> > > Segmentation fault (core dumped)
> > > 94
> > > 95
> > > 96
> > > 97
> > > 98
> > > 99
> > > 
> > > 
> > > What you think about this problem?
> > > Is it a bug of ACE_Task_Base class?
> > > 
> > 
> > _______________________________________________
> > ace-users mailing list
> > ace-users at mail.cse.wustl.edu
> > http://mail.cse.wustl.edu/mailman/listinfo/ace-users
> 
> _______________________________________________
> ace-users mailing list
> ace-users at mail.cse.wustl.edu
> http://mail.cse.wustl.edu/mailman/listinfo/ace-users
> 




More information about the Ace-users mailing list