[Ace-users] Re: Possible bug in ACE_Task_Base::cleanup.

Krivenok Dmitry krivenok.dmitry at gmail.com
Thu Jul 12 02:46:40 CDT 2007


On Jul 12, 1:13 am, "Steve Huston" <shus... at riverace.com> wrote:
> 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 athttp://www.riverace.com/newsletters/
>
> -Steve
>
> --
> Steve Huston, Riverace Corporation
> Would you like ACE to run great on your platform?
> Seehttp://www.riverace.com/sponsor.htm
>
>
>
> > -----Original Message-----
> > From: ace-users-boun... at cse.wustl.edu
> > [mailto:ace-users-boun... at cse.wustl.edu] On Behalf Of Douglas
> > C. Schmidt
> > Sent: Wednesday, July 11, 2007 4:38 PM
> > To: Johnny Willemsen
> > Cc: ace-us... at cse.wustl.edu; krivenok.dmi... 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 for irrefragable answer :)
Ok, I will carefully read both of your books.

Sorry for my question if it was so stupid.
I'm newbie in programming with ACE.

Yes, I agree that the cause of seg fault in _this_ test program
lies in that main thread exits while there is at least one active Job
thread.
It was my oversight while writing test program.

What if a add the following line
ACE_OS::sleep(60 * 60 * 24); // HACK
before return operator in main() function?

In such a case main thread sleeps for a day.
It's a hack of course :)
However, SIGSEGV signal may be generated if object
of class Job has been deleted in the main thread
after decrementing threads count, but before
calling close() hook in cleanup() method of Job thread.
So, close() method will be called on previously deleted
object!
Am I wrong?

>
> >       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
> ***
> > > *** Seehttp://www.theaceorb.nl/en/support.html
> ***
>
> > > "Krivenok Dmitry" <krivenok.dmi... 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-us... at mail.cse.wustl.edu
> > >http://mail.cse.wustl.edu/mailman/listinfo/ace-users
>
> > _______________________________________________
> > ace-users mailing list
> > ace-us... at mail.cse.wustl.edu
> >http://mail.cse.wustl.edu/mailman/listinfo/ace-users




More information about the Ace-users mailing list