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