162
163
ulong thread_stack __attribute__((unused)))
164
165
if (printstack(fileno(stderr)) == -1)
165
fprintf(stderr, "Error when traversing the stack, stack appears corrupt.\n");
166
my_safe_printf_stderr("%s",
167
"Error when traversing the stack, stack appears corrupt.\n");
169
"http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n"
170
"and follow instructions on how to resolve the stack trace.\n"
171
"Resolved stack trace is much more helpful in diagnosing the\n"
172
"problem, so please do resolve it\n");
169
my_safe_printf_stderr("%s"
171
"http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n"
172
"and follow instructions on how to resolve the stack trace.\n"
173
"Resolved stack trace is much more helpful in diagnosing the\n"
174
"problem, so please do resolve it\n");
175
177
#elif HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD)
324
327
ulong tmp= min(0x10000,thread_stack);
325
328
/* Assume that the stack starts at the previous even 65K */
326
stack_bottom= (uchar*) (((ulong) &fp + tmp) &
328
fprintf(stderr, "Cannot determine thread, fp=%p, backtrace may not be correct.\n", fp);
329
stack_bottom= (uchar*) (((ulong) &fp + tmp) & ~(ulong) 0xFFFF);
330
my_safe_printf_stderr("Cannot determine thread, fp=%p, "
331
"backtrace may not be correct.\n", fp);
330
333
if (fp > (uchar**) stack_bottom ||
331
334
fp < (uchar**) stack_bottom - thread_stack)
333
fprintf(stderr, "Bogus stack limit or frame pointer,\
334
fp=%p, stack_bottom=%p, thread_stack=%ld, aborting backtrace.\n",
335
fp, stack_bottom, thread_stack);
336
my_safe_printf_stderr("Bogus stack limit or frame pointer, "
337
"fp=%p, stack_bottom=%p, thread_stack=%ld, "
338
"aborting backtrace.\n",
339
fp, stack_bottom, thread_stack);
339
fprintf(stderr, "Stack range sanity check OK, backtrace follows:\n");
343
my_safe_printf_stderr("%s",
344
"Stack range sanity check OK, backtrace follows:\n");
340
345
#if defined(__alpha__) && defined(__GNUC__)
341
fprintf(stderr, "Warning: Alpha stacks are difficult -\
342
will be taking some wild guesses, stack trace may be incorrect or \
343
terminate abruptly\n");
346
my_safe_printf_stderr("%s",
347
"Warning: Alpha stacks are difficult -"
348
"will be taking some wild guesses, stack trace may be incorrect or "
349
"terminate abruptly\n");
344
351
/* On Alpha, we need to get pc */
345
352
__asm __volatile__ ("bsr %0, do_next; do_next: "
370
378
pc = find_prev_pc(pc, fp);
372
fprintf(stderr, "%p\n", pc);
380
my_safe_printf_stderr("%p\n", pc);
375
fprintf(stderr, "Not smart enough to deal with the rest\
383
my_safe_printf_stderr("%s",
384
"Not smart enough to deal with the rest of this stack\n");
382
fprintf(stderr, "Not smart enough to deal with the rest of this stack\n");
390
my_safe_printf_stderr("%s",
391
"Not smart enough to deal with the rest of this stack\n");
385
394
#endif /* defined(__alpha__) && defined(__GNUC__) */
386
395
if (new_fp <= fp )
388
fprintf(stderr, "New value of fp=%p failed sanity check,\
389
terminating stack trace!\n", new_fp);
397
my_safe_printf_stderr("New value of fp=%p failed sanity check, "
398
"terminating stack trace!\n", new_fp);
396
fprintf(stderr, "Stack trace seems successful - bottom reached\n");
404
my_safe_printf_stderr("%s",
405
"Stack trace seems successful - bottom reached\n");
400
"Please read http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n"
401
"and follow instructions on how to resolve the stack trace.\n"
402
"Resolved stack trace is much more helpful in diagnosing the\n"
403
"problem, so please do resolve it\n");
408
my_safe_printf_stderr("%s",
410
"http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n"
411
"and follow instructions on how to resolve the stack trace.\n"
412
"Resolved stack trace is much more helpful in diagnosing the\n"
413
"problem, so please do resolve it\n");
405
415
#endif /* TARGET_OS_LINUX */
406
416
#endif /* HAVE_STACKTRACE */
681
692
if(MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
682
693
hFile, MiniDumpNormal, &info, 0, 0))
684
fprintf(stderr, "Minidump written to %s\n",
685
_fullpath(path, dump_fname, sizeof(path)) ? path : dump_fname);
695
my_safe_printf_stderr("Minidump written to %s\n",
696
_fullpath(path, dump_fname, sizeof(path)) ?
689
fprintf(stderr,"MiniDumpWriteDump() failed, last error %u\n",
701
my_safe_printf_stderr("MiniDumpWriteDump() failed, last error %u\n",
702
(uint) GetLastError());
692
704
CloseHandle(hFile);
696
fprintf(stderr, "CreateFile(%s) failed, last error %u\n", dump_fname,
708
my_safe_printf_stderr("CreateFile(%s) failed, last error %u\n",
709
dump_fname, (uint) GetLastError());
707
fprintf(stderr, "%.*s\n", len, val);
718
my_write_stderr(val, len);
709
720
__except(EXCEPTION_EXECUTE_HANDLER)
711
fprintf(stderr, "is an invalid string pointer\n");
722
my_safe_printf_stderr("%s", "is an invalid string pointer\n");
714
725
#endif /*__WIN__*/
729
size_t my_write_stderr(const void *buf, size_t count)
732
SetFilePointer(GetStdHandle(STD_ERROR_HANDLE), 0, NULL, FILE_END);
733
WriteFile(GetStdHandle(STD_ERROR_HANDLE), buf, count, &bytes_written, NULL);
734
return bytes_written;
737
size_t my_write_stderr(const void *buf, size_t count)
739
return (size_t) write(STDERR_FILENO, buf, count);
744
static const char digits[]= "0123456789abcdef";
746
char *my_safe_utoa(int base, ulonglong val, char *buf)
750
*buf--= digits[val % base];
751
} while ((val /= base) != 0);
756
char *my_safe_itoa(int base, longlong val, char *buf)
759
const my_bool is_neg= (val < 0);
764
if (is_neg && base == 16)
768
for (ix= 0; ix < 16; ++ix)
773
*buf--= digits[val % base];
774
} while ((val /= base) != 0);
776
if (is_neg && base == 10)
779
if (is_neg && base == 16)
783
for (ix= 0; ix < 16; ++ix, --buf)
787
case '0': *buf= 'f'; break;
788
case '1': *buf= 'e'; break;
789
case '2': *buf= 'd'; break;
790
case '3': *buf= 'c'; break;
791
case '4': *buf= 'b'; break;
792
case '5': *buf= 'a'; break;
793
case '6': *buf= '9'; break;
794
case '7': *buf= '8'; break;
795
case '8': *buf= '7'; break;
796
case '9': *buf= '6'; break;
797
case 'a': *buf= '5'; break;
798
case 'b': *buf= '4'; break;
799
case 'c': *buf= '3'; break;
800
case 'd': *buf= '2'; break;
801
case 'e': *buf= '1'; break;
802
case 'f': *buf= '0'; break;
810
static const char *check_longlong(const char *fmt, my_bool *have_longlong)
812
*have_longlong= FALSE;
817
*have_longlong= (sizeof(long) == sizeof(longlong));
821
*have_longlong= TRUE;
827
static size_t my_safe_vsnprintf(char *to, size_t size,
828
const char* format, va_list ap)
831
char *end= start + size - 1;
832
for (; *format; ++format)
834
my_bool have_longlong = FALSE;
837
if (to == end) /* end of buffer */
839
*to++= *format; /* copy ordinary char */
842
++format; /* skip '%' */
844
format= check_longlong(format, &have_longlong);
857
have_longlong= (sizeof(void *) == sizeof(longlong));
861
uval= va_arg(ap, ulonglong);
863
ival= va_arg(ap, longlong);
868
uval= va_arg(ap, unsigned int);
870
ival= va_arg(ap, int);
875
const int base= (*format == 'x' || *format == 'p') ? 16 : 10;
876
char *val_as_str= (*format == 'u') ?
877
my_safe_utoa(base, uval, &buff[sizeof(buff)-1]) :
878
my_safe_itoa(base, ival, &buff[sizeof(buff)-1]);
880
/* Strip off "ffffffff" if we have 'x' format without 'll' */
881
if (*format == 'x' && !have_longlong && ival < 0)
884
while (*val_as_str && to < end)
885
*to++= *val_as_str++;
891
const char *val= va_arg(ap, char*);
894
while (*val && to < end)
905
size_t my_safe_snprintf(char* to, size_t n, const char* fmt, ...)
910
result= my_safe_vsnprintf(to, n, fmt, args);
916
size_t my_safe_printf_stderr(const char* fmt, ...)
922
result= my_safe_vsnprintf(to, sizeof(to), fmt, args);
924
my_write_stderr(to, result);