Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[ace-users] ACE_OS::mktime() ACE_OS::getservbyname_r() bug that causes a hang

142 views
Skip to first unread message

Jody Hagins

unread,
Jan 7, 1999, 3:00:00 AM1/7/99
to

Replace/remove all the explanatory text in brackets before mailing.

ACE VERSION: 4.6

HOST MACHINE and OPERATING SYSTEM:
Linux uzi.atdesk.com 2.0.34 #9 Fri Nov 13 14:37:47 EST 1998 i686 unknown


TARGET MACHINE and OPERATING SYSTEM, if different from HOST:
COMPILER NAME AND VERSION:
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.57/specs
gcc version egcs-2.91.57 19980901 (egcs-1.1 release)


AREA/CLASS/EXAMPLE AFFECTED:
ACE_OS::mktime() and ACE_OS::getservbyname_r()

SYNOPSIS:
Program hangs on call to ACE_OS::getservbyname_r() after ACE_OS::mktime()
has been called. Only happens if ACE is built multithread enabled.

DESCRIPTION:
The following test program demonstrates an example where the program calls
ACE_OS::mktime(). After that, the program calls ACE_OS::getservbyname_r(),
and that call hangs (i.e. never returns).

If I replace ACE_OS::mktime() with ::mktime() the program functions as
expected.

REPEAT BY:

Here is a test program.

#include "ace/SOCK_Connector.h"
#include "ace/INET_Addr.h"
#include "ace/Thread.h"
#include "ace/OS.h"
#include "ace/Read_Buffer.h"
#include "ace/Synch_T.h"
#include "ace/Synch.h"

#define SHOW_BUG

unsigned int baseTime;

int main (int argc, char ** argv)
{
servent sentry;
servent *sp;
ACE_SERVENT_DATA buf;
cerr << __FILE__ << ": " << __LINE__ << endl;
time_t timeNow = ACE_OS::time();
tm t;
ACE_OS::localtime_r(&timeNow, &t);
t.tm_hour = t.tm_min = t.tm_sec = 0;
#if defined(SHOW_BUG)
baseTime = (unsigned int)ACE_OS::mktime(&t);
#else
baseTime = (unsigned int)::mktime(&t);
#endif
cerr << __FILE__ << ": " << __LINE__ << endl;
sp = ACE_OS::getservbyname_r ("otchitter", "tcp", &sentry, buf);
ACE_OS::localtime_r(&timeNow, &t);
cerr << __FILE__ << ": " << __LINE__ << endl;
for (;;)
{
cerr << __FILE__ << ": " << __LINE__ << endl;
ACE_OS::sleep(2);
}
}

SAMPLE FIX/WORKAROUND:
Use ::mktime() instead of ACE_OS::mktime().

David Levine

unread,
Jan 7, 1999, 3:00:00 AM1/7/99
to
Jody writes:

> HOST MACHINE and OPERATING SYSTEM:
> Linux uzi.atdesk.com 2.0.34 #9 Fri Nov 13 14:37:47 EST 1998 i686 unknown

> AREA/CLASS/EXAMPLE AFFECTED:


> ACE_OS::mktime() and ACE_OS::getservbyname_r()
>
> SYNOPSIS:
> Program hangs on call to ACE_OS::getservbyname_r() after ACE_OS::mktime()
> has been called. Only happens if ACE is built multithread enabled.
>
> DESCRIPTION:
> The following test program demonstrates an example where the program calls
> ACE_OS::mktime(). After that, the program calls ACE_OS::getservbyname_r(),
> and that call hangs (i.e. never returns).
>
> If I replace ACE_OS::mktime() with ::mktime() the program functions as
> expected.

How strange. ACE_OS::mktime () is thread safe; ::mktime () isn't.
ACE_OS::mktime () just guards ::mktime ():

ACE_MT (ACE_Thread_Mutex *ace_os_monitor_lock =
ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object
(ACE_Object_Manager::ACE_OS_MONITOR_LOCK);
ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *ace_os_monitor_lock, (time_t) -1));

ACE_OSCALL_RETURN (::mktime (t), time_t, (time_t) -1);

If you remove the ACE_GUARD_RETURN (in OS.cpp) and rebuild your
libACE, does your program work properly?

Have you tried this on any other platforms?

Thanks,
David

David Levine

unread,
Jan 7, 1999, 3:00:00 AM1/7/99
to
I wrote:

I tried on SunOS 5.7 and Linux 2.0.36, and it succeeded on
both.

Do you have a newer Linux installation to test on?

Thanks,
David


Jody Hagins

unread,
Jan 7, 1999, 3:00:00 AM1/7/99
to

David Levine <lev...@cs.wustl.edu> wrote in article
<1999010719...@danzon.cs.wustl.edu>...


> > If I replace ACE_OS::mktime() with ::mktime() the program functions as
> > expected.
>
> How strange. ACE_OS::mktime () is thread safe; ::mktime () isn't.
> ACE_OS::mktime () just guards ::mktime ():
>
> ACE_MT (ACE_Thread_Mutex *ace_os_monitor_lock =
> ACE_Managed_Object<ACE_Thread_Mutex>::get_preallocated_object
> (ACE_Object_Manager::ACE_OS_MONITOR_LOCK);
> ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, *ace_os_monitor_lock,

(time_t) -1));


>
> ACE_OSCALL_RETURN (::mktime (t), time_t, (time_t) -1);
>
> If you remove the ACE_GUARD_RETURN (in OS.cpp) and rebuild your
> libACE, does your program work properly?

If I comment out the entire ACE_MT macro (of which ACE_GUARD_RETURN is a
part) then the program works. I suspect some weird interaction with this
locking mechanism.

Note that the test program only has a single thread. However, the same
thing happens if I have other threads. I can spin off a worker thread that
sleeps and wakes up every second. It works, but the main thread will still
see this same problem.


>
> Have you tried this on any other platforms?

No. I only have ACE on Linux at present.


Jody Hagins

unread,
Jan 7, 1999, 3:00:00 AM1/7/99
to

Jody Hagins

unread,
Jan 8, 1999, 3:00:00 AM1/8/99
to
David Levine <lev...@cs.wustl.edu> wrote in article
<1999010720...@taumsauk.cs.wustl.edu>...


>
> I tried on SunOS 5.7 and Linux 2.0.36, and it succeeded on
> both.
>
> Do you have a newer Linux installation to test on?

What egcs did you use? Also, in the normal ACE tests directory, there is a
test that hangs under linux. Does that hang go away under your 2.0.36
setup? I do have a 2.0.35 machine around here, but I don't know if I can
put ACE on it. I'll see.


David Levine

unread,
Jan 8, 1999, 3:00:00 AM1/8/99
to
Jody Hagins writes:

> What egcs did you use?

The version that ships with RedHat 5.2, egcs 1.0.3.

> Also, in the normal ACE tests directory, there is a
> test that hangs under linux. Does that hang go away under your 2.0.36
> setup?

No. It sounds like you're using an old egcs version, which
do have problems with ACE on Linux. Please see
ACE-INSTALL.html for recommended versions.

Thanks,
David

0 new messages