Commit 93e7e5f9 authored by Olav Sandstaa's avatar Olav Sandstaa

Fix for Bug#54478 "mysqld crashes during boot when running mtr with --debug option"

      
The crash during boot was caused by a DBUG_PRINT statement in fill_schema_schemata() (in
sql_show.cc). This DBUG_PRINT statement contained several instances of %s in the format 
string and for one of these we gave a NULL pointer as the argument. This caused the
call to vsnprintf() to crash when running on Solaris.
      
The fix for this problem is to replace the call to vsnprintf() with my_vsnprintf()
which handles that a NULL pointer is passed as argumens for %s.

This patch also extends my_vsnprintf() to support %i in the format string.
parent 3e70a34f
...@@ -1335,15 +1335,11 @@ void _db_doprnt_(const char *format,...) ...@@ -1335,15 +1335,11 @@ void _db_doprnt_(const char *format,...)
* This function is intended as a * This function is intended as a
* vfprintf clone with consistent, platform independent output for * vfprintf clone with consistent, platform independent output for
* problematic formats like %p, %zd and %lld. * problematic formats like %p, %zd and %lld.
* However: full functionality for my_vsnprintf has not been backported yet,
* so code using "%g" or "%f" will have undefined behaviour.
*/ */
static void DbugVfprintf(FILE *stream, const char* format, va_list args) static void DbugVfprintf(FILE *stream, const char* format, va_list args)
{ {
char cvtbuf[1024]; char cvtbuf[1024];
size_t len; (void) my_vsnprintf(cvtbuf, sizeof(cvtbuf), format, args);
/* Do not use my_vsnprintf, it does not support "%g". */
len = vsnprintf(cvtbuf, sizeof(cvtbuf), format, args);
(void) fprintf(stream, "%s\n", cvtbuf); (void) fprintf(stream, "%s\n", cvtbuf);
} }
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
<length modifier> can be 'l', 'll', or 'z'. <length modifier> can be 'l', 'll', or 'z'.
Supported formats are 's' (null pointer is accepted, printed as Supported formats are 's' (null pointer is accepted, printed as
"(null)"), 'b' (extension, see below), 'c', 'd', 'u', 'x', 'o', "(null)"), 'b' (extension, see below), 'c', 'd', 'i', 'u', 'x', 'o',
'X', 'p' (works as 0x%x). 'X', 'p' (works as 0x%x).
Standard syntax for positional arguments $n is supported. Standard syntax for positional arguments $n is supported.
......
...@@ -255,7 +255,7 @@ static char *process_int_arg(char *to, char *end, size_t length, ...@@ -255,7 +255,7 @@ static char *process_int_arg(char *to, char *end, size_t length,
if ((to_length= (size_t) (end-to)) < 16 || length) if ((to_length= (size_t) (end-to)) < 16 || length)
store_start= buff; store_start= buff;
if (arg_type == 'd') if (arg_type == 'd' || arg_type == 'i')
store_end= longlong10_to_str(par, store_start, -10); store_end= longlong10_to_str(par, store_start, -10);
else if (arg_type == 'u') else if (arg_type == 'u')
store_end= longlong10_to_str(par, store_start, 10); store_end= longlong10_to_str(par, store_start, 10);
...@@ -399,6 +399,7 @@ static char *process_args(CHARSET_INFO *cs, char *to, char *end, ...@@ -399,6 +399,7 @@ static char *process_args(CHARSET_INFO *cs, char *to, char *end,
args_arr[i].double_arg= va_arg(ap, double); args_arr[i].double_arg= va_arg(ap, double);
break; break;
case 'd': case 'd':
case 'i':
case 'u': case 'u':
case 'x': case 'x':
case 'X': case 'X':
...@@ -406,7 +407,7 @@ static char *process_args(CHARSET_INFO *cs, char *to, char *end, ...@@ -406,7 +407,7 @@ static char *process_args(CHARSET_INFO *cs, char *to, char *end,
case 'p': case 'p':
if (args_arr[i].have_longlong) if (args_arr[i].have_longlong)
args_arr[i].longlong_arg= va_arg(ap,longlong); args_arr[i].longlong_arg= va_arg(ap,longlong);
else if (args_arr[i].arg_type == 'd') else if (args_arr[i].arg_type == 'd' || args_arr[i].arg_type == 'i')
args_arr[i].longlong_arg= va_arg(ap, int); args_arr[i].longlong_arg= va_arg(ap, int);
else else
args_arr[i].longlong_arg= va_arg(ap, uint); args_arr[i].longlong_arg= va_arg(ap, uint);
...@@ -458,6 +459,7 @@ static char *process_args(CHARSET_INFO *cs, char *to, char *end, ...@@ -458,6 +459,7 @@ static char *process_args(CHARSET_INFO *cs, char *to, char *end,
break; break;
} }
case 'd': case 'd':
case 'i':
case 'u': case 'u':
case 'x': case 'x':
case 'X': case 'X':
...@@ -472,7 +474,7 @@ static char *process_args(CHARSET_INFO *cs, char *to, char *end, ...@@ -472,7 +474,7 @@ static char *process_args(CHARSET_INFO *cs, char *to, char *end,
if (args_arr[print_arr[i].arg_idx].have_longlong) if (args_arr[print_arr[i].arg_idx].have_longlong)
larg = args_arr[print_arr[i].arg_idx].longlong_arg; larg = args_arr[print_arr[i].arg_idx].longlong_arg;
else if (print_arr[i].arg_type == 'd') else if (print_arr[i].arg_type == 'd' || print_arr[i].arg_type == 'i' )
larg = (int) args_arr[print_arr[i].arg_idx].longlong_arg; larg = (int) args_arr[print_arr[i].arg_idx].longlong_arg;
else else
larg= (uint) args_arr[print_arr[i].arg_idx].longlong_arg; larg= (uint) args_arr[print_arr[i].arg_idx].longlong_arg;
...@@ -615,8 +617,8 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n, ...@@ -615,8 +617,8 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
to= process_dbl_arg(to, end, width, d, *fmt); to= process_dbl_arg(to, end, width, d, *fmt);
continue; continue;
} }
else if (*fmt == 'd' || *fmt == 'u' || *fmt == 'x' || *fmt == 'X' || else if (*fmt == 'd' || *fmt == 'i' || *fmt == 'u' || *fmt == 'x' ||
*fmt == 'p' || *fmt == 'o') *fmt == 'X' || *fmt == 'p' || *fmt == 'o')
{ {
/* Integer parameter */ /* Integer parameter */
longlong larg; longlong larg;
...@@ -625,7 +627,7 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n, ...@@ -625,7 +627,7 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
if (have_longlong) if (have_longlong)
larg = va_arg(ap,longlong); larg = va_arg(ap,longlong);
else if (*fmt == 'd') else if (*fmt == 'd' || *fmt == 'i')
larg = va_arg(ap, int); larg = va_arg(ap, int);
else else
larg= va_arg(ap, uint); larg= va_arg(ap, uint);
......
...@@ -31,7 +31,7 @@ void test1(const char *res, const char *fmt, ...) ...@@ -31,7 +31,7 @@ void test1(const char *res, const char *fmt, ...)
int main(void) int main(void)
{ {
plan(54); plan(58);
test1("Constant string", test1("Constant string",
"Constant string"); "Constant string");
...@@ -44,6 +44,8 @@ int main(void) ...@@ -44,6 +44,8 @@ int main(void)
"Format specifier c %c", '!'); "Format specifier c %c", '!');
test1("Format specifier d 1", test1("Format specifier d 1",
"Format specifier d %d", 1); "Format specifier d %d", 1);
test1("Format specifier i 1",
"Format specifier i %i", 1);
test1("Format specifier u 2", test1("Format specifier u 2",
"Format specifier u %u", 2); "Format specifier u %u", 2);
test1("Format specifier o 375", test1("Format specifier o 375",
...@@ -77,6 +79,9 @@ int main(void) ...@@ -77,6 +79,9 @@ int main(void)
test1("Length modifiers work: 1 * -1 * 2 * 3", test1("Length modifiers work: 1 * -1 * 2 * 3",
"Length modifiers work: %d * %ld * %lld * %zd", 1, -1L, 2LL, (size_t)3); "Length modifiers work: %d * %ld * %lld * %zd", 1, -1L, 2LL, (size_t)3);
test1("Length modifiers work: 1 * -1 * 2 * 3",
"Length modifiers work: %i * %li * %lli * %zd", 1, -1L, 2LL, (size_t)3);
test1("long long X: 123456789abcdef0", test1("long long X: 123456789abcdef0",
"long long X: %llx", 0x123456789abcdef0LL); "long long X: %llx", 0x123456789abcdef0LL);
...@@ -121,6 +126,10 @@ int main(void) ...@@ -121,6 +126,10 @@ int main(void)
"Hello int, %d", 1); "Hello int, %d", 1);
test1("Hello int, -1", test1("Hello int, -1",
"Hello int, %d", -1); "Hello int, %d", -1);
test1("Hello int, 1",
"Hello int, %i", 1);
test1("Hello int, -1",
"Hello int, %i", -1);
test1("Hello string 'I am a string'", test1("Hello string 'I am a string'",
"Hello string '%s'", "I am a string"); "Hello string '%s'", "I am a string");
test1("Hello hack hack hack hack hack hack hack 1", test1("Hello hack hack hack hack hack hack hack 1",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment