summaryrefslogtreecommitdiff
path: root/mysys/stacktrace.c
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2012-03-14 21:16:24 +0100
committerSergei Golubchik <sergii@pisem.net>2012-03-14 21:16:24 +0100
commit44ea4e7c1f90f80ab5cf55f435856acca7a176db (patch)
tree29b6ddd92aaa202477a375e554a319538d2919cb /mysys/stacktrace.c
parent8245178f5d55d2f1f90e87a78a0c5c5245875809 (diff)
downloadmariadb-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.c194
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;