mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
Merge of mysql-5.1-bugteam into mysql-5.5-bugteam.
This commit is contained in:
commit
e1e81ceb83
4 changed files with 112 additions and 18 deletions
|
@ -8074,13 +8074,16 @@ static void dump_backtrace(void)
|
||||||
{
|
{
|
||||||
struct st_connection *conn= cur_con;
|
struct st_connection *conn= cur_con;
|
||||||
|
|
||||||
my_safe_print_str("read_command_buf", read_command_buf,
|
fprintf(stderr, "read_command_buf (%p): ", read_command_buf);
|
||||||
sizeof(read_command_buf));
|
my_safe_print_str(read_command_buf, sizeof(read_command_buf));
|
||||||
|
|
||||||
if (conn)
|
if (conn)
|
||||||
{
|
{
|
||||||
my_safe_print_str("conn->name", conn->name, conn->name_len);
|
fprintf(stderr, "conn->name (%p): ", conn->name);
|
||||||
|
my_safe_print_str(conn->name, conn->name_len);
|
||||||
#ifdef EMBEDDED_LIBRARY
|
#ifdef EMBEDDED_LIBRARY
|
||||||
my_safe_print_str("conn->cur_query", conn->cur_query, conn->cur_query_len);
|
fprintf(stderr, "conn->cur_query (%p): ", conn->cur_query);
|
||||||
|
my_safe_print_str(conn->cur_query, conn->cur_query_len);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
fputs("Attempting backtrace...\n", stderr);
|
fputs("Attempting backtrace...\n", stderr);
|
||||||
|
|
|
@ -45,7 +45,7 @@ C_MODE_START
|
||||||
#if defined(HAVE_STACKTRACE) || defined(HAVE_BACKTRACE)
|
#if defined(HAVE_STACKTRACE) || defined(HAVE_BACKTRACE)
|
||||||
void my_init_stacktrace();
|
void my_init_stacktrace();
|
||||||
void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack);
|
void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack);
|
||||||
void my_safe_print_str(const char* name, const char* val, int max_len);
|
void my_safe_print_str(const char* val, int max_len);
|
||||||
void my_write_core(int sig);
|
void my_write_core(int sig);
|
||||||
#if BACKTRACE_DEMANGLE
|
#if BACKTRACE_DEMANGLE
|
||||||
char *my_demangle(const char *mangled_name, int *status);
|
char *my_demangle(const char *mangled_name, int *status);
|
||||||
|
|
|
@ -24,6 +24,11 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <ctype.h> /* isprint */
|
||||||
|
#include <sys/syscall.h> /* SYS_gettid */
|
||||||
|
#endif
|
||||||
|
|
||||||
#if HAVE_EXECINFO_H
|
#if HAVE_EXECINFO_H
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -43,10 +48,96 @@ void my_init_stacktrace()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void my_safe_print_str(const char* name, const char* val, int max_len)
|
#ifdef __linux__
|
||||||
|
|
||||||
|
static void print_buffer(char *buffer, size_t count)
|
||||||
{
|
{
|
||||||
char *heap_end= (char*) sbrk(0);
|
for (; count && *buffer; --count)
|
||||||
fprintf(stderr, "%s at %p ", name, val);
|
{
|
||||||
|
int c= (int) *buffer++;
|
||||||
|
fputc(isprint(c) ? c : ' ', stderr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Access the pages of this process through /proc/self/task/<tid>/mem
|
||||||
|
in order to safely print the contents of a memory address range.
|
||||||
|
|
||||||
|
@param addr The address at the start of the memory region.
|
||||||
|
@param max_len The length of the memory region.
|
||||||
|
|
||||||
|
@return Zero on success.
|
||||||
|
*/
|
||||||
|
static int safe_print_str(const char *addr, int max_len)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
pid_t tid;
|
||||||
|
off_t offset;
|
||||||
|
ssize_t nbytes= 0;
|
||||||
|
size_t total, count;
|
||||||
|
char buf[256];
|
||||||
|
|
||||||
|
tid= (pid_t) syscall(SYS_gettid);
|
||||||
|
|
||||||
|
sprintf(buf, "/proc/self/task/%d/mem", tid);
|
||||||
|
|
||||||
|
if ((fd= open(buf, O_RDONLY)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
total= max_len;
|
||||||
|
offset= (off_t) addr;
|
||||||
|
|
||||||
|
/* Read up to the maximum number of bytes. */
|
||||||
|
while (total)
|
||||||
|
{
|
||||||
|
count= min(sizeof(buf), total);
|
||||||
|
|
||||||
|
if ((nbytes= pread(fd, buf, count, offset)) < 0)
|
||||||
|
{
|
||||||
|
/* Just in case... */
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Advance offset into memory. */
|
||||||
|
total-= nbytes;
|
||||||
|
offset+= nbytes;
|
||||||
|
addr+= nbytes;
|
||||||
|
|
||||||
|
/* Output the printable characters. */
|
||||||
|
print_buffer(buf, nbytes);
|
||||||
|
|
||||||
|
/* Break if less than requested... */
|
||||||
|
if ((count - nbytes))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output a new line if something was printed. */
|
||||||
|
if (total != (size_t) max_len)
|
||||||
|
fputc('\n', stderr);
|
||||||
|
|
||||||
|
if (nbytes == -1)
|
||||||
|
fprintf(stderr, "Can't read from address %p: %m.\n", addr);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void my_safe_print_str(const char* val, int max_len)
|
||||||
|
{
|
||||||
|
char *heap_end;
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
if (!safe_print_str(val, max_len))
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
heap_end= (char*) sbrk(0);
|
||||||
|
|
||||||
if (!PTR_SANE(val))
|
if (!PTR_SANE(val))
|
||||||
{
|
{
|
||||||
|
@ -54,7 +145,6 @@ void my_safe_print_str(const char* name, const char* val, int max_len)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "= ");
|
|
||||||
for (; max_len && PTR_SANE(val) && *val; --max_len)
|
for (; max_len && PTR_SANE(val) && *val; --max_len)
|
||||||
fputc(*val++, stderr);
|
fputc(*val++, stderr);
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
|
@ -607,10 +697,9 @@ void my_write_core(int unused)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void my_safe_print_str(const char *name, const char *val, int len)
|
void my_safe_print_str(const char *val, int len)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"%s at %p", name, val);
|
__try
|
||||||
__try
|
|
||||||
{
|
{
|
||||||
fprintf(stderr,"=%.*s\n", len, val);
|
fprintf(stderr,"=%.*s\n", len, val);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2427,7 +2427,7 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n",
|
||||||
|
|
||||||
if (!(test_flags & TEST_NO_STACKTRACE))
|
if (!(test_flags & TEST_NO_STACKTRACE))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "thd: 0x%lx\n",(long) thd);
|
fprintf(stderr, "Thread pointer: 0x%lx\n", (long) thd);
|
||||||
fprintf(stderr, "Attempting backtrace. You can use the following "
|
fprintf(stderr, "Attempting backtrace. You can use the following "
|
||||||
"information to find out\nwhere mysqld died. If "
|
"information to find out\nwhere mysqld died. If "
|
||||||
"you see no messages after this, something went\n"
|
"you see no messages after this, something went\n"
|
||||||
|
@ -2455,11 +2455,13 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n",
|
||||||
kreason= "KILLED_NO_VALUE";
|
kreason= "KILLED_NO_VALUE";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "Trying to get some variables.\n\
|
fprintf(stderr, "\nTrying to get some variables.\n"
|
||||||
Some pointers may be invalid and cause the dump to abort...\n");
|
"Some pointers may be invalid and cause the dump to abort.\n");
|
||||||
my_safe_print_str("thd->query", thd->query(), 1024);
|
fprintf(stderr, "Query (%p): ", thd->query());
|
||||||
fprintf(stderr, "thd->thread_id=%lu\n", (ulong) thd->thread_id);
|
my_safe_print_str(thd->query(), min(1024, thd->query_length()));
|
||||||
fprintf(stderr, "thd->killed=%s\n", kreason);
|
fprintf(stderr, "Connection ID (thread ID): %lu\n", (ulong) thd->thread_id);
|
||||||
|
fprintf(stderr, "Status: %s\n", kreason);
|
||||||
|
fputc('\n', stderr);
|
||||||
}
|
}
|
||||||
fprintf(stderr, "\
|
fprintf(stderr, "\
|
||||||
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\
|
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\
|
||||||
|
|
Loading…
Reference in a new issue