List:Commits« Previous MessageNext Message »
From:Davi Arnaut Date:November 30 2010 7:07pm
Subject:bzr commit into mysql-5.5-bugteam branch (davi:3154)
View as plain text  
# At a local mysql-5.5-bugteam repository of davi

 3154 Davi Arnaut	2010-11-30 [merge]
      Merge of mysql-5.1-bugteam into mysql-5.5-bugteam.

    modified:
      client/mysqltest.cc
      include/my_stacktrace.h
      mysys/stacktrace.c
      sql/mysqld.cc
=== modified file 'client/mysqltest.cc'
--- a/client/mysqltest.cc	2010-11-27 10:52:17 +0000
+++ b/client/mysqltest.cc	2010-11-30 19:06:53 +0000
@@ -8074,13 +8074,16 @@ static void dump_backtrace(void)
 {
   struct st_connection *conn= cur_con;
 
-  my_safe_print_str("read_command_buf", read_command_buf,
-                    sizeof(read_command_buf));
+  fprintf(stderr, "read_command_buf (%p): ", read_command_buf);
+  my_safe_print_str(read_command_buf, sizeof(read_command_buf));
+
   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
-    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
   }
   fputs("Attempting backtrace...\n", stderr);

=== modified file 'include/my_stacktrace.h'
--- a/include/my_stacktrace.h	2010-07-15 11:13:30 +0000
+++ b/include/my_stacktrace.h	2010-11-30 19:06:53 +0000
@@ -45,7 +45,7 @@ C_MODE_START
 #if defined(HAVE_STACKTRACE) || defined(HAVE_BACKTRACE)
 void my_init_stacktrace();
 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);
 #if BACKTRACE_DEMANGLE
 char *my_demangle(const char *mangled_name, int *status);

=== modified file 'mysys/stacktrace.c'
--- a/mysys/stacktrace.c	2010-11-08 11:53:04 +0000
+++ b/mysys/stacktrace.c	2010-11-30 19:06:53 +0000
@@ -24,6 +24,11 @@
 #include <unistd.h>
 #include <strings.h>
 
+#ifdef __linux__
+#include <ctype.h>          /* isprint */
+#include <sys/syscall.h>    /* SYS_gettid */
+#endif
+
 #if HAVE_EXECINFO_H
 #include <execinfo.h>
 #endif
@@ -43,10 +48,96 @@ void my_init_stacktrace()
 #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)
+{
+  for (; count && *buffer; --count)
+  {
+    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= (char*) sbrk(0);
-  fprintf(stderr, "%s at %p ", name, val);
+  char *heap_end;
+
+#ifdef __linux__
+  if (!safe_print_str(val, max_len))
+    return;
+#endif
+
+  heap_end= (char*) sbrk(0);
 
   if (!PTR_SANE(val))
   {
@@ -54,7 +145,6 @@ void my_safe_print_str(const char* name,
     return;
   }
 
-  fprintf(stderr, "= ");
   for (; max_len && PTR_SANE(val) && *val; --max_len)
     fputc(*val++, 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);
   }

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2010-11-25 03:50:16 +0000
+++ b/sql/mysqld.cc	2010-11-30 19:06:53 +0000
@@ -2427,7 +2427,7 @@ the thread stack. Please read http://dev
 
   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 "
                     "information to find out\nwhere mysqld died. If "
                     "you see no messages after this, something went\n"
@@ -2455,11 +2455,13 @@ the thread stack. Please read http://dev
       kreason= "KILLED_NO_VALUE";
       break;
     }
-    fprintf(stderr, "Trying to get some variables.\n\
-Some pointers may be invalid and cause the dump to abort...\n");
-    my_safe_print_str("thd->query", thd->query(), 1024);
-    fprintf(stderr, "thd->thread_id=%lu\n", (ulong) thd->thread_id);
-    fprintf(stderr, "thd->killed=%s\n", kreason);
+    fprintf(stderr, "\nTrying to get some variables.\n"
+                    "Some pointers may be invalid and cause the dump to abort.\n");
+    fprintf(stderr, "Query (%p): ", thd->query());
+    my_safe_print_str(thd->query(), min(1024, thd->query_length()));
+    fprintf(stderr, "Connection ID (thread ID): %lu\n", (ulong) thd->thread_id);
+    fprintf(stderr, "Status: %s\n", kreason);
+    fputc('\n', stderr);
   }
   fprintf(stderr, "\
 The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\

No bundle (reason: revision is a merge).
Thread
bzr commit into mysql-5.5-bugteam branch (davi:3154) Davi Arnaut30 Nov