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