Bug #16155 TRUNCATE TABLE crashes mysqld
Submitted: 3 Jan 2006 15:47 Modified: 6 Jan 2006 16:11
Reporter: Kristian Nielsen Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S1 (Critical)
Version:Lastest 5.1-new bitkeeper OS:IBM AIX (AIX 5.2 (64 bit))
Assigned to: Kristian Nielsen CPU Architecture:Any

[3 Jan 2006 15:47] Kristian Nielsen
Description:
Mysqld crashes on a TRUNCATE TABLE statement (SIGSEGV).

Mysql-5.1-new bitkeeper tree. ChangeSet:

    1.2026 06/01/03 11:09:18 knielsen@mysql.com

I saw this in the testsuite (auto_increment), but it reproduces in a simple stand-alone test. The server crashes in several other tests, I assume the problems are related but have not investigated.

It produces a core file, but it is unhelpful:

mysqldev@aix52:~/knielsen/mysql-5.1.5-alpha-standard/mysql-test> gdb ../sql/mysqld var/master-data/core
Program terminated with signal 11, Segmentation fault.
#0  0x9000000002df2ac in pthread_kill ()
(gdb) bt
#0  0x9000000002df2ac in pthread_kill ()
#1  0xffffffffffffffff in ?? () from (unknown load module)

How to repeat:
Start mysqld; I started it using mysql-test-run.pl:

$ cd mysql-test
$ MTR_BUILD_THREAD=6 ./mysql-test-run.pl --tmpdir=/tmp/knielsen --start-and-exit auto_increment

Then run a mysql session like this:

$ ../client/mysql -uroot --socket=/tmp/knielsen/master.sock --password= test
mysql> create table kntest(a varchar(100));
mysql> truncate table kntest;
ERROR 2013 (HY000): Lost connection to MySQL server during query
[6 Jan 2006 14:29] Kristian Nielsen
A trace from the crash:

T@3    : | | | >mysql_truncate
T@3    : | | | | >unpack_filename
T@3    : | | | | | >dirname_part
T@3    : | | | | | | enter: './test/kntest.frm'
T@3    : | | | | | | >convert_dirname
T@3    : | | | | | | <convert_dirname
T@3    : | | | | | <dirname_part
T@3    : | | | | | >unpack_dirname
T@3    : | | | | | | >dirname_part
T@3    : | | | | | | | enter: './test/'
T@3    : | | | | | | | >convert_dirname
T@3    : | | | | | | | <convert_dirname
T@3    : | | | | | | <dirname_part
T@3    : | | | | | | >cleanup_dirname
T@3    : | | | | | | | enter: from: './test/'
T@3    : | | | | | | | exit: to: './test/'
T@3    : | | | | | | <cleanup_dirname
T@3    : | | | | | <unpack_dirname
T@3    : | | | | <unpack_filename
T@3    : | | | | >mysql_frm_type
T@3    : | | | | | >my_open
T@3    : | | | | | | my: Name: './test/kntest.frm'  Flags: 0  MyFlags: 0
T@3    : | | | | | <my_open
T@3    : | | | | | >my_malloc
T@3    : | | | | | | my: size: 18  my_flags: 0
T@3    : | | | | | | exit: ptr: 0x111e18eb0
T@3    : | | | | | <my_malloc
T@3    : | | | | | exit: fd: 28
T@3    : | | | | | >my_read
T@3    : | | | | | | my: Fd: 28  Buffer: 0x111ea2464  Count: 10  MyFlags: 20
T@3    : | | | | | <my_read
T@3    : | | | | | >my_close
T@3    : | | | | | | my: fd: 28  MyFlags: 16
T@3    : | | | | | | >my_free
T@3    : | | | | | | | my: ptr: 0x111e18eb0
T@3    : | | | | | | <my_free
T@3    : | | | | | <my_close
T@3    : | | | | <mysql_frm_type
T@3    : | | | | >mysql_uninstall_plugin
T@3    : | | | | <mysql_uninstall_plugin
T@3    : | | | | >lock_and_wait_for_table_name
T@3    : | | | | | >wait_if_global_read_lock
T@3    : | | | | | <wait_if_global_read_lock
T@3    : | | | | | >lock_table_name
T@3    : | | | | | | enter: db: test  name: kntest
T@3    : | | | | | | >hash_search
T@3    : | | | | | | <hash_search
T@3    : | | | | | | >my_malloc
T@3    : | | | | | | | my: size: 2564  my_flags: 48
T@3    : | | | | | | | exit: ptr: 0x111e195d0
T@3    : | | | | | | <my_malloc
T@3    : | | | | | <lock_table_name
T@3    : | | | | | >remove_table_from_cache
T@3    : | | | | | | >hash_search
T@3    : | | | | | | | exit: found key at 1
T@3    : | | | | | | <hash_search
T@3    : | | | | | | info: Table was in use by current thread. db_stat: 0
T@3    : | | | | | | info: Removing table from table_def_cache
T@3    : | | | | | | >hash_search
T@3    : | | | | | | <hash_search
T@3    : | | | | | <remove_table_from_cache
T@3    : | | | | | >start_waiting_global_read_lock
T@3    : | | | | | <start_waiting_global_read_lock
T@3    : | | | | <lock_and_wait_for_table_name
[6 Jan 2006 15:27] Kristian Nielsen
Hm, I found the cause of this.

It crashes in sql/sql_delete.cc line 893:

    *(path + path_length - reg_ext_length)= '\0';

The crash can be reproduced by this small program:

#include <string.h>
#include <stdio.h>

int main(int argc, char *argv) {
  char path[255];
  unsigned int path_length, reg_ext_length;
  strcpy(path, "./test/kntest.frm");
  path_length = 17;
  reg_ext_length = 4;
  *(path + path_length - reg_ext_length)= '\0';
  fprintf(stderr, "path='%s'\n", path);
}

Compile with "xlC_r -g -q64  test.cc" and it crashes. Compile with "xlC_r -g   test.cc" and it works ok...

Looks like a compiler bug then.

A workaround is to change the offending line to this (both in test program and mysqld):

    path[path_length - reg_ext_length]= '\0';

Maybe we should do this?
[6 Jan 2006 16:06] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/706
[6 Jan 2006 16:11] Kristian Nielsen
Fixed in 5.1.5.

Not in any released version, so nothing to document.