diff options
author | Sergei Golubchik <sergii@pisem.net> | 2012-03-14 21:16:24 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2012-03-14 21:16:24 +0100 |
commit | 44ea4e7c1f90f80ab5cf55f435856acca7a176db (patch) | |
tree | 29b6ddd92aaa202477a375e554a319538d2919cb /mysys/stacktrace.c | |
parent | 8245178f5d55d2f1f90e87a78a0c5c5245875809 (diff) | |
download | mariadb-git-44ea4e7c1f90f80ab5cf55f435856acca7a176db.tar.gz |
restore my_safe_printf_stderr for "crash-safe sigsegv handler"
use vsnprintf()
use write() on windows, not WriteFile or fwrite()
localtime_r is still a problem
Diffstat (limited to 'mysys/stacktrace.c')
-rw-r--r-- | mysys/stacktrace.c | 194 |
1 files changed, 8 insertions, 186 deletions
diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c index c59be6b1f48..2ec526f2535 100644 --- a/mysys/stacktrace.c +++ b/mysys/stacktrace.c @@ -685,7 +685,7 @@ void my_print_stacktrace(uchar* unused1, ulong unused2) &(package.sym)); have_source= pSymGetLineFromAddr64(hProcess, addr, &line_offset, &line); - fprintf(stderr,"%p ", addr); + my_safe_printf_stderr("%p ", addr); if(have_module) { char *base_image_name= strrchr(module.ImageName, '\\'); @@ -693,12 +693,13 @@ void my_print_stacktrace(uchar* unused1, ulong unused2) base_image_name++; else base_image_name= module.ImageName; - fprintf(stderr,"%s!", base_image_name); + my_safe_printf_stderr("%s!", base_image_name); } if(have_symbol) - fprintf(stderr, "%s()", package.sym.Name); + my_safe_printf_stderr("%s()", package.sym.Name); + else if(have_module) - fprintf(stderr,"%s", "???"); + my_safe_printf_stderr("%s", "???"); if(have_source) { @@ -707,10 +708,10 @@ void my_print_stacktrace(uchar* unused1, ulong unused2) base_file_name++; else base_file_name= line.FileName; - fprintf(stderr, "[%s:%u]", + my_safe_printf_stderr("[%s:%u]", base_file_name, line.LineNumber); } - fprintf(stderr,"%s", "\n"); + my_safe_printf_stderr("%s", "\n"); } } @@ -781,189 +782,10 @@ void my_safe_print_str(const char *val, int len) #endif /*__WIN__*/ -#ifdef __WIN__ -size_t my_write_stderr(const void *buf, size_t count) -{ - return fwrite(buf, 1, count, stderr); -} -#else size_t my_write_stderr(const void *buf, size_t count) { return (size_t) write(STDERR_FILENO, buf, count); } -#endif - - -static const char digits[]= "0123456789abcdef"; - -char *my_safe_utoa(int base, ulonglong val, char *buf) -{ - *buf--= 0; - do { - *buf--= digits[val % base]; - } while ((val /= base) != 0); - return buf + 1; -} - - -char *my_safe_itoa(int base, longlong val, char *buf) -{ - char *orig_buf= buf; - const my_bool is_neg= (val < 0); - *buf--= 0; - - if (is_neg) - val= -val; - if (is_neg && base == 16) - { - int ix; - val-= 1; - for (ix= 0; ix < 16; ++ix) - buf[-ix]= '0'; - } - - do { - *buf--= digits[val % base]; - } while ((val /= base) != 0); - - if (is_neg && base == 10) - *buf--= '-'; - - if (is_neg && base == 16) - { - int ix; - buf= orig_buf - 1; - for (ix= 0; ix < 16; ++ix, --buf) - { - switch (*buf) - { - case '0': *buf= 'f'; break; - case '1': *buf= 'e'; break; - case '2': *buf= 'd'; break; - case '3': *buf= 'c'; break; - case '4': *buf= 'b'; break; - case '5': *buf= 'a'; break; - case '6': *buf= '9'; break; - case '7': *buf= '8'; break; - case '8': *buf= '7'; break; - case '9': *buf= '6'; break; - case 'a': *buf= '5'; break; - case 'b': *buf= '4'; break; - case 'c': *buf= '3'; break; - case 'd': *buf= '2'; break; - case 'e': *buf= '1'; break; - case 'f': *buf= '0'; break; - } - } - } - return buf+1; -} - - -static const char *check_longlong(const char *fmt, my_bool *have_longlong) -{ - *have_longlong= FALSE; - if (*fmt == 'l') - { - fmt++; - if (*fmt != 'l') - *have_longlong= (sizeof(long) == sizeof(longlong)); - else - { - fmt++; - *have_longlong= TRUE; - } - } - return fmt; -} - -static size_t my_safe_vsnprintf(char *to, size_t size, - const char* format, va_list ap) -{ - char *start= to; - char *end= start + size - 1; - for (; *format; ++format) - { - my_bool have_longlong = FALSE; - if (*format != '%') - { - if (to == end) /* end of buffer */ - break; - *to++= *format; /* copy ordinary char */ - continue; - } - ++format; /* skip '%' */ - - format= check_longlong(format, &have_longlong); - - switch (*format) - { - case 'd': - case 'i': - case 'u': - case 'x': - case 'p': - { - longlong ival= 0; - ulonglong uval = 0; - if (*format == 'p') - have_longlong= (sizeof(void *) == sizeof(longlong)); - if (have_longlong) - { - if (*format == 'u') - uval= va_arg(ap, ulonglong); - else - ival= va_arg(ap, longlong); - } - else - { - if (*format == 'u') - uval= va_arg(ap, unsigned int); - else - ival= va_arg(ap, int); - } - - { - char buff[22]; - const int base= (*format == 'x' || *format == 'p') ? 16 : 10; - char *val_as_str= (*format == 'u') ? - my_safe_utoa(base, uval, &buff[sizeof(buff)-1]) : - my_safe_itoa(base, ival, &buff[sizeof(buff)-1]); - - /* Strip off "ffffffff" if we have 'x' format without 'll' */ - if (*format == 'x' && !have_longlong && ival < 0) - val_as_str+= 8; - - while (*val_as_str && to < end) - *to++= *val_as_str++; - continue; - } - } - case 's': - { - const char *val= va_arg(ap, char*); - if (!val) - val= "(null)"; - while (*val && to < end) - *to++= *val++; - continue; - } - } - } - *to= 0; - return to - start; -} - - -size_t my_safe_snprintf(char* to, size_t n, const char* fmt, ...) -{ - size_t result; - va_list args; - va_start(args,fmt); - result= my_safe_vsnprintf(to, n, fmt, args); - va_end(args); - return result; -} size_t my_safe_printf_stderr(const char* fmt, ...) @@ -972,7 +794,7 @@ size_t my_safe_printf_stderr(const char* fmt, ...) size_t result; va_list args; va_start(args,fmt); - result= my_safe_vsnprintf(to, sizeof(to), fmt, args); + result= vsnprintf(to, sizeof(to), fmt, args); va_end(args); my_write_stderr(to, result); return result; |