Port-sparc archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: ntpd wedged by libc?



On Fri, Mar 9, 2012 at 17:02, David Brownlee <abs%netbsd.org@localhost> wrote:
> On 7 March 2012 22:29, AGC <agcarver+netbsd%acarver.net@localhost> wrote:
>> On 3/7/2012 13:57, Dave Hart wrote:
>>
>> Yes, when it wedges it uses upwards of 80-90% CPU according to top but is
>> otherwise unresponsive unless issued a SIGKILL, SIGTERM, or SIGHUP. I attach
>> gdb to it while it's spinning the CPU that's where I get the stack trace.
>>  Interestingly a simple SIGTERM will break the loop and ntpd will actually
>> close out normally -- it issues the exit messages in the logs about
>> releasing kernel discipline and then message "exit on signal 15" (or
>> whatever the number is for a kill command with no signal flag, I don't
>> recall).
>
> Apologies if I've misunderstood something here, but if using the hand
> rolled snprintf does not use dtoa() and avoids the issue would it make
> sense to try one of:
>
> a) Modify the hand rolled snprintf to use dtoa() to confirm it is the
> dtoa() calls, plus have it keep a static fd open and just write out
> the argument before calling each dtoa(). If it hangs, you have a
> history of dtoa() calls which you can replay in a test app to see
> which bit pattern or sequence of bit patterns causes the issue.

Attached and inlined below is a patch to ntpd's replacement snprintf()
to log floating point values as hex dumps to "printf_dtoa.log" then
call dtoa(), though it doesn't actually use dtoa's text conversion
result.  AGC, if you apply this patch and rebuild ntpd (configured
with --enable-C99-snprintf) the log could be very helpful assuming it
eventually spins infinitely inside dtoa().

The code compiles but I don't have dtoa() on this system to test with,
so I haven't tested it.

Cheers,
Dave Hart


===== libntp/snprintf.c 1.12 vs edited =====
--- 1.12/libntp/snprintf.c      2011-10-21 19:10:01 +00:00
+++ edited/libntp/snprintf.c    2012-03-09 19:08:49 +00:00
@@ -192,6 +192,9 @@
 #include <config.h>
 #endif /* HAVE_CONFIG_H */

+extern char *dtoa(double d0, int mode, int ndigits, int *decpt, int
*sign, char **rve);
+extern void freedtoa(char *s);
+
 #if TEST_SNPRINTF
 #include <math.h>      /* For pow(3), NAN, and INFINITY. */
 #include <string.h>    /* For strcmp(3). */
@@ -300,6 +303,7 @@
 #endif /* TEST_SNPRINTF */

 #if HW_WANT_RPL_SNPRINTF || HW_WANT_RPL_VSNPRINTF ||
HW_WANT_RPL_ASPRINTF || HW_WANT_RPL_VASPRINTF
+#include <math.h>      /* dtoa() */
 #include <stdio.h>     /* For NULL, size_t, vsnprintf(3), and vasprintf(3). */
 #ifdef VA_START
 #undef VA_START
@@ -1100,6 +1104,11 @@ fmtflt(char *str, size_t *len, size_t si
        char iconvert[MAX_CONVERT_LENGTH];
        char fconvert[MAX_CONVERT_LENGTH];
        char econvert[4];       /* "e-12" (without nul-termination). */
+       static FILE *dtoa_log = NULL;
+       const u_char *puch;
+       int dtoamode;
+       int isneg;
+       int decpt;
        char esign = 0;
        char sign = 0;
        int leadfraczeros = 0;
@@ -1124,6 +1133,24 @@ fmtflt(char *str, size_t *len, size_t si
         */
        if (precision == -1)
                precision = 6;
+
+       if (NULL == dtoa_log)
+               dtoa_log = fopen("printf_dtoa.log", "w");
+       if (NULL != dtoa_log) {
+               for (puch = (void *)&fvalue;
+                    puch < (void *)(&fvalue + 1);
+                    puch++)
+                       fprintf(dtoa_log, "%02x", *puch);
+               fprintf(dtoa_log, "\n");
+               fflush(dtoa_log);
+               if (flags & PRINT_F_TYPE_E)
+                       dtoamode = 2;
+               else if (flags & PRINT_F_TYPE_G)
+                       dtoamode = 0;
+               else
+                       dtoamode = 3;
+               freedtoa(dtoa(fvalue, dtoamode, precision, &decpt, &isneg, 
NULL));
+       }

        if (fvalue < 0.0)
                sign = '-';

Attachment: ntp-dev-dtoa-log.patch
Description: Binary data



Home | Main Index | Thread Index | Old Index