From 0b7c5f4dcc496a9bbae17e386552d2d36700c3e9 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 16 Aug 2010 16:43:21 +0300 Subject: [PATCH 001/159] Bug #53296: LONG BLOB value types are not recognized Fixed the length of system variables to be 2^24 - 1 as it is documented for MEDIUMBLOB instead of 2^24. --- mysql-test/r/ps_2myisam.result | 272 ++++++++--------- mysql-test/r/ps_3innodb.result | 272 ++++++++--------- mysql-test/r/ps_4heap.result | 272 ++++++++--------- mysql-test/r/ps_5merge.result | 544 ++++++++++++++++----------------- sql/item_func.cc | 2 +- 5 files changed, 681 insertions(+), 681 deletions(-) diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result index a91d13d11a1..56b18ff4476 100644 --- a/mysql-test/r/ps_2myisam.result +++ b/mysql-test/r/ps_2myisam.result @@ -1929,26 +1929,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select @arg01:= c1, @arg02:= c2, @arg03:= c3, @arg04:= c4, @@ -1976,26 +1976,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select @@ -2026,26 +2026,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2066,26 +2066,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select ? := c1 from t9 where c1= 1" ; @@ -2114,26 +2114,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2158,26 +2158,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2204,26 +2204,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2242,26 +2242,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1 into ? from t9 where c1= 1" ; diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result index 50c94d6cc4e..2cd3b2f5820 100644 --- a/mysql-test/r/ps_3innodb.result +++ b/mysql-test/r/ps_3innodb.result @@ -1912,26 +1912,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select @arg01:= c1, @arg02:= c2, @arg03:= c3, @arg04:= c4, @@ -1959,26 +1959,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select @@ -2009,26 +2009,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2049,26 +2049,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select ? := c1 from t9 where c1= 1" ; @@ -2097,26 +2097,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2141,26 +2141,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2187,26 +2187,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2225,26 +2225,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1 into ? from t9 where c1= 1" ; diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result index a85809d3800..414267a5616 100644 --- a/mysql-test/r/ps_4heap.result +++ b/mysql-test/r/ps_4heap.result @@ -1913,26 +1913,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 0 31 8 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 0 31 8 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 0 31 8 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 0 31 8 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 0 31 8 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 0 31 8 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 0 31 8 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 0 31 8 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select @arg01:= c1, @arg02:= c2, @arg03:= c3, @arg04:= c4, @@ -1960,26 +1960,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 0 31 8 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 0 31 8 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 0 31 8 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 0 31 8 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 0 31 8 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 0 31 8 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 0 31 8 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 0 31 8 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select @@ -2010,26 +2010,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 0 31 8 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 0 31 8 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 0 31 8 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 0 31 8 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 0 31 8 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 0 31 8 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 0 31 8 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 0 31 8 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2050,26 +2050,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 0 31 8 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 0 31 8 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 0 31 8 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 0 31 8 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 0 31 8 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 0 31 8 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 0 31 8 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 0 31 8 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select ? := c1 from t9 where c1= 1" ; @@ -2098,26 +2098,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 0 31 8 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 0 31 8 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 0 31 8 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 0 31 8 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 0 31 8 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 0 31 8 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 0 31 8 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 0 31 8 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2142,26 +2142,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 0 31 8 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 0 31 8 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 0 31 8 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 0 31 8 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 0 31 8 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 0 31 8 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 0 31 8 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 0 31 8 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2188,26 +2188,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 0 31 8 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 0 31 8 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 0 31 8 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 0 31 8 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 0 31 8 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 0 31 8 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 0 31 8 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 0 31 8 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2226,26 +2226,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 0 31 8 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 0 31 8 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 0 31 8 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 0 31 8 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 0 31 8 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 0 31 8 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 0 31 8 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 0 31 8 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1 into ? from t9 where c1= 1" ; diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result index fd1b69c0ffd..d9e14374bc5 100644 --- a/mysql-test/r/ps_5merge.result +++ b/mysql-test/r/ps_5merge.result @@ -1849,26 +1849,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select @arg01:= c1, @arg02:= c2, @arg03:= c3, @arg04:= c4, @@ -1896,26 +1896,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select @@ -1946,26 +1946,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -1986,26 +1986,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select ? := c1 from t9 where c1= 1" ; @@ -2034,26 +2034,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2078,26 +2078,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -2124,26 +2124,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -2162,26 +2162,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1 into ? from t9 where c1= 1" ; @@ -4871,26 +4871,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select @arg01:= c1, @arg02:= c2, @arg03:= c3, @arg04:= c4, @@ -4918,26 +4918,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select @@ -4968,26 +4968,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -5008,26 +5008,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select ? := c1 from t9 where c1= 1" ; @@ -5056,26 +5056,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -5100,26 +5100,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, @@ -5146,26 +5146,26 @@ def @arg09 5 23 1 Y 32896 31 63 def @arg10 5 23 1 Y 32896 31 63 def @arg11 246 83 6 Y 128 30 63 def @arg12 246 83 6 Y 128 30 63 -def @arg13 251 16777216 10 Y 128 31 63 -def @arg14 251 16777216 19 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 8 Y 128 31 63 +def @arg13 250 16777215 10 Y 128 31 63 +def @arg14 250 16777215 19 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 8 Y 128 31 63 def @arg17 8 20 4 Y 32928 0 63 def @arg18 8 20 1 Y 32896 0 63 def @arg19 8 20 1 Y 32896 0 63 -def @arg20 251 16777216 1 Y 0 31 8 -def @arg21 251 16777216 10 Y 0 31 8 -def @arg22 251 16777216 30 Y 0 31 8 -def @arg23 251 16777216 8 Y 128 31 63 -def @arg24 251 16777216 8 Y 0 31 8 -def @arg25 251 16777216 4 Y 128 31 63 -def @arg26 251 16777216 4 Y 0 31 8 -def @arg27 251 16777216 10 Y 128 31 63 -def @arg28 251 16777216 10 Y 0 31 8 -def @arg29 251 16777216 8 Y 128 31 63 -def @arg30 251 16777216 8 Y 0 31 8 -def @arg31 251 16777216 3 Y 0 31 8 -def @arg32 251 16777216 6 Y 0 31 8 +def @arg20 250 16777215 1 Y 0 31 8 +def @arg21 250 16777215 10 Y 0 31 8 +def @arg22 250 16777215 30 Y 0 31 8 +def @arg23 250 16777215 8 Y 128 31 63 +def @arg24 250 16777215 8 Y 0 31 8 +def @arg25 250 16777215 4 Y 128 31 63 +def @arg26 250 16777215 4 Y 0 31 8 +def @arg27 250 16777215 10 Y 128 31 63 +def @arg28 250 16777215 10 Y 0 31 8 +def @arg29 250 16777215 8 Y 128 31 63 +def @arg30 250 16777215 8 Y 0 31 8 +def @arg31 250 16777215 3 Y 0 31 8 +def @arg32 250 16777215 6 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday set @my_key= 0 ; @@ -5184,26 +5184,26 @@ def @arg09 5 23 0 Y 32896 31 63 def @arg10 5 23 0 Y 32896 31 63 def @arg11 246 83 0 Y 128 30 63 def @arg12 246 83 0 Y 128 30 63 -def @arg13 251 16777216 0 Y 128 31 63 -def @arg14 251 16777216 0 Y 128 31 63 -def @arg15 251 16777216 19 Y 128 31 63 -def @arg16 251 16777216 0 Y 128 31 63 +def @arg13 250 16777215 0 Y 128 31 63 +def @arg14 250 16777215 0 Y 128 31 63 +def @arg15 250 16777215 19 Y 128 31 63 +def @arg16 250 16777215 0 Y 128 31 63 def @arg17 8 20 0 Y 32928 0 63 def @arg18 8 20 0 Y 32896 0 63 def @arg19 8 20 0 Y 32896 0 63 -def @arg20 251 16777216 0 Y 0 31 8 -def @arg21 251 16777216 0 Y 0 31 8 -def @arg22 251 16777216 0 Y 0 31 8 -def @arg23 251 16777216 0 Y 128 31 63 -def @arg24 251 16777216 0 Y 0 31 8 -def @arg25 251 16777216 0 Y 128 31 63 -def @arg26 251 16777216 0 Y 0 31 8 -def @arg27 251 16777216 0 Y 128 31 63 -def @arg28 251 16777216 0 Y 0 31 8 -def @arg29 251 16777216 0 Y 128 31 63 -def @arg30 251 16777216 0 Y 0 31 8 -def @arg31 251 16777216 0 Y 0 31 8 -def @arg32 251 16777216 0 Y 0 31 8 +def @arg20 250 16777215 0 Y 0 31 8 +def @arg21 250 16777215 0 Y 0 31 8 +def @arg22 250 16777215 0 Y 0 31 8 +def @arg23 250 16777215 0 Y 128 31 63 +def @arg24 250 16777215 0 Y 0 31 8 +def @arg25 250 16777215 0 Y 128 31 63 +def @arg26 250 16777215 0 Y 0 31 8 +def @arg27 250 16777215 0 Y 128 31 63 +def @arg28 250 16777215 0 Y 0 31 8 +def @arg29 250 16777215 0 Y 128 31 63 +def @arg30 250 16777215 0 Y 0 31 8 +def @arg31 250 16777215 0 Y 0 31 8 +def @arg32 250 16777215 0 Y 0 31 8 @arg01 @arg02 @arg03 @arg04 @arg05 @arg06 @arg07 @arg08 @arg09 @arg10 @arg11 @arg12 @arg13 @arg14 @arg15 @arg16 @arg17 @arg18 @arg19 @arg20 @arg21 @arg22 @arg23 @arg24 @arg25 @arg26 @arg27 @arg28 @arg29 @arg30 @arg31 @arg32 0 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1991-01-01 01:01:01 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL prepare stmt1 from "select c1 into ? from t9 where c1= 1" ; diff --git a/sql/item_func.cc b/sql/item_func.cc index 1b13297c951..999c048d9e9 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4640,7 +4640,7 @@ void Item_func_get_user_var::fix_length_and_dec() decimals=0; break; case STRING_RESULT: - max_length= MAX_BLOB_WIDTH; + max_length= MAX_BLOB_WIDTH - 1; break; case DECIMAL_RESULT: max_length= DECIMAL_MAX_STR_LENGTH; From 618d6e722042208c6424372570543d73968371a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 18 Aug 2010 14:40:02 +0300 Subject: [PATCH 002/159] Merge Bug#55626 fix from mysql-5.1-innodb: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit revno: 3545 revision-id: marko.makela@oracle.com-20100818110110-zfs0i1vfrccfb4yw parent: vasil.dimov@oracle.com-20100817193934-1yl7zz2odikxauf8 committer: Marko Mäkelä branch nick: 5.1-innodb timestamp: Wed 2010-08-18 14:01:10 +0300 message: Bug#55626: MIN and MAX reading a delete-marked record from secondary index Remove a bogus debug assertion that triggered the bug. Add assertions precisely where records must not be delete-marked. And a comment to clarify when the record is allowed to be delete-marked. --- storage/innobase/row/row0sel.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index 39ab2179740..945eab74924 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -2682,7 +2682,6 @@ row_sel_store_mysql_rec( ut_ad(prebuilt->mysql_template); ut_ad(prebuilt->default_rec); ut_ad(rec_offs_validate(rec, NULL, offsets)); - ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets))); if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) { mem_heap_free(prebuilt->blob_heap); @@ -3603,6 +3602,7 @@ row_search_for_mysql( row_sel_try_search_shortcut_for_mysql(). The latch will not be released until mtr_commit(&mtr). */ + ut_ad(!rec_get_deleted_flag(rec, comp)); if (!row_sel_store_mysql_rec(buf, prebuilt, rec, offsets)) { @@ -4230,7 +4230,7 @@ no_gap_lock: rec = old_vers; } - } else if (!lock_sec_rec_cons_read_sees(rec, trx->read_view)) { + } else { /* We are looking into a non-clustered index, and to get the right version of the record we have to look also into the clustered index: this @@ -4238,8 +4238,12 @@ no_gap_lock: information via the clustered index record. */ ut_ad(index != clust_index); + ut_ad(!dict_index_is_clust(index)); - goto requires_clust_rec; + if (!lock_sec_rec_cons_read_sees( + rec, trx->read_view)) { + goto requires_clust_rec; + } } } @@ -4362,8 +4366,13 @@ requires_clust_rec: ULINT_UNDEFINED, &heap); result_rec = rec; } + + /* result_rec can legitimately be delete-marked + now that it has been established that it points to a + clustered index record that exists in the read view. */ } else { result_rec = rec; + ut_ad(!rec_get_deleted_flag(rec, comp)); } /* We found a qualifying record 'result_rec'. At this point, From 97a780f1f9d4f6eab74007de7f08969ef7a8800a Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Wed, 18 Aug 2010 21:16:47 -0700 Subject: [PATCH 003/159] Bug #48026 Log start and end of InnoDB buffer pool initialization to the error log --- storage/innobase/srv/srv0start.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c index 4da836672ec..05fa637e7bb 100644 --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c @@ -1334,8 +1334,27 @@ innobase_start_or_create_for_mysql(void) fil_init(srv_file_per_table ? 50000 : 5000, srv_max_n_open_files); + /* Print time to initialize the buffer pool */ + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Initializing buffer pool, size ="); + + if (srv_buf_pool_size >= 1024 * 1024 * 1024) { + fprintf(stderr, + " %.1fG\n", + ((double) srv_buf_pool_size) / (1024 * 1024 * 1024)); + } else { + fprintf(stderr, + " %.1fM\n", + ((double) srv_buf_pool_size) / (1024 * 1024)); + } + err = buf_pool_init(srv_buf_pool_size, srv_buf_pool_instances); + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: Completed initialization of buffer pool\n"); + if (err != DB_SUCCESS) { fprintf(stderr, "InnoDB: Fatal error: cannot allocate the memory" From cb73a044f85f2aa33e6a46ab4c71b7a586583679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 19 Aug 2010 13:36:37 +0300 Subject: [PATCH 004/159] Bug#56114 Disallow trx->dict_operation_lock_mode==RW_X_LATCH in srv_suspend_mysql_thread() Issue an error message to the error log when trx->dict_operation_lock_mode == RW_X_LATCH in srv_suspend_mysql_thread(). Transactions that modify InnoDB data dictionary tables must be free of lock waits, because they must be holding the data dictionary latch in exclusive mode. The transactions must not be accessing any other tables other than the data dictionary tables. The handling of RW_X_LATCH was accidentally added in the InnoDB Plugin, as a wrong fix of an assertion failure. (Fast index creation was accessing both data dictionary tables and user tables in the same transaction.) --- storage/innobase/srv/srv0srv.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index bea8d7f8fdc..ce56a533d5e 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -1588,6 +1588,18 @@ srv_suspend_mysql_thread( row_mysql_unfreeze_data_dictionary(trx); break; case RW_X_LATCH: + /* There should never be a lock wait when the + dictionary latch is reserved in X mode. Dictionary + transactions should only acquire locks on dictionary + tables, not other tables. All access to dictionary + tables should be covered by dictionary + transactions. */ + ut_print_timestamp(stderr); + fputs(" InnoDB: Error: dict X latch held in " + "srv_suspend_mysql_thread\n", stderr); + /* This should never occur. This incorrect handling + was added in the early development of + ha_innobase::add_index() in InnoDB Plugin 1.0. */ /* Release fast index creation latch */ row_mysql_unlock_data_dictionary(trx); break; @@ -1607,6 +1619,9 @@ srv_suspend_mysql_thread( row_mysql_freeze_data_dictionary(trx); break; case RW_X_LATCH: + /* This should never occur. This incorrect handling + was added in the early development of + ha_innobase::add_index() in InnoDB Plugin 1.0. */ row_mysql_lock_data_dictionary(trx); break; } From 398f3ebbed83a7bde11ddb98910860862527a32c Mon Sep 17 00:00:00 2001 From: Inaam Rana Date: Fri, 20 Aug 2010 12:39:04 -0400 Subject: [PATCH 005/159] When flushing from LRU we try to keep a certain number of pages over and above the general requirement free. We call them BUF_FLUSH_EXTRA_MARGIN. With multiple buffer pools we may end up keeping this amount of pages for each buffer pool. This patch, diagnosed and fixed by Michael, throttles flushing in such cases. rb://435 bug#54346 --- storage/innobase/include/buf0flu.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h index 55814b6bf86..366063ab105 100644 --- a/storage/innobase/include/buf0flu.h +++ b/storage/innobase/include/buf0flu.h @@ -228,8 +228,8 @@ make sure that a read-ahead batch can be read efficiently in a single sweep). */ #define BUF_FLUSH_FREE_BLOCK_MARGIN(b) (5 + BUF_READ_AHEAD_AREA(b)) /** Extra margin to apply above BUF_FLUSH_FREE_BLOCK_MARGIN */ -#define BUF_FLUSH_EXTRA_MARGIN(b) (BUF_FLUSH_FREE_BLOCK_MARGIN(b) / 4 \ - + 100) +#define BUF_FLUSH_EXTRA_MARGIN(b) ((BUF_FLUSH_FREE_BLOCK_MARGIN(b) / 4 \ + + 100) / srv_buf_pool_instances) #endif /* !UNIV_HOTBACKUP */ #ifndef UNIV_NONINL From 938ce0efd7782697c5b7e96d7343e800438da909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 24 Aug 2010 11:34:19 +0300 Subject: [PATCH 006/159] =?UTF-8?q?Merge=20Bug#55832=20fix=20from=20mysql-?= =?UTF-8?q?5.1-innodb:=20-------------------------------------------------?= =?UTF-8?q?-----------=20revno:=203550=20revision-id:=20marko.makela@oracl?= =?UTF-8?q?e.com-20100824081003-v4ecy0tga99cpxw2=20parent:=20marko.makela@?= =?UTF-8?q?oracle.com-20100823102854-t1clrojqis2ley36=20committer:=20Marko?= =?UTF-8?q?=20M=C3=A4kel=C3=A4=20=20branch=20nick?= =?UTF-8?q?:=205.1-innodb=20timestamp:=20Tue=202010-08-24=2011:10:03=20+03?= =?UTF-8?q?00=20message:=20=20=20Bug#55832:=20selects=20crash=20too=20easi?= =?UTF-8?q?ly=20when=20innodb=5Fforce=5Frecovery>3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dict_update_statistics_low(): Create bogus statistics for those indexes that cannot be accessed because of the innodb_force_recovery setting. ha_innobase::info(): Calculate statistics for each index, even if innodb_force_recovery is set. Fill in bogus data for those indexes that are not accessed because of the innodb_force_recovery setting. --- storage/innobase/dict/dict0dict.c | 57 ++++++++++++++++----------- storage/innobase/handler/ha_innodb.cc | 39 +++++++++--------- 2 files changed, 55 insertions(+), 41 deletions(-) diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index 802f0bd8b6f..3dba63cc76a 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -4206,7 +4206,6 @@ dict_update_statistics_low( dictionary mutex */ { dict_index_t* index; - ulint size; ulint sum_of_index_sizes = 0; if (table->ibd_file_missing) { @@ -4221,14 +4220,6 @@ dict_update_statistics_low( return; } - /* If we have set a high innodb_force_recovery level, do not calculate - statistics, as a badly corrupted index can cause a crash in it. */ - - if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { - - return; - } - /* Find out the sizes of the indexes and how many different values for the key they approximately have */ @@ -4240,26 +4231,48 @@ dict_update_statistics_low( return; } - while (index) { - size = btr_get_size(index, BTR_TOTAL_SIZE); - index->stat_index_size = size; + do { + if (UNIV_LIKELY + (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE + || (srv_force_recovery < SRV_FORCE_NO_LOG_REDO + && dict_index_is_clust(index)))) { + ulint size; + size = btr_get_size(index, BTR_TOTAL_SIZE); - sum_of_index_sizes += size; + index->stat_index_size = size; - size = btr_get_size(index, BTR_N_LEAF_PAGES); + sum_of_index_sizes += size; - if (size == 0) { - /* The root node of the tree is a leaf */ - size = 1; + size = btr_get_size(index, BTR_N_LEAF_PAGES); + + if (size == 0) { + /* The root node of the tree is a leaf */ + size = 1; + } + + index->stat_n_leaf_pages = size; + + btr_estimate_number_of_different_key_vals(index); + } else { + /* If we have set a high innodb_force_recovery + level, do not calculate statistics, as a badly + corrupted index can cause a crash in it. + Initialize some bogus index cardinality + statistics, so that the data can be queried in + various means, also via secondary indexes. */ + ulint i; + + sum_of_index_sizes++; + index->stat_index_size = index->stat_n_leaf_pages = 1; + + for (i = dict_index_get_n_unique(index); i; ) { + index->stat_n_diff_key_vals[i--] = 1; + } } - index->stat_n_leaf_pages = size; - - btr_estimate_number_of_different_key_vals(index); - index = dict_table_get_next_index(index); - } + } while (index); index = dict_table_get_first_index(table); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index a004cba9603..bbf3c5aa3c8 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -7700,28 +7700,15 @@ ha_innobase::info( dict_index_t* index; ha_rows rec_per_key; ib_int64_t n_rows; - ulong j; - ulong i; char path[FN_REFLEN]; os_file_stat_t stat_info; - DBUG_ENTER("info"); /* If we are forcing recovery at a high level, we will suppress statistics calculation on tables, because that may crash the server if an index is badly corrupted. */ - if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { - - /* We return success (0) instead of HA_ERR_CRASHED, - because we want MySQL to process this query and not - stop, like it would do if it received the error code - HA_ERR_CRASHED. */ - - DBUG_RETURN(0); - } - /* We do not know if MySQL can call this function before calling external_lock(). To be safe, update the thd of the current table handle. */ @@ -7816,12 +7803,18 @@ ha_innobase::info( acquiring latches inside InnoDB, we do not call it if we are asked by MySQL to avoid locking. Another reason to avoid the call is that it uses quite a lot of CPU. - See Bug#38185. - We do not update delete_length if no locking is requested - so the "old" value can remain. delete_length is initialized - to 0 in the ha_statistics' constructor. */ - if (!(flag & HA_STATUS_NO_LOCK)) { - + See Bug#38185. */ + if (flag & HA_STATUS_NO_LOCK) { + /* We do not update delete_length if no + locking is requested so the "old" value can + remain. delete_length is initialized to 0 in + the ha_statistics' constructor. */ + } else if (UNIV_UNLIKELY + (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE)) { + /* Avoid accessing the tablespace if + innodb_crash_recovery is set to a high value. */ + stats.delete_length = 0; + } else { /* lock the data dictionary to avoid races with ibd_file_missing and tablespace_discarded */ row_mysql_lock_data_dictionary(prebuilt->trx); @@ -7866,6 +7859,7 @@ ha_innobase::info( } if (flag & HA_STATUS_CONST) { + ulong i; /* Verify the number of index in InnoDB and MySQL matches up. If prebuilt->clust_index_was_generated holds, InnoDB defines GEN_CLUST_INDEX internally */ @@ -7882,6 +7876,7 @@ ha_innobase::info( } for (i = 0; i < table->s->keys; i++) { + ulong j; /* We could get index quickly through internal index mapping with the index translation table. The identity of index (match up index name with @@ -7947,6 +7942,11 @@ ha_innobase::info( } } + if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { + + goto func_exit; + } + if (flag & HA_STATUS_ERRKEY) { const dict_index_t* err_index; @@ -7967,6 +7967,7 @@ ha_innobase::info( stats.auto_increment_value = innobase_peek_autoinc(); } +func_exit: prebuilt->trx->op_info = (char*)""; DBUG_RETURN(0); From bfcc8ae8d93ebb1ae23c5f12c8337843631cd6f0 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Wed, 25 Aug 2010 00:25:46 -0700 Subject: [PATCH 007/159] Add a space indentation to InnoDB buffer pool size and log sequence number boot up message. --- storage/innobase/srv/srv0start.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c index 05fa637e7bb..9bf18b8db9e 100644 --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c @@ -1337,7 +1337,7 @@ innobase_start_or_create_for_mysql(void) /* Print time to initialize the buffer pool */ ut_print_timestamp(stderr); fprintf(stderr, - " InnoDB: Initializing buffer pool, size ="); + " InnoDB: Initializing buffer pool, size ="); if (srv_buf_pool_size >= 1024 * 1024 * 1024) { fprintf(stderr, @@ -1353,7 +1353,7 @@ innobase_start_or_create_for_mysql(void) ut_print_timestamp(stderr); fprintf(stderr, - " InnoDB: Completed initialization of buffer pool\n"); + " InnoDB: Completed initialization of buffer pool\n"); if (err != DB_SUCCESS) { fprintf(stderr, @@ -1871,7 +1871,7 @@ innobase_start_or_create_for_mysql(void) if (srv_print_verbose_log) { ut_print_timestamp(stderr); fprintf(stderr, - " InnoDB %s started; " + " InnoDB: %s started; " "log sequence number %llu\n", INNODB_VERSION_STR, srv_start_lsn); } From 86327002fe29e70f0e29d97e0cf0b1e14806c2f8 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Mon, 30 Aug 2010 17:33:55 +0200 Subject: [PATCH 008/159] Bug#50036: Inconsistent errors when using TIMESTAMP columns/expressions It was hard to understand what the error really meant. The error checking in partitioning is done in several different parts during the execution of a query which can make it hard to return useful errors. Added a new error for bad VALUES part in the per PARTITION clause. Using the more verbose error that a column is not allowed in the partitioning function instead of just that the function is not allowed. mysql-test/r/partition.result: changed error to be more specific mysql-test/r/partition_error.result: updated result mysql-test/std_data/parts/t1TIMESTAMP.frm: .frm file of CREATE TABLE t1 (a TIMESTAMP) PARTITION BY HASH(TO_DAYS(a)); mysql-test/t/partition.test: changed error to be more specific mysql-test/t/partition_error.test: Added test (also for verifying behaviour of previously created tables which is no longer allowed). Updated expected errors in other places sql/partition_info.cc: Added function report_part_expr_error to be able to return a more specific error. Renamed fix_func_partition to fix_partition_values since the function really fixes/checks the VALUES clause. sql/partition_info.h: removed part_result_type, since it was unused. renamed fix_funk_partition->fix_partition_values added report_part_expr_error sql/share/errmsg-utf8.txt: Added a more specific error. sql/sql_partition.cc: made use of report_part_expr_error to get a more specific error. sql/sql_yacc.yy: Changed error message to be more specific. And return an other error code. --- mysql-test/r/partition.result | 4 +- mysql-test/r/partition_error.result | 130 +++++++++++++++++++++- mysql-test/std_data/parts/t1TIMESTAMP.frm | Bin 0 -> 8554 bytes mysql-test/t/partition.test | 4 +- mysql-test/t/partition_error.test | 102 ++++++++++++++++- sql/partition_info.cc | 66 +++++++++-- sql/partition_info.h | 11 +- sql/share/errmsg-utf8.txt | 4 + sql/sql_partition.cc | 18 +-- sql/sql_yacc.yy | 2 +- 10 files changed, 302 insertions(+), 39 deletions(-) create mode 100644 mysql-test/std_data/parts/t1TIMESTAMP.frm diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index 55366bd2e07..693c338fc76 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -520,12 +520,12 @@ create table t1 (a bigint) partition by range (a) (partition p0 values less than (0xFFFFFFFFFFFFFFFF), partition p1 values less than (10)); -ERROR HY000: VALUES value must be of same type as partition function +ERROR HY000: VALUES value for partition 'p0' must have type INT create table t1 (a bigint) partition by list (a) (partition p0 values in (0xFFFFFFFFFFFFFFFF), partition p1 values in (10)); -ERROR HY000: VALUES value must be of same type as partition function +ERROR HY000: VALUES value for partition 'p0' must have type INT create table t1 (a bigint unsigned) partition by range (a) (partition p0 values less than (100), diff --git a/mysql-test/r/partition_error.result b/mysql-test/r/partition_error.result index 25addd7fdea..830ca4bee10 100644 --- a/mysql-test/r/partition_error.result +++ b/mysql-test/r/partition_error.result @@ -1,4 +1,124 @@ -drop table if exists t1; +drop table if exists t1, t2; +# +# Bug#50036: Inconsistent errors when using TIMESTAMP +# columns/expressions +# 1. correct and appropriate errors in light of +# the fix for BUG#42849: +CREATE TABLE t1 (c TIMESTAMP) +PARTITION BY RANGE (TO_DAYS(c)) +(PARTITION p0 VALUES LESS THAN (10000), +PARTITION p1 VALUES LESS THAN (MAXVALUE)); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE t2 (c TIMESTAMP); +ALTER TABLE t2 +PARTITION BY RANGE (TO_DAYS(c)) +(PARTITION p0 VALUES LESS THAN (10000), +PARTITION p1 VALUES LESS THAN (MAXVALUE)); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE t1 (c TIMESTAMP) +PARTITION BY RANGE COLUMNS(c) +(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'), +PARTITION p1 VALUES LESS THAN (MAXVALUE)); +ERROR HY000: Field 'c' is of a not allowed type for this type of partitioning +ALTER TABLE t2 PARTITION BY RANGE COLUMNS(c) +(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'), +PARTITION p1 VALUES LESS THAN (MAXVALUE)); +ERROR HY000: Field 'c' is of a not allowed type for this type of partitioning +DROP TABLE t2; +# 2. These errors where questionable before the fix: +# VALUES clause are checked first, clearified the error message. +CREATE TABLE t1 (c TIMESTAMP) +PARTITION BY RANGE (c) +(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'), +PARTITION p1 VALUES LESS THAN (MAXVALUE)); +ERROR HY000: VALUES value for partition 'p0' must have type INT +# TIMESTAMP is not INT (e.g. UNIX_TIMESTAMP). +CREATE TABLE t1 (c TIMESTAMP) +PARTITION BY RANGE (UNIX_TIMESTAMP(c)) +(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'), +PARTITION p1 VALUES LESS THAN (MAXVALUE)); +ERROR HY000: VALUES value for partition 'p0' must have type INT +CREATE TABLE t1 (c TIMESTAMP) +PARTITION BY RANGE (UNIX_TIMESTAMP(c)) +(PARTITION p0 VALUES LESS THAN (UNIX_TIMESTAMP('2000-01-01 00:00:00')), +PARTITION p1 VALUES LESS THAN (MAXVALUE)); +DROP TABLE t1; +# Changed error from ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR +CREATE TABLE t1 (c TIMESTAMP) +PARTITION BY HASH (c) PARTITIONS 4; +ERROR HY000: Field 'c' is of a not allowed type for this type of partitioning +# Added test with existing TIMESTAMP partitioning (when it was allowed). +CREATE TABLE t1 (a TIMESTAMP) +PARTITION BY HASH (UNIX_TIMESTAMP(a)); +INSERT INTO t1 VALUES ('2000-01-02 03:04:05'); +SELECT * FROM t1; +a +2000-01-02 03:04:05 +FLUSH TABLES; +SELECT * FROM t1; +a +2000-01-02 03:04:05 +Warning 1486 Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +Warnings: +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY HASH (TO_DAYS(a)) */ +INSERT INTO t1 VALUES ('2001-02-03 04:05:06'); +SELECT * FROM t1; +a +2000-01-02 03:04:05 +2001-02-03 04:05:06 +ALTER TABLE t1 ADD PARTITION PARTITIONS 2; +ALTER TABLE t1 +PARTITION BY RANGE (TO_DAYS(a)) +(PARTITION p0 VALUES LESS THAN (10000), +PARTITION p1 VALUES LESS THAN (MAXVALUE)); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY HASH (TO_DAYS(a)) +PARTITIONS 3 */ +Warnings: +Warning 1486 Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE t2 LIKE t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY HASH (TO_DAYS(a)) +PARTITIONS 3 */ +Warnings: +Warning 1486 Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +DROP TABLE t2; +CREATE TABLE t2 SELECT * FROM t1; +DROP TABLE t2; +ALTER TABLE t1 PARTITION BY HASH (UNIX_TIMESTAMP(a)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY HASH (UNIX_TIMESTAMP(a)) */ +ALTER TABLE t1 ADD PARTITION PARTITIONS 2; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY HASH (UNIX_TIMESTAMP(a)) +PARTITIONS 3 */ +SELECT * FROM t1; +a +2000-01-02 03:04:05 +2001-02-03 04:05:06 +DROP TABLE t1; # # Bug#49161: Out of memory; restart server and try again (needed 2 bytes) # @@ -497,7 +617,7 @@ partition by range (a) partitions 2 (partition x1 values less than (4.0) tablespace ts1, partition x2 values less than (8) tablespace ts2); -ERROR HY000: VALUES value must be of same type as partition function +ERROR HY000: VALUES value for partition 'x1' must have type INT CREATE TABLE t1 ( a int not null, b int not null, @@ -736,7 +856,7 @@ partition by list (a) partitions 2 (partition x1 values in (4.0, 12+8), partition x2 values in (3, 21)); -ERROR HY000: VALUES value must be of same type as partition function +ERROR HY000: VALUES value for partition 'x1' must have type INT CREATE TABLE t1 ( a int not null, b int not null, @@ -796,12 +916,12 @@ CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) PARTITION BY RANGE (a) ( PARTITION p VALUES LESS THAN (20080819), PARTITION pmax VALUES LESS THAN MAXVALUE); -ERROR HY000: The PARTITION function returns the wrong type +ERROR HY000: Field 'a' is of a not allowed type for this type of partitioning ALTER TABLE old PARTITION BY RANGE (a) ( PARTITION p VALUES LESS THAN (20080819), PARTITION pmax VALUES LESS THAN MAXVALUE); -ERROR HY000: The PARTITION function returns the wrong type +ERROR HY000: Field 'a' is of a not allowed type for this type of partitioning CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) PARTITION BY RANGE (a+0) ( PARTITION p VALUES LESS THAN (20080819), diff --git a/mysql-test/std_data/parts/t1TIMESTAMP.frm b/mysql-test/std_data/parts/t1TIMESTAMP.frm new file mode 100644 index 0000000000000000000000000000000000000000..c9fc49d86a918b24ba07232be14dd9266ecec281 GIT binary patch literal 8554 zcmeI%F%JPT7{>8`i*TFdgi%K~5s8(Y7+AP)i%D)|K*TrnJ$w|WahIEo63;XAecPr@ z^IQ8eL8k_710!E(P{p=rQ7rgcr0vV|0prg!fZ-5av8Pc25|DrdBp?9^NI(J-kbndv zAb}qiu;kV2$}ZrV-R{Tx@pA6_J(tAWbd|0)Yd7D!WxQLuLAp6C;{9%rMNxHHjRYhh z0SQPz0uqpb1SB8<2}nQ!zbJ4r{?q@DV=znzy+DI{>0n9dmi+{4Y$tMG#@}Hx>NX6q MFr^308RS{c8xS%aYybcN literal 0 HcmV?d00001 diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 1224dee24ed..fe2ef8cea1f 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -430,12 +430,12 @@ drop table t1; # # BUG 16002: Handle unsigned integer functions properly # ---error ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR +--error ER_VALUES_IS_NOT_INT_TYPE_ERROR create table t1 (a bigint) partition by range (a) (partition p0 values less than (0xFFFFFFFFFFFFFFFF), partition p1 values less than (10)); ---error ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR +--error ER_VALUES_IS_NOT_INT_TYPE_ERROR create table t1 (a bigint) partition by list (a) (partition p0 values in (0xFFFFFFFFFFFFFFFF), diff --git a/mysql-test/t/partition_error.test b/mysql-test/t/partition_error.test index 1496a626796..1afb65d496c 100644 --- a/mysql-test/t/partition_error.test +++ b/mysql-test/t/partition_error.test @@ -5,11 +5,103 @@ -- source include/have_partition.inc --disable_warnings -drop table if exists t1; +drop table if exists t1, t2; --enable_warnings let $MYSQLD_DATADIR= `SELECT @@datadir`; +--echo # +--echo # Bug#50036: Inconsistent errors when using TIMESTAMP +--echo # columns/expressions + +--echo # 1. correct and appropriate errors in light of +--echo # the fix for BUG#42849: +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE t1 (c TIMESTAMP) +PARTITION BY RANGE (TO_DAYS(c)) +(PARTITION p0 VALUES LESS THAN (10000), + PARTITION p1 VALUES LESS THAN (MAXVALUE)); +CREATE TABLE t2 (c TIMESTAMP); +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE t2 +PARTITION BY RANGE (TO_DAYS(c)) +(PARTITION p0 VALUES LESS THAN (10000), + PARTITION p1 VALUES LESS THAN (MAXVALUE)); + +--error ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD +CREATE TABLE t1 (c TIMESTAMP) +PARTITION BY RANGE COLUMNS(c) +(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'), + PARTITION p1 VALUES LESS THAN (MAXVALUE)); +--error ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD +ALTER TABLE t2 PARTITION BY RANGE COLUMNS(c) +(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'), + PARTITION p1 VALUES LESS THAN (MAXVALUE)); +DROP TABLE t2; + +--echo # 2. These errors where questionable before the fix: + +--echo # VALUES clause are checked first, clearified the error message. +--error ER_VALUES_IS_NOT_INT_TYPE_ERROR +CREATE TABLE t1 (c TIMESTAMP) +PARTITION BY RANGE (c) +(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'), + PARTITION p1 VALUES LESS THAN (MAXVALUE)); + +--echo # TIMESTAMP is not INT (e.g. UNIX_TIMESTAMP). +--error ER_VALUES_IS_NOT_INT_TYPE_ERROR +CREATE TABLE t1 (c TIMESTAMP) +PARTITION BY RANGE (UNIX_TIMESTAMP(c)) +(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'), + PARTITION p1 VALUES LESS THAN (MAXVALUE)); + +CREATE TABLE t1 (c TIMESTAMP) +PARTITION BY RANGE (UNIX_TIMESTAMP(c)) +(PARTITION p0 VALUES LESS THAN (UNIX_TIMESTAMP('2000-01-01 00:00:00')), + PARTITION p1 VALUES LESS THAN (MAXVALUE)); +DROP TABLE t1; + +--echo # Changed error from ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR +--error ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD +CREATE TABLE t1 (c TIMESTAMP) +PARTITION BY HASH (c) PARTITIONS 4; + +--echo # Added test with existing TIMESTAMP partitioning (when it was allowed). + +CREATE TABLE t1 (a TIMESTAMP) +PARTITION BY HASH (UNIX_TIMESTAMP(a)); +INSERT INTO t1 VALUES ('2000-01-02 03:04:05'); +--sorted_result +SELECT * FROM t1; +FLUSH TABLES; +--remove_file $MYSQLD_DATADIR/test/t1.frm +--copy_file std_data/parts/t1TIMESTAMP.frm $MYSQLD_DATADIR/test/t1.frm +--sorted_result +SELECT * FROM t1; +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES ('2001-02-03 04:05:06'); +--sorted_result +SELECT * FROM t1; +ALTER TABLE t1 ADD PARTITION PARTITIONS 2; +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE t1 +PARTITION BY RANGE (TO_DAYS(a)) +(PARTITION p0 VALUES LESS THAN (10000), + PARTITION p1 VALUES LESS THAN (MAXVALUE)); +SHOW CREATE TABLE t1; +CREATE TABLE t2 LIKE t1; +SHOW CREATE TABLE t2; +DROP TABLE t2; +CREATE TABLE t2 SELECT * FROM t1; +DROP TABLE t2; +ALTER TABLE t1 PARTITION BY HASH (UNIX_TIMESTAMP(a)); +SHOW CREATE TABLE t1; +ALTER TABLE t1 ADD PARTITION PARTITIONS 2; +SHOW CREATE TABLE t1; +--sorted_result +SELECT * FROM t1; +DROP TABLE t1; + --echo # --echo # Bug#49161: Out of memory; restart server and try again (needed 2 bytes) --echo # @@ -536,7 +628,7 @@ partitions 2 # # Partition by range, inconsistent partition function and constants # ---error ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR +--error ER_VALUES_IS_NOT_INT_TYPE_ERROR CREATE TABLE t1 ( a int not null, b int not null, @@ -849,7 +941,7 @@ partitions 2 # # Partition by list, wrong constant result type (not INT) # ---error ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR +--error ER_VALUES_IS_NOT_INT_TYPE_ERROR CREATE TABLE t1 ( a int not null, b int not null, @@ -939,13 +1031,13 @@ PARTITION pmax VALUES LESS THAN MAXVALUE); # Check that allowed arithmetic/math functions involving TIMESTAMP values result # in ER_PARTITION_FUNC_NOT_ALLOWED_ERROR when used as a partitioning function ---error ER_PARTITION_FUNC_NOT_ALLOWED_ERROR +--error ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) PARTITION BY RANGE (a) ( PARTITION p VALUES LESS THAN (20080819), PARTITION pmax VALUES LESS THAN MAXVALUE); ---error ER_PARTITION_FUNC_NOT_ALLOWED_ERROR +--error ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD ALTER TABLE old PARTITION BY RANGE (a) ( PARTITION p VALUES LESS THAN (20080819), diff --git a/sql/partition_info.cc b/sql/partition_info.cc index caf28fdd83e..879e7b10023 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -742,7 +742,6 @@ bool partition_info::check_range_constants(THD *thd) longlong part_range_value; bool signed_flag= !part_expr->unsigned_flag; - part_result_type= INT_RESULT; range_int_array= (longlong*)sql_alloc(num_parts * sizeof(longlong)); if (unlikely(range_int_array == NULL)) { @@ -917,7 +916,6 @@ bool partition_info::check_list_constants(THD *thd) List_iterator list_func_it(partitions); DBUG_ENTER("partition_info::check_list_constants"); - part_result_type= INT_RESULT; num_list_values= 0; /* We begin by calculating the number of list values that have been @@ -1608,6 +1606,52 @@ id_err: return 1; } + +/** + Check what kind of error to report + + @param use_subpart_expr Use the subpart_expr instead of part_expr + @param part_str Name of partition to report error (or NULL) +*/ +void partition_info::report_part_expr_error(bool use_subpart_expr) +{ + Item *expr= part_expr; + DBUG_ENTER("partition_info::report_part_expr_error"); + if (use_subpart_expr) + expr= subpart_expr; + + if (expr->type() == Item::FIELD_ITEM) + { + partition_type type= part_type; + bool list_of_fields= list_of_part_fields; + Item_field *item_field= (Item_field*) expr; + /* + The expression consists of a single field. + It must be of integer type unless KEY or COLUMNS partitioning. + */ + if (use_subpart_expr) + { + type= subpart_type; + list_of_fields= list_of_subpart_fields; + } + if (!column_list && + item_field->field && + item_field->field->result_type() != INT_RESULT && + !(type == HASH_PARTITION && list_of_fields)) + { + my_error(ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD, MYF(0), + item_field->name); + DBUG_VOID_RETURN; + } + } + if (use_subpart_expr) + my_error(ER_PARTITION_FUNC_NOT_ALLOWED_ERROR, MYF(0), "SUBPARTITION"); + else + my_error(ER_PARTITION_FUNC_NOT_ALLOWED_ERROR, MYF(0), "PARTITION"); + DBUG_VOID_RETURN; +} + + /* Create a new column value in current list with maxvalue Called from parser @@ -1891,7 +1935,7 @@ int partition_info::reorganize_into_single_field_col_val() code. SYNOPSIS - fix_func_partition() + fix_partition_values() thd Thread object col_val Array of one value part_elem The partition instance @@ -1901,13 +1945,13 @@ int partition_info::reorganize_into_single_field_col_val() TRUE Failure FALSE Success */ -int partition_info::fix_func_partition(THD *thd, - part_elem_value *val, - partition_element *part_elem, - uint part_id) +int partition_info::fix_partition_values(THD *thd, + part_elem_value *val, + partition_element *part_elem, + uint part_id) { part_column_list_val *col_val= val->col_val_array; - DBUG_ENTER("partition_info::fix_func_partition"); + DBUG_ENTER("partition_info::fix_partition_values"); if (col_val->fixed) { @@ -1953,7 +1997,9 @@ int partition_info::fix_func_partition(THD *thd, } else if (item_expr->result_type() != INT_RESULT) { - my_error(ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR, MYF(0)); + /* VALUES clause only allowed on partitions, not subpartitions */ + my_error(ER_VALUES_IS_NOT_INT_TYPE_ERROR, MYF(0), + part_elem->partition_name); DBUG_RETURN(TRUE); } if (part_type == RANGE_PARTITION) @@ -2168,7 +2214,7 @@ int partition_info::fix_parser_data(THD *thd) } else { - if (fix_func_partition(thd, val, part_elem, i)) + if (fix_partition_values(thd, val, part_elem, i)) { DBUG_RETURN(TRUE); } diff --git a/sql/partition_info.h b/sql/partition_info.h index b196d0b59a2..6ae210d9574 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -166,7 +166,6 @@ public: key_map some_fields_in_PF; handlerton *default_engine_type; - Item_result part_result_type; partition_type part_type; partition_type subpart_type; @@ -226,7 +225,6 @@ public: curr_part_elem(NULL), current_partition(NULL), curr_list_object(0), num_columns(0), default_engine_type(NULL), - part_result_type(INT_RESULT), part_type(NOT_A_PARTITION), subpart_type(NOT_A_PARTITION), part_info_len(0), part_func_len(0), subpart_func_len(0), @@ -279,10 +277,10 @@ public: void print_no_partition_found(TABLE *table); void print_debug(const char *str, uint*); Item* get_column_item(Item *item, Field *field); - int fix_func_partition(THD *thd, - part_elem_value *val, - partition_element *part_elem, - uint part_id); + int fix_partition_values(THD *thd, + part_elem_value *val, + partition_element *part_elem, + uint part_id); bool fix_column_value_functions(THD *thd, part_elem_value *val, uint part_id); @@ -299,6 +297,7 @@ public: bool init_column_part(); bool add_column_list_value(THD *thd, Item *item); void set_show_version_string(String *packet); + void report_part_expr_error(bool use_subpart_expr); private: static int list_part_cmp(const void* a, const void* b); bool set_up_default_partitions(handler *file, HA_CREATE_INFO *info, diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 9e7fdbfeae5..7b7f9024a63 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6346,3 +6346,7 @@ ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN ER_FAILED_READ_FROM_PAR_FILE eng "Failed to read from the .par file" swe "Misslyckades läsa frÃ¥n .par filen" + +ER_VALUES_IS_NOT_INT_TYPE_ERROR + eng "VALUES value for partition '%-.64s' must have type INT" + swe "Värden i VALUES för partition '%-.64s' mÃ¥ste ha typen INT" diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index b72816f8ce3..d95ba3fa71e 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1762,8 +1762,7 @@ bool fix_partition_func(THD *thd, TABLE *table, goto end; if (unlikely(part_info->subpart_expr->result_type() != INT_RESULT)) { - my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0), - subpart_str); + part_info->report_part_expr_error(TRUE); goto end; } } @@ -1790,10 +1789,9 @@ bool fix_partition_func(THD *thd, TABLE *table, goto end; if (unlikely(part_info->part_expr->result_type() != INT_RESULT)) { - my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0), part_str); + part_info->report_part_expr_error(FALSE); goto end; } - part_info->part_result_type= INT_RESULT; } part_info->fixed= TRUE; } @@ -1839,18 +1837,22 @@ bool fix_partition_func(THD *thd, TABLE *table, if (unlikely(!part_info->column_list && part_info->part_expr->result_type() != INT_RESULT)) { - my_error(ER_PARTITION_FUNC_NOT_ALLOWED_ERROR, MYF(0), part_str); + part_info->report_part_expr_error(FALSE); goto end; } } if (((part_info->part_type != HASH_PARTITION || - part_info->list_of_part_fields == FALSE) && - (!part_info->column_list && - check_part_func_fields(part_info->part_field_array, TRUE))) || + part_info->list_of_part_fields == FALSE) && + !part_info->column_list && + check_part_func_fields(part_info->part_field_array, TRUE)) || (part_info->list_of_subpart_fields == FALSE && part_info->is_sub_partitioned() && check_part_func_fields(part_info->subpart_field_array, TRUE))) { + /* + Range/List/HASH (but not KEY) and not COLUMNS or HASH subpartitioning + with columns in the partitioning expression using unallowed charset. + */ my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0)); goto end; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 6a510c04054..70e7e21cef4 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4813,7 +4813,7 @@ part_value_expr_item: if (!lex->safe_to_cache_query) { - my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0)); + my_parse_error(ER(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR)); MYSQL_YYABORT; } if (part_info->add_column_list_value(YYTHD, part_expr)) From 7f36cd6cdda7819d0a743d224b867c2a2d6abdd1 Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Mon, 6 Sep 2010 22:41:37 -0700 Subject: [PATCH 009/159] Port fix for bug #53756 from 5.1 built-in to 5.1 plugin. --- .../innodb_plugin/r/innodb_bug53756.result | 118 +++++++++++ .../t/innodb_bug53756-master.opt | 1 + .../innodb_plugin/t/innodb_bug53756.test | 184 ++++++++++++++++++ storage/innodb_plugin/ChangeLog | 4 + storage/innodb_plugin/dict/dict0load.c | 27 ++- 5 files changed, 320 insertions(+), 14 deletions(-) create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug53756.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug53756-master.opt create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug53756.test diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug53756.result b/mysql-test/suite/innodb_plugin/r/innodb_bug53756.result new file mode 100644 index 00000000000..37453be8201 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug53756.result @@ -0,0 +1,118 @@ +DROP TABLE IF EXISTS bug_53756 ; +CREATE TABLE bug_53756 (pk INT, c1 INT) ENGINE=InnoDB; +ALTER TABLE bug_53756 ADD PRIMARY KEY (pk); +INSERT INTO bug_53756 VALUES(1, 11), (2, 22), (3, 33), (4, 44); + +# Select a less restrictive isolation level. +SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +COMMIT; + +# Start a transaction in the default connection for isolation. +START TRANSACTION; +SELECT @@tx_isolation; +@@tx_isolation +READ-COMMITTED +SELECT * FROM bug_53756; +pk c1 +1 11 +2 22 +3 33 +4 44 + +# connection con1 deletes row 1 +START TRANSACTION; +SELECT @@tx_isolation; +@@tx_isolation +READ-COMMITTED +DELETE FROM bug_53756 WHERE pk=1; + +# connection con2 deletes row 2 +START TRANSACTION; +SELECT @@tx_isolation; +@@tx_isolation +READ-COMMITTED +DELETE FROM bug_53756 WHERE pk=2; + +# connection con3 updates row 3 +START TRANSACTION; +SELECT @@tx_isolation; +@@tx_isolation +READ-COMMITTED +UPDATE bug_53756 SET c1=77 WHERE pk=3; + +# connection con4 updates row 4 +START TRANSACTION; +SELECT @@tx_isolation; +@@tx_isolation +READ-COMMITTED +UPDATE bug_53756 SET c1=88 WHERE pk=4; + +# connection con5 inserts row 5 +START TRANSACTION; +SELECT @@tx_isolation; +@@tx_isolation +READ-COMMITTED +INSERT INTO bug_53756 VALUES(5, 55); + +# connection con6 inserts row 6 +START TRANSACTION; +SELECT @@tx_isolation; +@@tx_isolation +READ-COMMITTED +INSERT INTO bug_53756 VALUES(6, 66); + +# connection con1 commits. +COMMIT; + +# connection con3 commits. +COMMIT; + +# connection con4 rolls back. +ROLLBACK; + +# connection con6 rolls back. +ROLLBACK; + +# The connections 2 and 5 stay open. + +# connection default selects resulting data. +# Delete of row 1 was committed. +# Update of row 3 was committed. +# Due to isolation level read committed, these should be included. +# All other changes should not be included. +SELECT * FROM bug_53756; +pk c1 +2 22 +3 77 +4 44 + +# connection default +# +# Crash server. +START TRANSACTION; +INSERT INTO bug_53756 VALUES (666,666); +SET SESSION debug="+d,crash_commit_before"; +COMMIT; +ERROR HY000: Lost connection to MySQL server during query + +# +# disconnect con1, con2, con3, con4, con5, con6. +# +# Restart server. + +# +# Select recovered data. +# Delete of row 1 was committed. +# Update of row 3 was committed. +# These should be included. +# All other changes should not be included. +# Delete of row 2 and insert of row 5 should be rolled back +SELECT * FROM bug_53756; +pk c1 +2 22 +3 77 +4 44 + +# Clean up. +DROP TABLE bug_53756; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug53756-master.opt b/mysql-test/suite/innodb_plugin/t/innodb_bug53756-master.opt new file mode 100644 index 00000000000..425fda95086 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug53756-master.opt @@ -0,0 +1 @@ +--skip-stack-trace --skip-core-file diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug53756.test b/mysql-test/suite/innodb_plugin/t/innodb_bug53756.test new file mode 100644 index 00000000000..0623be1d0ae --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug53756.test @@ -0,0 +1,184 @@ +# This is the test case for bug #53756. Alter table operation could +# leave a deleted record for the temp table (later renamed to the altered +# table) in the SYS_TABLES secondary index, we should ignore this row and +# find the first non-deleted row for the specified table_id when load table +# metadata in the function dict_load_table_on_id() during crash recovery. + +# +# innobackup needs to connect to the server. Not supported in embedded. +--source include/not_embedded.inc +# +# This test case needs to crash the server. Needs a debug server. +--source include/have_debug.inc +# +# Don't test this under valgrind, memory leaks will occur. +--source include/not_valgrind.inc +# +# This test case needs InnoDB. +-- source include/have_innodb_plugin.inc + +# +# Precautionary clean up. +# +--disable_warnings +DROP TABLE IF EXISTS bug_53756 ; +--enable_warnings + +# +# Create test data. +# +CREATE TABLE bug_53756 (pk INT, c1 INT) ENGINE=InnoDB; +ALTER TABLE bug_53756 ADD PRIMARY KEY (pk); +INSERT INTO bug_53756 VALUES(1, 11), (2, 22), (3, 33), (4, 44); + +--echo +--echo # Select a less restrictive isolation level. +# Don't use user variables. They won't survive server crash. +--let $global_isolation= `SELECT @@global.tx_isolation`; +--let $session_isolation= `SELECT @@session.tx_isolation`; +SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED; +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +COMMIT; + +--echo +--echo # Start a transaction in the default connection for isolation. +START TRANSACTION; +SELECT @@tx_isolation; +SELECT * FROM bug_53756; + +--echo +--echo # connection con1 deletes row 1 +--connect (con1,localhost,root,,) +START TRANSACTION; +SELECT @@tx_isolation; +DELETE FROM bug_53756 WHERE pk=1; + +--echo +--echo # connection con2 deletes row 2 +--connect (con2,localhost,root,,) +START TRANSACTION; +SELECT @@tx_isolation; +DELETE FROM bug_53756 WHERE pk=2; + +--echo +--echo # connection con3 updates row 3 +--connect (con3,localhost,root,,) +START TRANSACTION; +SELECT @@tx_isolation; +UPDATE bug_53756 SET c1=77 WHERE pk=3; + +--echo +--echo # connection con4 updates row 4 +--connect (con4,localhost,root,,) +START TRANSACTION; +SELECT @@tx_isolation; +UPDATE bug_53756 SET c1=88 WHERE pk=4; + +--echo +--echo # connection con5 inserts row 5 +--connect (con5,localhost,root,,) +START TRANSACTION; +SELECT @@tx_isolation; +INSERT INTO bug_53756 VALUES(5, 55); + +--echo +--echo # connection con6 inserts row 6 +--connect (con6,localhost,root,,) +START TRANSACTION; +SELECT @@tx_isolation; +INSERT INTO bug_53756 VALUES(6, 66); + +--echo +--echo # connection con1 commits. +--connection con1 +COMMIT; + +--echo +--echo # connection con3 commits. +--connection con3 +COMMIT; + +--echo +--echo # connection con4 rolls back. +--connection con4 +ROLLBACK; + +--echo +--echo # connection con6 rolls back. +--connection con6 +ROLLBACK; + +--echo +--echo # The connections 2 and 5 stay open. + +--echo +--echo # connection default selects resulting data. +--echo # Delete of row 1 was committed. +--echo # Update of row 3 was committed. +--echo # Due to isolation level read committed, these should be included. +--echo # All other changes should not be included. +--connection default +SELECT * FROM bug_53756; + +--echo +--echo # connection default +--connection default +--echo # +--echo # Crash server. +# +# Write file to make mysql-test-run.pl expect the "crash", but don't start +# it until it's told to +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +# +START TRANSACTION; +INSERT INTO bug_53756 VALUES (666,666); +# +# Request a crash on next execution of commit. +SET SESSION debug="+d,crash_commit_before"; +# +# Execute the statement that causes the crash. +--error 2013 +COMMIT; +--echo +--echo # +--echo # disconnect con1, con2, con3, con4, con5, con6. +--disconnect con1 +--disconnect con2 +--disconnect con3 +--disconnect con4 +--disconnect con5 +--disconnect con6 +--echo # +--echo # Restart server. +# +# Write file to make mysql-test-run.pl start up the server again +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +# +# Turn on reconnect +--enable_reconnect +# +# Call script that will poll the server waiting for it to be back online again +--source include/wait_until_connected_again.inc +# +# Turn off reconnect again +--disable_reconnect +--echo + +--echo # +--echo # Select recovered data. +--echo # Delete of row 1 was committed. +--echo # Update of row 3 was committed. +--echo # These should be included. +--echo # All other changes should not be included. +--echo # Delete of row 2 and insert of row 5 should be rolled back +SELECT * FROM bug_53756; + +--echo +--echo # Clean up. +DROP TABLE bug_53756; + +--disable_query_log +eval SET GLOBAL tx_isolation= '$global_isolation'; +eval SET SESSION tx_isolation= '$session_isolation'; +--enable_query_log + diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 538cd40dd5b..19ff64562fc 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,7 @@ +2010-09-06 The InnoDB Team + * dict/dict0load.c, innodb_bug53756.test innodb_bug53756.result + Fix Bug #53756 ALTER TABLE ADD PRIMARY KEY affects crash recovery + 2010-08-24 The InnoDB Team * handler/ha_innodb.c, dict/dict0dict.c: diff --git a/storage/innodb_plugin/dict/dict0load.c b/storage/innodb_plugin/dict/dict0load.c index 3c495d21786..e20c9c57379 100644 --- a/storage/innodb_plugin/dict/dict0load.c +++ b/storage/innodb_plugin/dict/dict0load.c @@ -1072,6 +1072,8 @@ dict_load_table_on_id( ut_ad(mutex_own(&(dict_sys->mutex))); + table = NULL; + /* NOTE that the operation of this function is protected by the dictionary mutex, and therefore no deadlocks can occur with other dictionary operations. */ @@ -1098,15 +1100,17 @@ dict_load_table_on_id( BTR_SEARCH_LEAF, &pcur, &mtr); rec = btr_pcur_get_rec(&pcur); - if (!btr_pcur_is_on_user_rec(&pcur) - || rec_get_deleted_flag(rec, 0)) { + if (!btr_pcur_is_on_user_rec(&pcur)) { /* Not found */ + goto func_exit; + } - btr_pcur_close(&pcur); - mtr_commit(&mtr); - mem_heap_free(heap); - - return(NULL); + /* Find the first record that is not delete marked */ + while (rec_get_deleted_flag(rec, 0)) { + if (!btr_pcur_move_to_next_user_rec(&pcur, &mtr)) { + goto func_exit; + } + rec = btr_pcur_get_rec(&pcur); } /*---------------------------------------------------*/ @@ -1119,19 +1123,14 @@ dict_load_table_on_id( /* Check if the table id in record is the one searched for */ if (ut_dulint_cmp(table_id, mach_read_from_8(field)) != 0) { - - btr_pcur_close(&pcur); - mtr_commit(&mtr); - mem_heap_free(heap); - - return(NULL); + goto func_exit; } /* Now we get the table name from the record */ field = rec_get_nth_field_old(rec, 1, &len); /* Load the table definition to memory */ table = dict_load_table(mem_heap_strdupl(heap, (char*) field, len)); - +func_exit: btr_pcur_close(&pcur); mtr_commit(&mtr); mem_heap_free(heap); From da437a06d672da67114d2c46e9fa718a71b46ed1 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 7 Sep 2010 21:09:50 +0300 Subject: [PATCH 010/159] Fix Bug#56384 Remove two COPYING files from innobase directory Remove non applicable licensing files storage/innobase/COPYING is in the MySQL top level directory and storage/innobase/COPYING.Sun_Microsystems is not applicable anymore now that Oracle and Sun are one company. --- storage/innobase/COPYING | 351 ---------------------- storage/innobase/COPYING.Sun_Microsystems | 31 -- 2 files changed, 382 deletions(-) delete mode 100644 storage/innobase/COPYING delete mode 100644 storage/innobase/COPYING.Sun_Microsystems diff --git a/storage/innobase/COPYING b/storage/innobase/COPYING deleted file mode 100644 index 6b106e18fdb..00000000000 --- a/storage/innobase/COPYING +++ /dev/null @@ -1,351 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -Preamble -======== - -The licenses for most software are designed to take away your freedom -to share and change it. By contrast, the GNU General Public License is -intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - -When we speak of free software, we are referring to freedom, not price. -Our General Public Licenses are designed to make sure that you have -the freedom to distribute copies of free software (and charge for this -service if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs; and that you know you can do these things. - -To protect your rights, we need to make restrictions that forbid anyone -to deny you these rights or to ask you to surrender the rights. These -restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - -For example, if you distribute copies of such a program, whether gratis -or for a fee, you must give the recipients all the rights that you -have. You must make sure that they, too, receive or can get the source -code. And you must show them these terms so they know their rights. - -We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - -Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - -Finally, any free program is threatened constantly by software patents. -We wish to avoid the danger that redistributors of a free program will -individually obtain patent licenses, in effect making the program -proprietary. To prevent this, we have made it clear that any patent -must be licensed for everyone's free use or not licensed at all. - -The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - 0. This License applies to any program or other work which contains a - notice placed by the copyright holder saying it may be distributed - under the terms of this General Public License. The "Program", - below, refers to any such program or work, and a "work based on - the Program" means either the Program or any derivative work under - copyright law: that is to say, a work containing the Program or a - portion of it, either verbatim or with modifications and/or - translated into another language. (Hereinafter, translation is - included without limitation in the term "modification".) Each - licensee is addressed as "you". - - Activities other than copying, distribution and modification are - not covered by this License; they are outside its scope. The act - of running the Program is not restricted, and the output from the - Program is covered only if its contents constitute a work based on - the Program (independent of having been made by running the - Program). Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's - source code as you receive it, in any medium, provided that you - conspicuously and appropriately publish on each copy an appropriate - copyright notice and disclaimer of warranty; keep intact all the - notices that refer to this License and to the absence of any - warranty; and give any other recipients of the Program a copy of - this License along with the Program. - - You may charge a fee for the physical act of transferring a copy, - and you may at your option offer warranty protection in exchange - for a fee. - - 2. You may modify your copy or copies of the Program or any portion - of it, thus forming a work based on the Program, and copy and - distribute such modifications or work under the terms of Section 1 - above, provided that you also meet all of these conditions: - - a. You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b. You must cause any work that you distribute or publish, that - in whole or in part contains or is derived from the Program - or any part thereof, to be licensed as a whole at no charge - to all third parties under the terms of this License. - - c. If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display - an announcement including an appropriate copyright notice and - a notice that there is no warranty (or else, saying that you - provide a warranty) and that users may redistribute the - program under these conditions, and telling the user how to - view a copy of this License. (Exception: if the Program - itself is interactive but does not normally print such an - announcement, your work based on the Program is not required - to print an announcement.) - - These requirements apply to the modified work as a whole. If - identifiable sections of that work are not derived from the - Program, and can be reasonably considered independent and separate - works in themselves, then this License, and its terms, do not - apply to those sections when you distribute them as separate - works. But when you distribute the same sections as part of a - whole which is a work based on the Program, the distribution of - the whole must be on the terms of this License, whose permissions - for other licensees extend to the entire whole, and thus to each - and every part regardless of who wrote it. - - Thus, it is not the intent of this section to claim rights or - contest your rights to work written entirely by you; rather, the - intent is to exercise the right to control the distribution of - derivative or collective works based on the Program. - - In addition, mere aggregation of another work not based on the - Program with the Program (or with a work based on the Program) on - a volume of a storage or distribution medium does not bring the - other work under the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, - under Section 2) in object code or executable form under the terms - of Sections 1 and 2 above provided that you also do one of the - following: - - a. Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of - Sections 1 and 2 above on a medium customarily used for - software interchange; or, - - b. Accompany it with a written offer, valid for at least three - years, to give any third-party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a - medium customarily used for software interchange; or, - - c. Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with - such an offer, in accord with Subsection b above.) - - The source code for a work means the preferred form of the work for - making modifications to it. For an executable work, complete - source code means all the source code for all modules it contains, - plus any associated interface definition files, plus the scripts - used to control compilation and installation of the executable. - However, as a special exception, the source code distributed need - not include anything that is normally distributed (in either - source or binary form) with the major components (compiler, - kernel, and so on) of the operating system on which the executable - runs, unless that component itself accompanies the executable. - - If distribution of executable or object code is made by offering - access to copy from a designated place, then offering equivalent - access to copy the source code from the same place counts as - distribution of the source code, even though third parties are not - compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program - except as expressly provided under this License. Any attempt - otherwise to copy, modify, sublicense or distribute the Program is - void, and will automatically terminate your rights under this - License. However, parties who have received copies, or rights, - from you under this License will not have their licenses - terminated so long as such parties remain in full compliance. - - 5. You are not required to accept this License, since you have not - signed it. However, nothing else grants you permission to modify - or distribute the Program or its derivative works. These actions - are prohibited by law if you do not accept this License. - Therefore, by modifying or distributing the Program (or any work - based on the Program), you indicate your acceptance of this - License to do so, and all its terms and conditions for copying, - distributing or modifying the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the - Program), the recipient automatically receives a license from the - original licensor to copy, distribute or modify the Program - subject to these terms and conditions. You may not impose any - further restrictions on the recipients' exercise of the rights - granted herein. You are not responsible for enforcing compliance - by third parties to this License. - - 7. If, as a consequence of a court judgment or allegation of patent - infringement or for any other reason (not limited to patent - issues), conditions are imposed on you (whether by court order, - agreement or otherwise) that contradict the conditions of this - License, they do not excuse you from the conditions of this - License. If you cannot distribute so as to satisfy simultaneously - your obligations under this License and any other pertinent - obligations, then as a consequence you may not distribute the - Program at all. For example, if a patent license would not permit - royalty-free redistribution of the Program by all those who - receive copies directly or indirectly through you, then the only - way you could satisfy both it and this License would be to refrain - entirely from distribution of the Program. - - If any portion of this section is held invalid or unenforceable - under any particular circumstance, the balance of the section is - intended to apply and the section as a whole is intended to apply - in other circumstances. - - It is not the purpose of this section to induce you to infringe any - patents or other property right claims or to contest validity of - any such claims; this section has the sole purpose of protecting - the integrity of the free software distribution system, which is - implemented by public license practices. Many people have made - generous contributions to the wide range of software distributed - through that system in reliance on consistent application of that - system; it is up to the author/donor to decide if he or she is - willing to distribute software through any other system and a - licensee cannot impose that choice. - - This section is intended to make thoroughly clear what is believed - to be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in - certain countries either by patents or by copyrighted interfaces, - the original copyright holder who places the Program under this - License may add an explicit geographical distribution limitation - excluding those countries, so that distribution is permitted only - in or among countries not thus excluded. In such case, this - License incorporates the limitation as if written in the body of - this License. - - 9. The Free Software Foundation may publish revised and/or new - versions of the General Public License from time to time. Such - new versions will be similar in spirit to the present version, but - may differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the - Program specifies a version number of this License which applies - to it and "any later version", you have the option of following - the terms and conditions either of that version or of any later - version published by the Free Software Foundation. If the Program - does not specify a version number of this License, you may choose - any version ever published by the Free Software Foundation. - - 10. If you wish to incorporate parts of the Program into other free - programs whose distribution conditions are different, write to the - author to ask for permission. For software which is copyrighted - by the Free Software Foundation, write to the Free Software - Foundation; we sometimes make exceptions for this. Our decision - will be guided by the two goals of preserving the free status of - all derivatives of our free software and of promoting the sharing - and reuse of software generally. - - NO WARRANTY - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO - WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE - LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT - HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT - WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT - NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE - QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE - PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY - SERVICING, REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN - WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY - MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE - LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, - INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR - INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF - DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU - OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY - OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS -How to Apply These Terms to Your New Programs -============================================= - -If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these -terms. - -To do so, attach the following notices to the program. It is safest to -attach them to the start of each source file to most effectively convey -the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES. - Copyright (C) YYYY NAME OF AUTHOR - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19YY NAME OF AUTHOR - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the -appropriate parts of the General Public License. Of course, the -commands you use may be called something other than `show w' and `show -c'; they could even be mouse-clicks or menu items--whatever suits your -program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - SIGNATURE OF TY COON, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, -you may consider it more useful to permit linking proprietary -applications with the library. If this is what you want to do, use the -GNU Library General Public License instead of this License. diff --git a/storage/innobase/COPYING.Sun_Microsystems b/storage/innobase/COPYING.Sun_Microsystems deleted file mode 100644 index 5a77ef3ab73..00000000000 --- a/storage/innobase/COPYING.Sun_Microsystems +++ /dev/null @@ -1,31 +0,0 @@ -Portions of this software contain modifications contributed by -Sun Microsystems, Inc. These contributions are used with the following -license: - -Copyright (c) 2009, Sun Microsystems, Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - * Neither the name of Sun Microsystems, Inc. nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From c9d8e8209a1e371818c5db03fd5a555d3a9e31d0 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Thu, 9 Sep 2010 13:06:43 +0300 Subject: [PATCH 011/159] Enable UNIV_DEBUG when WITH_DEBUG is defined --- storage/innobase/CMakeLists.txt | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index e993aa0d96a..587e39dcf3c 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -40,12 +40,10 @@ IF(UNIX) ENDIF() ENDIF() -# Enable InnoDB's UNIV_DEBUG if MySQL's WITH_DEBUG[_FULL] is defined -# enable when this bug is resolved: -# Bug#54861 Additional connections not handled properly in mtr --embedded -#IF(WITH_DEBUG) -# ADD_DEFINITIONS("-DUNIV_DEBUG") -#ENDIF() +# Enable InnoDB's UNIV_DEBUG if MySQL's WITH_DEBUG is defined +IF(WITH_DEBUG) + ADD_DEFINITIONS("-DUNIV_DEBUG") +ENDIF() IF(NOT MSVC) # either define HAVE_IB_GCC_ATOMIC_BUILTINS or not From c42d0a143a2ef906f7f905c7b6aaf6a68ae4faba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 9 Sep 2010 13:44:04 +0300 Subject: [PATCH 012/159] Remove unused constant REC_INFO_BITS. This was replaced with REC_OLD_INFO_BITS in MySQL 5.0.3. --- storage/innobase/include/rem0rec.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h index 53402e8d3a9..5a3dd609ea5 100644 --- a/storage/innobase/include/rem0rec.h +++ b/storage/innobase/include/rem0rec.h @@ -806,8 +806,6 @@ rec_print( dict_index_t* index); /*!< in: record descriptor */ #endif /* UNIV_HOTBACKUP */ -#define REC_INFO_BITS 6 /* This is single byte bit-field */ - /* Maximum lengths for the data in a physical record if the offsets are given in one byte (resp. two byte) format. */ #define REC_1BYTE_OFFS_LIMIT 0x7FUL From 987702f29097b2cfd72d8ea4ed576e318de2e593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 9 Sep 2010 13:48:00 +0300 Subject: [PATCH 013/159] ibuf_insert_to_index_page(): Remove bogus code added for delete buffering. In early development of delete buffering, we did allow B-tree pages to become empty as a result of buffered deletes. That caused fundamental problems. The fix was to refuse buffering purge operations unless the page can be guaranteed to be nonempty. Remove an attempt to cope with empty pages when merging inserts. --- storage/innobase/ibuf/ibuf0ibuf.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index a048de0e884..b77390ab038 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -3779,17 +3779,11 @@ ibuf_insert_to_index_page( rec = page_rec_get_next(page_get_infimum_rec(page)); if (page_rec_is_supremum(rec)) { - /* Empty pages can result from buffered delete operations. - The first record from the free list can be used to find the - father node. */ - rec = page_header_get_ptr(page, PAGE_FREE); - if (UNIV_UNLIKELY(rec == NULL)) { - fputs("InnoDB: Trying to insert a record from" - " the insert buffer to an index page\n" - "InnoDB: but the index page is empty!\n", - stderr); - goto dump; - } + fputs("InnoDB: Trying to insert a record from" + " the insert buffer to an index page\n" + "InnoDB: but the index page is empty!\n", + stderr); + goto dump; } if (UNIV_UNLIKELY(rec_get_n_fields(rec, index) From 07ebf63261d9d17a0adc660358cc6b7f8d79f1a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 9 Sep 2010 13:50:06 +0300 Subject: [PATCH 014/159] Invoke make with -j$(nproc) for better parallelism. --- storage/innobase/compile-innodb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/compile-innodb b/storage/innobase/compile-innodb index 23e7f98e50c..988c862465d 100755 --- a/storage/innobase/compile-innodb +++ b/storage/innobase/compile-innodb @@ -22,4 +22,4 @@ MYSQL_ROOT="$(dirname ${0})/../.." cd ${MYSQL_ROOT} cmake -DWITH_INNOBASE_STORAGE_ENGINE:BOOL=ON -make -j4 +make -j$(nproc) From 3578a30fc49949ccca942702ac22692c0509cbd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 9 Sep 2010 14:27:52 +0300 Subject: [PATCH 015/159] Remove ut0auxconf.h. It was needed when InnoDB Plugin was distributed independently of MySQL. Approved by Vasil Dimov. --- storage/innobase/Doxyfile | 2 +- storage/innobase/Makefile.am | 1 - storage/innobase/include/univ.i | 13 ---- storage/innobase/include/ut0auxconf.h | 14 ----- .../ut/ut0auxconf_atomic_pthread_t_gcc.c | 43 ------------- .../ut/ut0auxconf_atomic_pthread_t_solaris.c | 54 ---------------- .../innobase/ut/ut0auxconf_have_gcc_atomics.c | 61 ------------------- .../ut/ut0auxconf_have_solaris_atomics.c | 39 ------------ storage/innobase/ut/ut0auxconf_pause.c | 32 ---------- .../innobase/ut/ut0auxconf_sizeof_pthread_t.c | 35 ----------- 10 files changed, 1 insertion(+), 293 deletions(-) delete mode 100644 storage/innobase/include/ut0auxconf.h delete mode 100644 storage/innobase/ut/ut0auxconf_atomic_pthread_t_gcc.c delete mode 100644 storage/innobase/ut/ut0auxconf_atomic_pthread_t_solaris.c delete mode 100644 storage/innobase/ut/ut0auxconf_have_gcc_atomics.c delete mode 100644 storage/innobase/ut/ut0auxconf_have_solaris_atomics.c delete mode 100644 storage/innobase/ut/ut0auxconf_pause.c delete mode 100644 storage/innobase/ut/ut0auxconf_sizeof_pthread_t.c diff --git a/storage/innobase/Doxyfile b/storage/innobase/Doxyfile index 62aa7dd8abc..7cf5048fa52 100644 --- a/storage/innobase/Doxyfile +++ b/storage/innobase/Doxyfile @@ -565,7 +565,7 @@ RECURSIVE = YES # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. -EXCLUDE = ut0auxconf_* +EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded diff --git a/storage/innobase/Makefile.am b/storage/innobase/Makefile.am index 7a6103d9e79..460abddb11e 100644 --- a/storage/innobase/Makefile.am +++ b/storage/innobase/Makefile.am @@ -207,7 +207,6 @@ noinst_HEADERS= \ include/usr0sess.h \ include/usr0sess.ic \ include/usr0types.h \ - include/ut0auxconf.h \ include/ut0byte.h \ include/ut0byte.ic \ include/ut0dbg.h \ diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index 5a5af76e175..748070efa02 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -78,19 +78,6 @@ the virtual method table (vtable) in GCC 3. */ # define ha_innobase ha_innodb #endif /* MYSQL_DYNAMIC_PLUGIN */ -/* if any of the following macros is defined at this point this means -that the code from the "right" plug.in was executed and we do not -need to include ut0auxconf.h which would either define the same macros -or will be empty */ -#if !defined(HAVE_IB_GCC_ATOMIC_BUILTINS) \ - && !defined(HAVE_IB_ATOMIC_PTHREAD_T_GCC) \ - && !defined(HAVE_IB_SOLARIS_ATOMICS) \ - && !defined(HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS) \ - && !defined(SIZEOF_PTHREAD_T) \ - && !defined(HAVE_IB_PAUSE_INSTRUCTION) -# include "ut0auxconf.h" -#endif - #if (defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)) && !defined(MYSQL_SERVER) && !defined(__WIN__) # undef __WIN__ # define __WIN__ diff --git a/storage/innobase/include/ut0auxconf.h b/storage/innobase/include/ut0auxconf.h deleted file mode 100644 index 16bcc308392..00000000000 --- a/storage/innobase/include/ut0auxconf.h +++ /dev/null @@ -1,14 +0,0 @@ -/* Do not remove this file even though it is empty. -This file is included in univ.i and will cause compilation failure -if not present. -A custom checks have been added in the generated -storage/innobase/Makefile.in that is shipped with the InnoDB Plugin -source archive. These checks eventually define some macros and put -them in this file. -This is a hack that has been developed in order to deploy new compile -time checks without the need to regenerate the ./configure script that is -distributed in the MySQL 5.1 official source archives. -If by any chance Makefile.in and ./configure are regenerated and thus -the hack from Makefile.in wiped away then the "real" checks from plug.in -will take over. -*/ diff --git a/storage/innobase/ut/ut0auxconf_atomic_pthread_t_gcc.c b/storage/innobase/ut/ut0auxconf_atomic_pthread_t_gcc.c deleted file mode 100644 index 30de5aa6f17..00000000000 --- a/storage/innobase/ut/ut0auxconf_atomic_pthread_t_gcc.c +++ /dev/null @@ -1,43 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2009, Innobase Oy. All Rights Reserved. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -/***************************************************************************** -If this program compiles, then pthread_t objects can be used as arguments -to GCC atomic builtin functions. - -Created March 5, 2009 Vasil Dimov -*****************************************************************************/ - -#include -#include - -int -main(int argc, char** argv) -{ - pthread_t x1; - pthread_t x2; - pthread_t x3; - - memset(&x1, 0x0, sizeof(x1)); - memset(&x2, 0x0, sizeof(x2)); - memset(&x3, 0x0, sizeof(x3)); - - __sync_bool_compare_and_swap(&x1, x2, x3); - - return(0); -} diff --git a/storage/innobase/ut/ut0auxconf_atomic_pthread_t_solaris.c b/storage/innobase/ut/ut0auxconf_atomic_pthread_t_solaris.c deleted file mode 100644 index 310603c7503..00000000000 --- a/storage/innobase/ut/ut0auxconf_atomic_pthread_t_solaris.c +++ /dev/null @@ -1,54 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2009, Innobase Oy. All Rights Reserved. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -/***************************************************************************** -If this program compiles and returns 0, then pthread_t objects can be used as -arguments to Solaris libc atomic functions. - -Created April 18, 2009 Vasil Dimov -*****************************************************************************/ - -#include -#include - -int -main(int argc, char** argv) -{ - pthread_t x1; - pthread_t x2; - pthread_t x3; - - memset(&x1, 0x0, sizeof(x1)); - memset(&x2, 0x0, sizeof(x2)); - memset(&x3, 0x0, sizeof(x3)); - - if (sizeof(pthread_t) == 4) { - - atomic_cas_32(&x1, x2, x3); - - } else if (sizeof(pthread_t) == 8) { - - atomic_cas_64(&x1, x2, x3); - - } else { - - return(1); - } - - return(0); -} diff --git a/storage/innobase/ut/ut0auxconf_have_gcc_atomics.c b/storage/innobase/ut/ut0auxconf_have_gcc_atomics.c deleted file mode 100644 index da5c13d7d79..00000000000 --- a/storage/innobase/ut/ut0auxconf_have_gcc_atomics.c +++ /dev/null @@ -1,61 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2009, Innobase Oy. All Rights Reserved. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -/***************************************************************************** -If this program compiles and returns 0, then GCC atomic funcions are available. - -Created September 12, 2009 Vasil Dimov -*****************************************************************************/ - -int -main(int argc, char** argv) -{ - long x; - long y; - long res; - char c; - - x = 10; - y = 123; - res = __sync_bool_compare_and_swap(&x, x, y); - if (!res || x != y) { - return(1); - } - - x = 10; - y = 123; - res = __sync_bool_compare_and_swap(&x, x + 1, y); - if (res || x != 10) { - return(1); - } - - x = 10; - y = 123; - res = __sync_add_and_fetch(&x, y); - if (res != 123 + 10 || x != 123 + 10) { - return(1); - } - - c = 10; - res = __sync_lock_test_and_set(&c, 123); - if (res != 10 || c != 123) { - return(1); - } - - return(0); -} diff --git a/storage/innobase/ut/ut0auxconf_have_solaris_atomics.c b/storage/innobase/ut/ut0auxconf_have_solaris_atomics.c deleted file mode 100644 index 7eb704edd4b..00000000000 --- a/storage/innobase/ut/ut0auxconf_have_solaris_atomics.c +++ /dev/null @@ -1,39 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2009, Innobase Oy. All Rights Reserved. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -/***************************************************************************** -If this program compiles, then Solaris libc atomic funcions are available. - -Created April 18, 2009 Vasil Dimov -*****************************************************************************/ -#include - -int -main(int argc, char** argv) -{ - ulong_t ulong = 0; - uint32_t uint32 = 0; - uint64_t uint64 = 0; - - atomic_cas_ulong(&ulong, 0, 1); - atomic_cas_32(&uint32, 0, 1); - atomic_cas_64(&uint64, 0, 1); - atomic_add_long(&ulong, 0); - - return(0); -} diff --git a/storage/innobase/ut/ut0auxconf_pause.c b/storage/innobase/ut/ut0auxconf_pause.c deleted file mode 100644 index 54d63bdd9bc..00000000000 --- a/storage/innobase/ut/ut0auxconf_pause.c +++ /dev/null @@ -1,32 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2009, Innobase Oy. All Rights Reserved. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -/***************************************************************************** -If this program compiles and can be run and returns 0, then the pause -instruction is available. - -Created Jul 21, 2009 Vasil Dimov -*****************************************************************************/ - -int -main(int argc, char** argv) -{ - __asm__ __volatile__ ("pause"); - - return(0); -} diff --git a/storage/innobase/ut/ut0auxconf_sizeof_pthread_t.c b/storage/innobase/ut/ut0auxconf_sizeof_pthread_t.c deleted file mode 100644 index 96add4526ef..00000000000 --- a/storage/innobase/ut/ut0auxconf_sizeof_pthread_t.c +++ /dev/null @@ -1,35 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2009, Innobase Oy. All Rights Reserved. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA - -*****************************************************************************/ - -/***************************************************************************** -This program should compile and when run, print a single line like: -#define SIZEOF_PTHREAD_T %d - -Created April 18, 2009 Vasil Dimov -*****************************************************************************/ - -#include -#include - -int -main(int argc, char** argv) -{ - printf("#define SIZEOF_PTHREAD_T %d\n", (int) sizeof(pthread_t)); - - return(0); -} From 838b4c6f386558466cbcd1794daa968ebcaaa097 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Fri, 10 Sep 2010 12:32:21 +0300 Subject: [PATCH 016/159] Whitespace fixup on ha_innodb.cc:2567 --- storage/innobase/handler/ha_innodb.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index bbf3c5aa3c8..39c08d5d152 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2564,7 +2564,7 @@ static int innobase_start_trx_and_assign_read_view( /*====================================*/ - handlerton *hton, /*!< in: Innodb handlerton */ + handlerton *hton, /*!< in: Innodb handlerton */ THD* thd) /*!< in: MySQL thread handle of the user for whom the transaction should be committed */ { From f7d5e1d80779d0231d7c67098efae290aceb5681 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Fri, 10 Sep 2010 12:52:14 +0300 Subject: [PATCH 017/159] Whitespace fixup on ha_innodb.cc:9561 --- storage/innobase/handler/ha_innodb.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 39c08d5d152..df6032fbd40 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -9558,7 +9558,7 @@ ha_innobase::innobase_get_autoinc( } /*******************************************************************//** -This function reads the global auto-inc counter. It doesn't use the +This function reads the global auto-inc counter. It doesn't use the AUTOINC lock even if the lock mode is set to TRADITIONAL. @return the autoinc value */ UNIV_INTERN From 4937eec1a21cd53110f0067dc9fb4c8fc1e9d7cc Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Fri, 10 Sep 2010 13:08:06 +0200 Subject: [PATCH 018/159] Bug #56647 Valgrind warnings for memory leak in mysqltest.cc Moved an init_dynamic_string() from before to after potential die() --- client/mysqltest.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index b7b7ad25d23..ec8aa0f0110 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -7309,11 +7309,10 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) (flags & QUERY_REAP_FLAG)); DBUG_ENTER("run_query"); - init_dynamic_string(&ds_warnings, NULL, 0, 256); - if (cn->pending && (flags & QUERY_SEND_FLAG)) die ("Cannot run query on connection between send and reap"); + init_dynamic_string(&ds_warnings, NULL, 0, 256); /* Evaluate query if this is an eval command */ From cf481a46d71e5397d0bbd7f94697ef7fa2ae4f81 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 13 Sep 2010 16:33:25 +0300 Subject: [PATCH 019/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: storage/innobase/include/ut0rnd.ic:70:8: error: variable 'n_bits' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/include/ut0rnd.ic | 3 --- 1 file changed, 3 deletions(-) diff --git a/storage/innobase/include/ut0rnd.ic b/storage/innobase/include/ut0rnd.ic index 625c378489a..dc4c0d62f56 100644 --- a/storage/innobase/include/ut0rnd.ic +++ b/storage/innobase/include/ut0rnd.ic @@ -67,9 +67,6 @@ ut_rnd_gen_ulint(void) /* out: the 'random' number */ { ulint rnd; - ulint n_bits; - - n_bits = 8 * sizeof(ulint); ut_rnd_ulint_counter = UT_RND1 * ut_rnd_ulint_counter + UT_RND2; From 806e6d0387e874ad5a259496dfff7e0bf5ed11a3 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 13 Sep 2010 16:39:40 +0300 Subject: [PATCH 020/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: btr/btr0btr.c:2063:9: error: variable 'level' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/btr/btr0btr.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c index 5e8831b5d5e..b1b59227883 100644 --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c @@ -2060,7 +2060,6 @@ btr_compress( ulint n_recs; ulint max_ins_size; ulint max_ins_size_reorg; - ulint level; ulint comp; page = btr_cur_get_page(cursor); @@ -2072,7 +2071,6 @@ btr_compress( MTR_MEMO_X_LOCK)); ut_ad(mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_X_FIX)); - level = btr_page_get_level(page, mtr); space = dict_index_get_space(index); left_page_no = btr_page_get_prev(page, mtr); From 8d5eb632b395f5f7bbc886b70e22087d62d41b95 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 11:37:21 +0300 Subject: [PATCH 021/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warnings: btr/btr0cur.c: In function 'btr_store_big_rec_extern_fields': btr/btr0cur.c:3368:10: error: variable 'rec_page' set but not used [-Werror=unused-but-set-variable] btr/btr0cur.c: In function 'btr_free_externally_stored_field': btr/btr0cur.c:3542:8: error: variable 'offset' set but not used [-Werror=unused-but-set-variable] btr/btr0cur.c:3539:10: error: variable 'rec_page' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/btr/btr0cur.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c index d2a2e4d2157..a7160d74a32 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -3365,7 +3365,9 @@ btr_store_big_rec_extern_fields( page_t* page; ulint space_id; page_t* prev_page; +#ifdef UNIV_SYNC_DEBUG page_t* rec_page; +#endif /* UNIV_SYNC_DEBUG */ ulint prev_page_no; ulint hint_page_no; ulint i; @@ -3460,9 +3462,12 @@ btr_store_big_rec_extern_fields( extern_len -= store_len; - rec_page = buf_page_get(space_id, - buf_frame_get_page_no(data), - RW_X_LATCH, &mtr); +#ifdef UNIV_SYNC_DEBUG + rec_page = +#endif /* UNIV_SYNC_DEBUG */ + buf_page_get(space_id, + buf_frame_get_page_no(data), + RW_X_LATCH, &mtr); #ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(rec_page, SYNC_NO_ORDER_CHECK); #endif /* UNIV_SYNC_DEBUG */ @@ -3536,10 +3541,11 @@ btr_free_externally_stored_field( X-latch to the index tree */ { page_t* page; +#ifdef UNIV_SYNC_DEBUG page_t* rec_page; +#endif /* UNIV_SYNC_DEBUG */ ulint space_id; ulint page_no; - ulint offset; ulint extern_len; ulint next_page_no; ulint part_len; @@ -3556,9 +3562,12 @@ btr_free_externally_stored_field( for (;;) { mtr_start(&mtr); - rec_page = buf_page_get(buf_frame_get_space_id(data), - buf_frame_get_page_no(data), - RW_X_LATCH, &mtr); +#ifdef UNIV_SYNC_DEBUG + rec_page = +#endif /* UNIV_SYNC_DEBUG */ + buf_page_get(buf_frame_get_space_id(data), + buf_frame_get_page_no(data), + RW_X_LATCH, &mtr); #ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(rec_page, SYNC_NO_ORDER_CHECK); #endif /* UNIV_SYNC_DEBUG */ @@ -3568,8 +3577,6 @@ btr_free_externally_stored_field( page_no = mach_read_from_4(data + local_len + BTR_EXTERN_PAGE_NO); - offset = mach_read_from_4(data + local_len - + BTR_EXTERN_OFFSET); extern_len = mach_read_from_4(data + local_len + BTR_EXTERN_LEN + 4); From 38eba5da0d03bbb5062e04b7e23b73de2e58eacd Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 11:38:59 +0300 Subject: [PATCH 022/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warnings: btr/btr0pcur.c: In function 'btr_pcur_move_backward_from_page': btr/btr0pcur.c:432:8: error: variable 'space' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/btr/btr0pcur.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innobase/btr/btr0pcur.c b/storage/innobase/btr/btr0pcur.c index 65b3c90c809..f73e82fb597 100644 --- a/storage/innobase/btr/btr0pcur.c +++ b/storage/innobase/btr/btr0pcur.c @@ -429,7 +429,6 @@ btr_pcur_move_backward_from_page( mtr_t* mtr) /* in: mtr */ { ulint prev_page_no; - ulint space; page_t* page; page_t* prev_page; ulint latch_mode; @@ -465,7 +464,6 @@ btr_pcur_move_backward_from_page( page = btr_pcur_get_page(cursor); prev_page_no = btr_page_get_prev(page, mtr); - space = buf_frame_get_space_id(page); if (btr_pcur_is_before_first_on_page(cursor, mtr) && (prev_page_no != FIL_NULL)) { From 91918245ece2fb42f203e43637f0a7a72fa6f9c8 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 11:39:34 +0300 Subject: [PATCH 023/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warnings: btr/btr0sea.c: In function 'btr_search_update_hash_on_delete': btr/btr0sea.c:1404:9: error: variable 'found' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/btr/btr0sea.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c index 84ad0e27110..97c9f89db72 100644 --- a/storage/innobase/btr/btr0sea.c +++ b/storage/innobase/btr/btr0sea.c @@ -1401,7 +1401,6 @@ btr_search_update_hash_on_delete( rec_t* rec; ulint fold; dulint index_id; - ibool found; ulint offsets_[REC_OFFS_NORMAL_SIZE]; mem_heap_t* heap = NULL; *offsets_ = (sizeof offsets_) / sizeof *offsets_; @@ -1433,7 +1432,7 @@ btr_search_update_hash_on_delete( } rw_lock_x_lock(&btr_search_latch); - found = ha_search_and_delete_if_found(table, fold, rec); + ha_search_and_delete_if_found(table, fold, rec); rw_lock_x_unlock(&btr_search_latch); } From 87d4bae87e71bd745ba1caaf8a4003f55459cff4 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 12:00:58 +0300 Subject: [PATCH 024/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: buf/buf0flu.c: In function 'buf_flush_batch': buf/buf0flu.c:844:9: error: variable 'old_page_count' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/buf/buf0flu.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c index 7533205d695..24fa306c127 100644 --- a/storage/innobase/buf/buf0flu.c +++ b/storage/innobase/buf/buf0flu.c @@ -841,7 +841,6 @@ buf_flush_batch( { buf_block_t* block; ulint page_count = 0; - ulint old_page_count; ulint space; ulint offset; ibool found; @@ -913,15 +912,9 @@ buf_flush_batch( mutex_exit(&block->mutex); mutex_exit(&(buf_pool->mutex)); - old_page_count = page_count; - /* Try to flush also all the neighbors */ page_count += buf_flush_try_neighbors( space, offset, flush_type); - /* fprintf(stderr, - "Flush type %lu, page no %lu, neighb %lu\n", - flush_type, offset, - page_count - old_page_count); */ mutex_enter(&(buf_pool->mutex)); From f0634f15ae5db95adeff318e8eddda02d38c0ee2 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 12:06:47 +0300 Subject: [PATCH 025/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: eval/eval0eval.c: In function 'eval_notfound': eval/eval0eval.c:371:14: error: variable 'arg2' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/eval/eval0eval.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innobase/eval/eval0eval.c b/storage/innobase/eval/eval0eval.c index cbc47ec508f..fb4e72a511f 100644 --- a/storage/innobase/eval/eval0eval.c +++ b/storage/innobase/eval/eval0eval.c @@ -368,13 +368,11 @@ eval_notfound( func_node_t* func_node) /* in: function node */ { que_node_t* arg1; - que_node_t* arg2; sym_node_t* cursor; sel_node_t* sel_node; ibool ibool_val; arg1 = func_node->args; - arg2 = que_node_get_next(arg1); ut_ad(func_node->func == PARS_NOTFOUND_TOKEN); From e63ef8a33f6bdc36314be42307aab715bd8dfa14 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 12:11:00 +0300 Subject: [PATCH 026/159] Remove redundant variable --- storage/innobase/eval/eval0eval.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/storage/innobase/eval/eval0eval.c b/storage/innobase/eval/eval0eval.c index fb4e72a511f..52e9923fc05 100644 --- a/storage/innobase/eval/eval0eval.c +++ b/storage/innobase/eval/eval0eval.c @@ -367,16 +367,13 @@ eval_notfound( /*==========*/ func_node_t* func_node) /* in: function node */ { - que_node_t* arg1; sym_node_t* cursor; sel_node_t* sel_node; ibool ibool_val; - arg1 = func_node->args; - ut_ad(func_node->func == PARS_NOTFOUND_TOKEN); - cursor = arg1; + cursor = func_node->args; ut_ad(que_node_get_type(cursor) == QUE_NODE_SYMBOL); From 8e942b3265db5289f60c118ea66c20f2f6fe16bd Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 12:37:03 +0300 Subject: [PATCH 027/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: lock/lock0lock.c: In function 'lock_print_info_all_transactions': lock/lock0lock.c:4299:10: error: variable 'page' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/lock/lock0lock.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index 04240960b3a..57df99fb401 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -4296,7 +4296,6 @@ lock_print_info_all_transactions( lock_t* lock; ulint space; ulint page_no; - page_t* page; ibool load_page_first = TRUE; ulint nth_trx = 0; ulint nth_lock = 0; @@ -4410,8 +4409,7 @@ loop: mtr_start(&mtr); - page = buf_page_get_with_no_latch( - space, page_no, &mtr); + buf_page_get_with_no_latch(space, page_no, &mtr); mtr_commit(&mtr); From 27c84cf762dc201b82c598af15cbac6fdf61d323 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 12:41:00 +0300 Subject: [PATCH 028/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: log/log0recv.c: In function 'recv_recovery_from_checkpoint_start': log/log0recv.c:2509:10: error: variable 'archived_lsn' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/log/log0recv.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c index e6524eeefbf..f896b11a519 100644 --- a/storage/innobase/log/log0recv.c +++ b/storage/innobase/log/log0recv.c @@ -2506,7 +2506,9 @@ recv_recovery_from_checkpoint_start( dulint old_scanned_lsn; dulint group_scanned_lsn; dulint contiguous_lsn; +#ifdef UNIV_LOG_ARCHIVE dulint archived_lsn; +#endif /* UNIV_LOG_ARCHIVE */ ulint capacity; byte* buf; byte log_hdr_buf[LOG_FILE_HDR_SIZE]; @@ -2552,7 +2554,9 @@ recv_recovery_from_checkpoint_start( checkpoint_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_LSN); checkpoint_no = mach_read_from_8(buf + LOG_CHECKPOINT_NO); +#ifdef UNIV_LOG_ARCHIVE archived_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN); +#endif /* UNIV_LOG_ARCHIVE */ /* Read the first log file header to print a note if this is a recovery from a restored InnoDB Hot Backup */ From 1813340bd6ce6a8813f5b4ce7fae609c55799946 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 12:46:23 +0300 Subject: [PATCH 029/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: log/log0recv.c: In function 'recv_synchronize_groups': log/log0recv.c:403:10: error: variable 'limit_lsn' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/log/log0recv.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c index f896b11a519..6e1ca58cb15 100644 --- a/storage/innobase/log/log0recv.c +++ b/storage/innobase/log/log0recv.c @@ -400,10 +400,8 @@ recv_synchronize_groups( dulint start_lsn; dulint end_lsn; dulint recovered_lsn; - dulint limit_lsn; recovered_lsn = recv_sys->recovered_lsn; - limit_lsn = recv_sys->limit_lsn; /* Read the last recovered log block to the recovery system buffer: the block is always incomplete */ From 5e4febf4f3fc5cc55d3375c4c6abbdcf40b3da1a Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 13:01:25 +0300 Subject: [PATCH 030/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warnings: os/os0file.c: In function 'os_file_create': os/os0file.c:1318:14: error: variable 'purpose_str' set but not used [-Werror=unused-but-set-variable] os/os0file.c:1317:14: error: variable 'type_str' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/os/os0file.c | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index 3396d1adf2f..a995aee5fab 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -1314,8 +1314,6 @@ try_again: int create_flag; ibool retry; const char* mode_str = NULL; - const char* type_str = NULL; - const char* purpose_str = NULL; try_again: ut_a(name); @@ -1335,26 +1333,9 @@ try_again: ut_error; } - if (type == OS_LOG_FILE) { - type_str = "LOG"; - } else if (type == OS_DATA_FILE) { - type_str = "DATA"; - } else { - ut_error; - } + ut_a(type == OS_LOG_FILE || type == OS_DATA_FILE); + ut_a(purpose == OS_FILE_AIO || purpose == OS_FILE_NORMAL); - if (purpose == OS_FILE_AIO) { - purpose_str = "AIO"; - } else if (purpose == OS_FILE_NORMAL) { - purpose_str = "NORMAL"; - } else { - ut_error; - } - -#if 0 - fprintf(stderr, "Opening file %s, mode %s, type %s, purpose %s\n", - name, mode_str, type_str, purpose_str); -#endif #ifdef O_SYNC /* We let O_SYNC only affect log files; note that we map O_DSYNC to O_SYNC because the datasync options seemed to corrupt files in 2001 From d4bd5e00898c67e293954a776636f2e921d3188f Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 13:38:21 +0300 Subject: [PATCH 031/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: que/que0que.c: In function 'que_run_threads_low': que/que0que.c:1295:9: error: variable 'cumul_resource' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/que/que0que.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/storage/innobase/que/que0que.c b/storage/innobase/que/que0que.c index bf83f28f04e..9b5c25d4680 100644 --- a/storage/innobase/que/que0que.c +++ b/storage/innobase/que/que0que.c @@ -1292,18 +1292,13 @@ que_run_threads_low( que_thr_t* thr) /* in: query thread */ { que_thr_t* next_thr; - ulint cumul_resource; ulint loop_count; ut_ad(thr->state == QUE_THR_RUNNING); ut_a(thr_get_trx(thr)->error_state == DB_SUCCESS); ut_ad(!mutex_own(&kernel_mutex)); - /* cumul_resource counts how much resources the OS thread (NOT the - query thread) has spent in this function */ - loop_count = QUE_MAX_LOOPS_WITHOUT_CHECK; - cumul_resource = 0; loop: /* Check that there is enough space in the log to accommodate possible log entries by this query step; if the operation can touch From a82e39e7286cc5b730df5191200fc22b7a595ac4 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 13:39:52 +0300 Subject: [PATCH 032/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: que/que0que.c: In function 'que_thr_dec_refer_count': que/que0que.c:805:11: error: variable 'sess' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/que/que0que.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innobase/que/que0que.c b/storage/innobase/que/que0que.c index 9b5c25d4680..1a76823ca4d 100644 --- a/storage/innobase/que/que0que.c +++ b/storage/innobase/que/que0que.c @@ -802,13 +802,11 @@ que_thr_dec_refer_count( { que_fork_t* fork; trx_t* trx; - sess_t* sess; ulint fork_type; ibool stopped; fork = thr->common.parent; trx = thr_get_trx(thr); - sess = trx->sess; mutex_enter(&kernel_mutex); From 1bdcd70fad735a2a602e70fcac282cad84b92ab6 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 13:56:29 +0300 Subject: [PATCH 033/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: row/row0purge.c: In function 'row_purge_step': row/row0purge.c:660:9: error: variable 'err' set but not used [-Werror=unused-but-set-variable] (row_purge() always returns DB_SUCCESS) --- storage/innobase/row/row0purge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/row/row0purge.c b/storage/innobase/row/row0purge.c index 1fef47da13f..deec3b0a454 100644 --- a/storage/innobase/row/row0purge.c +++ b/storage/innobase/row/row0purge.c @@ -667,7 +667,7 @@ row_purge_step( err = row_purge(node, thr); - ut_ad(err == DB_SUCCESS); + ut_a(err == DB_SUCCESS); return(thr); } From 67c388410b73fbac0bf6d71a304521a7895ce201 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 14:09:36 +0300 Subject: [PATCH 034/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: row/row0umod.c: In function 'row_undo_mod_clust_low': row/row0umod.c:92:9: error: variable 'success' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/row/row0umod.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/storage/innobase/row/row0umod.c b/storage/innobase/row/row0umod.c index 68139da116e..a3333fcc536 100644 --- a/storage/innobase/row/row0umod.c +++ b/storage/innobase/row/row0umod.c @@ -89,12 +89,17 @@ row_undo_mod_clust_low( btr_pcur_t* pcur; btr_cur_t* btr_cur; ulint err; +#ifdef UNIV_DEBUG ibool success; +#endif /* UNIV_DEBUG */ pcur = &(node->pcur); btr_cur = btr_pcur_get_btr_cur(pcur); - success = btr_pcur_restore_position(mode, pcur, mtr); +#ifdef UNIV_DEBUG + success = +#endif /* UNIV_DEBUG */ + btr_pcur_restore_position(mode, pcur, mtr); ut_ad(success); From c283946dd6e3de1368538350d57f4104e6cc0862 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 14:46:13 +0300 Subject: [PATCH 035/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: row/row0upd.c: In function 'row_upd_in_place_in_select': row/row0upd.c:2040:9: error: variable 'err' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/row/row0upd.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c index c91cc449b96..034b7010410 100644 --- a/storage/innobase/row/row0upd.c +++ b/storage/innobase/row/row0upd.c @@ -2037,7 +2037,9 @@ row_upd_in_place_in_select( upd_node_t* node; btr_pcur_t* pcur; btr_cur_t* btr_cur; +#ifdef UNIV_DEBUG ulint err; +#endif /* UNIV_DEBUG */ mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; *offsets_ = (sizeof offsets_) / sizeof *offsets_; @@ -2074,8 +2076,11 @@ row_upd_in_place_in_select( ut_ad(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE); ut_ad(node->select_will_do_update); - err = btr_cur_update_in_place(BTR_NO_LOCKING_FLAG, btr_cur, - node->update, node->cmpl_info, - thr, mtr); +#ifdef UNIV_DEBUG + err = +#endif /* UNIV_DEBUG */ + btr_cur_update_in_place(BTR_NO_LOCKING_FLAG, btr_cur, + node->update, node->cmpl_info, + thr, mtr); ut_ad(err == DB_SUCCESS); } From 00c6e219c6aa1400a0bd6ddf55fe1c56ff62fedc Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 14:50:13 +0300 Subject: [PATCH 036/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: row/row0vers.c: In function 'row_vers_impl_x_locked_off_kernel': row/row0vers.c:62:9: error: variable 'err' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/row/row0vers.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/storage/innobase/row/row0vers.c b/storage/innobase/row/row0vers.c index 03d9a2f1203..f4adfa855df 100644 --- a/storage/innobase/row/row0vers.c +++ b/storage/innobase/row/row0vers.c @@ -59,7 +59,9 @@ row_vers_impl_x_locked_off_kernel( trx_t* trx; ulint vers_del; ulint rec_del; +#ifdef UNIV_DEBUG ulint err; +#endif /* UNIV_DEBUG */ mtr_t mtr; ulint comp; @@ -152,9 +154,12 @@ row_vers_impl_x_locked_off_kernel( heap2 = heap; heap = mem_heap_create(1024); - err = trx_undo_prev_version_build(clust_rec, &mtr, version, - clust_index, clust_offsets, - heap, &prev_version); +#ifdef UNIV_DEBUG + err = +#endif /* UNIV_DEBUG */ + trx_undo_prev_version_build(clust_rec, &mtr, version, + clust_index, clust_offsets, + heap, &prev_version); mem_heap_free(heap2); /* free version and clust_offsets */ if (prev_version) { From 3d4dcf266f0c1c7102754ad9c5fa97db3be3b2a3 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 15:04:03 +0300 Subject: [PATCH 037/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: trx/trx0purge.c: In function 'trx_purge_add_update_undo_to_history': trx/trx0purge.c:254:16: error: variable 'page_header' set but not used [-Werror=unused-but-set-variable] trx/trx0purge.c:252:15: error: variable 'seg_header' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/trx/trx0purge.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c index f0f300d918e..caeb98484af 100644 --- a/storage/innobase/trx/trx0purge.c +++ b/storage/innobase/trx/trx0purge.c @@ -249,9 +249,10 @@ trx_purge_add_update_undo_to_history( trx_undo_t* undo; trx_rseg_t* rseg; trx_rsegf_t* rseg_header; +#ifdef UNIV_DEBUG trx_usegf_t* seg_header; +#endif /* UNIV_DEBUG */ trx_ulogf_t* undo_header; - trx_upagef_t* page_header; ulint hist_size; undo = trx->update_undo; @@ -265,8 +266,9 @@ trx_purge_add_update_undo_to_history( rseg_header = trx_rsegf_get(rseg->space, rseg->page_no, mtr); undo_header = undo_page + undo->hdr_offset; +#ifdef UNIV_DEBUG seg_header = undo_page + TRX_UNDO_SEG_HDR; - page_header = undo_page + TRX_UNDO_PAGE_HDR; +#endif /* UNIV_DEBUG */ if (undo->state != TRX_UNDO_CACHED) { /* The undo log segment will not be reused */ From 64ae6d4a7e8f507d48c1b4fc0985d1d2733d6ce1 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 14 Sep 2010 14:04:37 +0200 Subject: [PATCH 038/159] Bug #55426 mysqltest crashes when trying to unlock not acquired mutex Bug #55546 mysqltest fails to create a new thread on HPUX Missing call to pthread_join(), in embedded mode This independently solves both problems, see 55426 for details. Addendum: cannot test against a pthread_t, adds boolean flag instead --- client/mysqltest.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index ec8aa0f0110..31854737cbc 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -242,7 +242,9 @@ struct st_connection int cur_query_len; pthread_mutex_t mutex; pthread_cond_t cond; + pthread_t tid; int query_done; + my_bool has_thread; #endif /*EMBEDDED_LIBRARY*/ }; @@ -733,8 +735,6 @@ pthread_handler_t send_one_query(void *arg) static int do_send_query(struct st_connection *cn, const char *q, int q_len, int flags) { - pthread_t tid; - if (flags & QUERY_REAP_FLAG) return mysql_send_query(&cn->mysql, q, q_len); @@ -745,9 +745,10 @@ static int do_send_query(struct st_connection *cn, const char *q, int q_len, cn->cur_query= q; cn->cur_query_len= q_len; cn->query_done= 0; - if (pthread_create(&tid, &cn_thd_attrib, send_one_query, (void*)cn)) + if (pthread_create(&cn->tid, &cn_thd_attrib, send_one_query, (void*)cn)) die("Cannot start new thread for query"); + cn->has_thread= TRUE; return 0; } @@ -760,6 +761,11 @@ static void wait_query_thread_end(struct st_connection *con) pthread_cond_wait(&con->cond, &con->mutex); pthread_mutex_unlock(&con->mutex); } + if (con->has_thread) + { + pthread_join(con->tid, NULL); + con->has_thread= FALSE; + } } #else /*EMBEDDED_LIBRARY*/ @@ -5187,6 +5193,7 @@ void do_connect(struct st_command *command) #ifdef EMBEDDED_LIBRARY con_slot->query_done= 1; + con_slot->has_thread= FALSE; #endif if (!mysql_init(&con_slot->mysql)) die("Failed on mysql_init()"); From 00686b4e11227b2a2559f4406a2986e79023030a Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 15:17:48 +0300 Subject: [PATCH 039/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: trx/trx0purge.c: In function 'trx_purge_rseg_get_next_history_log': trx/trx0purge.c:599:15: error: variable 'seg_hdr' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/trx/trx0purge.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c index caeb98484af..3e77efccde7 100644 --- a/storage/innobase/trx/trx0purge.c +++ b/storage/innobase/trx/trx0purge.c @@ -596,7 +596,6 @@ trx_purge_rseg_get_next_history_log( { page_t* undo_page; trx_ulogf_t* log_hdr; - trx_usegf_t* seg_hdr; fil_addr_t prev_log_addr; dulint trx_no; ibool del_marks; @@ -617,7 +616,6 @@ trx_purge_rseg_get_next_history_log( undo_page = trx_undo_page_get_s_latched(rseg->space, rseg->last_page_no, &mtr); log_hdr = undo_page + rseg->last_offset; - seg_hdr = undo_page + TRX_UNDO_SEG_HDR; /* Increase the purge page count by one for every handled log */ From 94ce8492b6eed4cc3468910eb3d1731b413e6ad0 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 15:19:04 +0300 Subject: [PATCH 040/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: trx/trx0purge.c: In function 'trx_purge_rec_release': trx/trx0purge.c:1007:18: error: variable 'arr' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/trx/trx0purge.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c index 3e77efccde7..9e09efc82b2 100644 --- a/storage/innobase/trx/trx0purge.c +++ b/storage/innobase/trx/trx0purge.c @@ -1004,12 +1004,8 @@ trx_purge_rec_release( /*==================*/ trx_undo_inf_t* cell) /* in: storage cell */ { - trx_undo_arr_t* arr; - mutex_enter(&(purge_sys->mutex)); - arr = purge_sys->arr; - trx_purge_arr_remove_info(cell); mutex_exit(&(purge_sys->mutex)); From d1b9cca52ced3ff0598b46cda39935f99d7e2138 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 15:21:32 +0300 Subject: [PATCH 041/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warnings: trx/trx0roll.c: In function 'trx_undo_arr_remove_info': trx/trx0roll.c:717:9: error: variable 'n' set but not used [-Werror=unused-but-set-variable] trx/trx0roll.c:716:9: error: variable 'n_used' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/trx/trx0roll.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/storage/innobase/trx/trx0roll.c b/storage/innobase/trx/trx0roll.c index 8934fe87c7e..285e30796a5 100644 --- a/storage/innobase/trx/trx0roll.c +++ b/storage/innobase/trx/trx0roll.c @@ -713,13 +713,8 @@ trx_undo_arr_remove_info( dulint undo_no)/* in: undo number */ { trx_undo_inf_t* cell; - ulint n_used; - ulint n; ulint i; - n_used = arr->n_used; - n = 0; - for (i = 0;; i++) { cell = trx_undo_arr_get_nth_info(arr, i); From 9d74ab6033bed490a2701dbb6ca97ed7cd73879f Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 15:28:48 +0300 Subject: [PATCH 042/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: trx/trx0sys.c: In function 'trx_sys_create_doublewrite_buf': trx/trx0sys.c:168:10: error: variable 'new_page' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/trx/trx0sys.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c index f732aca93f5..137771b71ed 100644 --- a/storage/innobase/trx/trx0sys.c +++ b/storage/innobase/trx/trx0sys.c @@ -165,7 +165,9 @@ trx_sys_create_doublewrite_buf(void) { page_t* page; page_t* page2; +#ifdef UNIV_SYNC_DEBUG page_t* new_page; +#endif /* UNIV_SYNC_DEBUG */ byte* doublewrite; byte* fseg_header; ulint page_no; @@ -271,8 +273,11 @@ start_again: the page position in the tablespace, then the page has not been written to in doublewrite. */ - new_page = buf_page_get(TRX_SYS_SPACE, page_no, - RW_X_LATCH, &mtr); +#ifdef UNIV_SYNC_DEBUG + new_page = +#endif /* UNIV_SYNC_DEBUG */ + buf_page_get(TRX_SYS_SPACE, page_no, + RW_X_LATCH, &mtr); #ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(new_page, SYNC_NO_ORDER_CHECK); #endif /* UNIV_SYNC_DEBUG */ From e3de88c3f81b5b505828147e0445ed68c0101381 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 15:30:26 +0300 Subject: [PATCH 043/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: trx/trx0trx.c: In function 'trx_prepare_off_kernel': trx/trx0trx.c:1830:11: error: variable 'update_hdr_page' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/trx/trx0trx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c index 545226a5994..21f75e0818f 100644 --- a/storage/innobase/trx/trx0trx.c +++ b/storage/innobase/trx/trx0trx.c @@ -1827,7 +1827,6 @@ trx_prepare_off_kernel( /*===================*/ trx_t* trx) /* in: transaction */ { - page_t* update_hdr_page; trx_rseg_t* rseg; ibool must_flush_log = FALSE; dulint lsn; @@ -1863,7 +1862,7 @@ trx_prepare_off_kernel( } if (trx->update_undo) { - update_hdr_page = trx_undo_set_state_at_prepare( + trx_undo_set_state_at_prepare( trx, trx->update_undo, &mtr); } From 33c7ab2b98617552c6d3d4095a4080169fd522fa Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 17:53:49 +0300 Subject: [PATCH 044/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: trx/trx0undo.c: In function 'trx_undo_truncate_end': trx/trx0undo.c:1015:14: error: variable 'rseg' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/trx/trx0undo.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c index deb6c85e6e3..e47abe2c08a 100644 --- a/storage/innobase/trx/trx0undo.c +++ b/storage/innobase/trx/trx0undo.c @@ -1012,14 +1012,11 @@ trx_undo_truncate_end( ulint last_page_no; trx_undo_rec_t* rec; trx_undo_rec_t* trunc_here; - trx_rseg_t* rseg; mtr_t mtr; ut_ad(mutex_own(&(trx->undo_mutex))); ut_ad(mutex_own(&(trx->rseg->mutex))); - rseg = trx->rseg; - for (;;) { mtr_start(&mtr); From bed81fec77ded8366f20fbfea86e494bd387dfe8 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 17:55:44 +0300 Subject: [PATCH 045/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: trx/trx0undo.c: In function 'trx_undo_set_state_at_prepare': trx/trx0undo.c:1798:16: error: variable 'page_hdr' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/trx/trx0undo.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c index e47abe2c08a..4547ee9ea64 100644 --- a/storage/innobase/trx/trx0undo.c +++ b/storage/innobase/trx/trx0undo.c @@ -1795,7 +1795,6 @@ trx_undo_set_state_at_prepare( mtr_t* mtr) /* in: mtr */ { trx_usegf_t* seg_hdr; - trx_upagef_t* page_hdr; trx_ulogf_t* undo_header; page_t* undo_page; ulint offset; @@ -1812,7 +1811,6 @@ trx_undo_set_state_at_prepare( undo_page = trx_undo_page_get(undo->space, undo->hdr_page_no, mtr); seg_hdr = undo_page + TRX_UNDO_SEG_HDR; - page_hdr = undo_page + TRX_UNDO_PAGE_HDR; /*------------------------------*/ undo->state = TRX_UNDO_PREPARED; From de12861681c40eb69dbffe53d9f9aa43364a6bb0 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 18:22:30 +0300 Subject: [PATCH 046/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: handler/ha_innodb.cc: In function 'void innobase_drop_database(handlerton*, char*)': handler/ha_innodb.cc:5969:6: error: variable 'error' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/handler/ha_innodb.cc | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 4688b5fd16c..4027a908fb3 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -5966,7 +5966,6 @@ innobase_drop_database( trx_t* parent_trx; trx_t* trx; char* ptr; - int error; char* namebuf; THD* thd = current_thd; @@ -6004,7 +6003,7 @@ innobase_drop_database( trx->check_foreigns = FALSE; } - error = row_drop_database_for_mysql(namebuf, trx); + row_drop_database_for_mysql(namebuf, trx); my_free(namebuf, MYF(0)); /* Flush the log to reduce probability that the .frm files and @@ -6020,13 +6019,7 @@ innobase_drop_database( innobase_commit_low(trx); trx_free_for_mysql(trx); -#ifdef NO_LONGER_INTERESTED_IN_DROP_DB_ERROR - error = convert_error_code_to_mysql(error, NULL); - - return(error); -#else return; -#endif } /************************************************************************* From 05a0ad8dcb3a0b6e6fecef8b2846f3f30c2cb4f8 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 18:25:41 +0300 Subject: [PATCH 047/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: handler/ha_innodb.cc: In function 'bool innodb_show_status(handlerton*, THD*, bool (*)(THD*, const char*, uint, const char*, uint, const char*, uint))': handler/ha_innodb.cc:7539:7: error: variable 'result' set but not used [-Werror=unused-but-set-variable] --- storage/innobase/handler/ha_innodb.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 4027a908fb3..cfd4b229ce0 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -7536,12 +7536,9 @@ innodb_show_status( mutex_exit_noninline(&srv_monitor_file_mutex); - bool result = FALSE; + stat_print(thd, innobase_hton_name, (uint) strlen(innobase_hton_name), + STRING_WITH_LEN(""), str, flen); - if (stat_print(thd, innobase_hton_name, (uint) strlen(innobase_hton_name), - STRING_WITH_LEN(""), str, flen)) { - result= TRUE; - } my_free(str, MYF(0)); DBUG_RETURN(FALSE); From 33d9825d0ca15951b30290979e52df09866a853c Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 20:58:02 +0300 Subject: [PATCH 048/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: ./include/ut0rnd.ic: In function 'ut_rnd_gen_ulint': ./include/ut0rnd.ic:88:8: error: variable 'n_bits' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/include/ut0rnd.ic | 3 --- 1 file changed, 3 deletions(-) diff --git a/storage/innodb_plugin/include/ut0rnd.ic b/storage/innodb_plugin/include/ut0rnd.ic index c3dbd86923c..a33813037ea 100644 --- a/storage/innodb_plugin/include/ut0rnd.ic +++ b/storage/innodb_plugin/include/ut0rnd.ic @@ -85,9 +85,6 @@ ut_rnd_gen_ulint(void) /*==================*/ { ulint rnd; - ulint n_bits; - - n_bits = 8 * sizeof(ulint); ut_rnd_ulint_counter = UT_RND1 * ut_rnd_ulint_counter + UT_RND2; From 424ec78a464eac0bf4977d687d16231535504434 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 21:12:19 +0300 Subject: [PATCH 049/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: btr/btr0btr.c: In function 'btr_page_split_and_insert': btr/btr0btr.c:1898:11: error: variable 'insert_page' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/btr/btr0btr.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/storage/innodb_plugin/btr/btr0btr.c b/storage/innodb_plugin/btr/btr0btr.c index 02677e0a71c..11b6782d5d6 100644 --- a/storage/innodb_plugin/btr/btr0btr.c +++ b/storage/innodb_plugin/btr/btr0btr.c @@ -1895,7 +1895,6 @@ btr_page_split_and_insert( buf_block_t* left_block; buf_block_t* right_block; buf_block_t* insert_block; - page_t* insert_page; page_cur_t* page_cursor; rec_t* first_rec; byte* buf = 0; /* remove warning */ @@ -2153,8 +2152,6 @@ insert_empty: insert_block = right_block; } - insert_page = buf_block_get_frame(insert_block); - /* 7. Reposition the cursor for insert and try insertion */ page_cursor = btr_cur_get_page_cur(cursor); @@ -2166,8 +2163,12 @@ insert_empty: #ifdef UNIV_ZIP_DEBUG { + page_t* insert_page + = buf_block_get_frame(insert_block); + page_zip_des_t* insert_page_zip = buf_block_get_page_zip(insert_block); + ut_a(!insert_page_zip || page_zip_validate(insert_page_zip, insert_page)); } From 67a1603c932460e3d965c36aec4f55e9c5b36c14 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 21:14:42 +0300 Subject: [PATCH 050/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: btr/btr0btr.c: In function 'btr_compress': btr/btr0btr.c:2564:9: error: variable 'level' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/btr/btr0btr.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innodb_plugin/btr/btr0btr.c b/storage/innodb_plugin/btr/btr0btr.c index 11b6782d5d6..29cd470e650 100644 --- a/storage/innodb_plugin/btr/btr0btr.c +++ b/storage/innodb_plugin/btr/btr0btr.c @@ -2561,7 +2561,6 @@ btr_compress( ulint n_recs; ulint max_ins_size; ulint max_ins_size_reorg; - ulint level; block = btr_cur_get_block(cursor); page = btr_cur_get_page(cursor); @@ -2571,7 +2570,6 @@ btr_compress( ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index), MTR_MEMO_X_LOCK)); ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); - level = btr_page_get_level(page, mtr); space = dict_index_get_space(index); zip_size = dict_table_zip_size(index->table); From 57e860c6a163eef759a1e3a92639da7a283a5392 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 21:30:37 +0300 Subject: [PATCH 051/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: btr/btr0cur.c: In function 'btr_cur_optimistic_update': btr/btr0cur.c:1839:10: error: variable 'orig_rec' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/btr/btr0cur.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c index 7fa7d42320a..7f4b5ffaf64 100644 --- a/storage/innodb_plugin/btr/btr0cur.c +++ b/storage/innodb_plugin/btr/btr0cur.c @@ -1836,7 +1836,6 @@ btr_cur_optimistic_update( page_t* page; page_zip_des_t* page_zip; rec_t* rec; - rec_t* orig_rec; ulint max_size; ulint new_rec_size; ulint old_rec_size; @@ -1850,7 +1849,7 @@ btr_cur_optimistic_update( block = btr_cur_get_block(cursor); page = buf_block_get_frame(block); - orig_rec = rec = btr_cur_get_rec(cursor); + rec = btr_cur_get_rec(cursor); index = cursor->index; ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table)); ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); From 07cded618786098a54106c896f0c6e3f7f217659 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 21:33:02 +0300 Subject: [PATCH 052/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: btr/btr0cur.c: In function 'btr_free_externally_stored_field': btr/btr0cur.c:4281:16: error: variable 'rec_block' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/btr/btr0cur.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c index 7f4b5ffaf64..884b7fed8dd 100644 --- a/storage/innodb_plugin/btr/btr0cur.c +++ b/storage/innodb_plugin/btr/btr0cur.c @@ -4278,12 +4278,17 @@ btr_free_externally_stored_field( } for (;;) { +#ifdef UNIV_SYNC_DEBUG buf_block_t* rec_block; +#endif /* UNIV_SYNC_DEBUG */ buf_block_t* ext_block; mtr_start(&mtr); - rec_block = buf_page_get(page_get_space_id( +#ifdef UNIV_SYNC_DEBUG + rec_block = +#endif /* UNIV_SYNC_DEBUG */ + buf_page_get(page_get_space_id( page_align(field_ref)), rec_zip_size, page_get_page_no( From 8e3c62cc577d9acc5ef9caf52fa4d4f49c72c1a6 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 21:35:37 +0300 Subject: [PATCH 053/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: btr/btr0pcur.c: In function 'btr_pcur_move_backward_from_page': btr/btr0pcur.c:455:9: error: variable 'space' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/btr/btr0pcur.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innodb_plugin/btr/btr0pcur.c b/storage/innodb_plugin/btr/btr0pcur.c index 658901208ef..056896c7927 100644 --- a/storage/innodb_plugin/btr/btr0pcur.c +++ b/storage/innodb_plugin/btr/btr0pcur.c @@ -452,7 +452,6 @@ btr_pcur_move_backward_from_page( mtr_t* mtr) /*!< in: mtr */ { ulint prev_page_no; - ulint space; page_t* page; buf_block_t* prev_block; ulint latch_mode; @@ -488,7 +487,6 @@ btr_pcur_move_backward_from_page( page = btr_pcur_get_page(cursor); prev_page_no = btr_page_get_prev(page, mtr); - space = buf_block_get_space(btr_pcur_get_block(cursor)); if (prev_page_no == FIL_NULL) { } else if (btr_pcur_is_before_first_on_page(cursor)) { From bcde57a3bdcf4aed4fa2404980d5874f757b4fa6 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 14 Sep 2010 21:36:29 +0300 Subject: [PATCH 054/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: btr/btr0sea.c: In function 'btr_search_update_hash_on_delete': btr/btr0sea.c:1498:9: error: variable 'found' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/btr/btr0sea.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storage/innodb_plugin/btr/btr0sea.c b/storage/innodb_plugin/btr/btr0sea.c index f3ffe07a951..035fdbb61d2 100644 --- a/storage/innodb_plugin/btr/btr0sea.c +++ b/storage/innodb_plugin/btr/btr0sea.c @@ -1495,7 +1495,6 @@ btr_search_update_hash_on_delete( rec_t* rec; ulint fold; dulint index_id; - ibool found; ulint offsets_[REC_OFFS_NORMAL_SIZE]; mem_heap_t* heap = NULL; rec_offs_init(offsets_); @@ -1528,7 +1527,7 @@ btr_search_update_hash_on_delete( } rw_lock_x_lock(&btr_search_latch); - found = ha_search_and_delete_if_found(table, fold, rec); + ha_search_and_delete_if_found(table, fold, rec); rw_lock_x_unlock(&btr_search_latch); } From afd4b25d8a0ab1447d37033a377ee05a03314d44 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Wed, 15 Sep 2010 10:22:12 +0200 Subject: [PATCH 055/159] Bug#56659: Mismatch of CAPITAL vs small letters in "unified filelist" partitioning output Bug#56657: Test still uses "--exec rm -f ..." which is non-portable Bug#56601: Test uses Unix path for temporary file, fails, and writes misleading message Several tests that was written in a non portable way (failed on windows) Fixed by 1) backporting the fix for replace_result to also apply to list_files (mysqltest from mysql-trunk) 2) replacing all #p#/#sp#/#tmp# to #P#/#SP#/#TMP#/ (innodb always converts filenames to lower case in windows). 3) replacing '--exec rm -f' with '--remove_files_wildcard' 4) replacing a perl snippet with '--write_file' client/mysqltest.cc: backport from mysql-trunk to allow replace_result to apply also on list_files mysql-test/suite/parts/inc/partition_check_drop.inc: Compensate for differences between innodb on windows vs unix. Using mysqltest command, instead of unix command to remove files. mysql-test/suite/parts/inc/partition_crash.inc: compensate for differences between innodb on windows vs unix mysql-test/suite/parts/inc/partition_fail.inc: compensate for differences between innodb on windows vs unix mysql-test/suite/parts/inc/partition_layout.inc: compensate for differences between innodb on windows vs unix mysql-test/suite/parts/inc/partition_layout_check1.inc: compensate for differences between innodb on windows vs unix mysql-test/suite/parts/inc/partition_layout_check2.inc: compensate for differences between innodb on windows vs unix mysql-test/suite/parts/r/partition_recover_myisam.result: updated result mysql-test/suite/parts/r/partition_special_myisam.result: updated result mysql-test/suite/parts/t/part_supported_sql_func_innodb.test: Test takes very long time, require --big flag mysql-test/suite/parts/t/partition_alter1_1_2_innodb.test: Test takes very long time, require --big flag mysql-test/suite/parts/t/partition_alter1_2_innodb.test: Test takes very long time, require --big flag mysql-test/suite/parts/t/partition_alter2_1_1_innodb.test: Test takes very long time, require --big flag mysql-test/suite/parts/t/partition_alter2_1_2_innodb.test: Test takes very long time, require --big flag mysql-test/suite/parts/t/partition_alter2_2_2_innodb.test: Test takes very long time, require --big flag mysql-test/suite/parts/t/partition_alter4_innodb.test: Test takes very long time, require --big flag mysql-test/suite/parts/t/partition_debug_sync_innodb.test: compensate for differences between innodb on windows vs unix mysql-test/suite/parts/t/partition_recover_myisam.test: more generic suppression (failed in windows) mysql-test/suite/parts/t/partition_special_myisam.test: Using portable mysqltest command 'write_file' instead of perl snippet. --- client/mysqltest.cc | 8 +++++--- mysql-test/suite/parts/inc/partition_check_drop.inc | 9 +++++---- mysql-test/suite/parts/inc/partition_crash.inc | 6 +++--- mysql-test/suite/parts/inc/partition_fail.inc | 2 ++ mysql-test/suite/parts/inc/partition_layout.inc | 2 +- .../suite/parts/inc/partition_layout_check1.inc | 2 +- .../suite/parts/inc/partition_layout_check2.inc | 2 +- .../suite/parts/r/partition_recover_myisam.result | 2 +- .../suite/parts/r/partition_special_myisam.result | 2 +- .../suite/parts/t/part_supported_sql_func_innodb.test | 3 +++ .../suite/parts/t/partition_alter1_1_2_innodb.test | 3 +++ .../suite/parts/t/partition_alter1_2_innodb.test | 3 +++ .../suite/parts/t/partition_alter2_1_1_innodb.test | 3 +++ .../suite/parts/t/partition_alter2_1_2_innodb.test | 3 +++ .../suite/parts/t/partition_alter2_2_2_innodb.test | 3 +++ mysql-test/suite/parts/t/partition_alter4_innodb.test | 3 +++ .../suite/parts/t/partition_debug_sync_innodb.test | 2 ++ .../suite/parts/t/partition_recover_myisam.test | 2 +- .../suite/parts/t/partition_special_myisam.test | 11 ++++++----- 19 files changed, 50 insertions(+), 21 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index ca9217bf428..abe845b3710 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -447,7 +447,7 @@ struct st_command char *query, *query_buf,*first_argument,*last_argument,*end; DYNAMIC_STRING content; int first_word_len, query_len; - my_bool abort_on_error; + my_bool abort_on_error, used_replace; struct st_expected_errors expected_errors; char require_file[FN_REFLEN]; enum enum_commands type; @@ -3414,7 +3414,7 @@ static int get_list_files(DYNAMIC_STRING *ds, const DYNAMIC_STRING *ds_dirname, if (ds_wild && ds_wild->length && wild_compare(file->name, ds_wild->str, 0)) continue; - dynstr_append(ds, file->name); + replace_dynstr_append(ds, file->name); dynstr_append(ds, "\n"); } set_wild_chars(0); @@ -3444,6 +3444,7 @@ static void do_list_files(struct st_command *command) {"file", ARG_STRING, FALSE, &ds_wild, "Filename (incl. wildcard)"} }; DBUG_ENTER("do_list_files"); + command->used_replace= 1; check_command_args(command, command->first_argument, list_files_args, @@ -3485,6 +3486,7 @@ static void do_list_files_write_file_command(struct st_command *command, {"file", ARG_STRING, FALSE, &ds_wild, "Filename (incl. wildcard)"} }; DBUG_ENTER("do_list_files_write_file"); + command->used_replace= 1; check_command_args(command, command->first_argument, list_files_args, @@ -8473,7 +8475,7 @@ int main(int argc, char **argv) memset(&saved_expected_errors, 0, sizeof(saved_expected_errors)); } - if (command_executed != last_command_executed) + if (command_executed != last_command_executed || command->used_replace) { /* As soon as any command has been executed, diff --git a/mysql-test/suite/parts/inc/partition_check_drop.inc b/mysql-test/suite/parts/inc/partition_check_drop.inc index daaa5e541c7..0941cd9703b 100644 --- a/mysql-test/suite/parts/inc/partition_check_drop.inc +++ b/mysql-test/suite/parts/inc/partition_check_drop.inc @@ -26,10 +26,12 @@ if ($do_file_tests) { let $ls_file= $MYSQLD_DATADIR/test/tmp2; # List the files belonging to the table t1 + --replace_result $MYSQLTEST_VARDIR \$MYSQLTEST_VARDIR #p# #P# #sp# #SP# --list_files_write_file $ls_file $MYSQLD_DATADIR/test t1* --chmod 0644 $ls_file if ($with_directories) { + --replace_result $MYSQLTEST_VARDIR \$MYSQLTEST_VARDIR #p# #P# #sp# #SP# --list_files_append_file $ls_file $MYSQLTEST_VARDIR/tmp t1* } eval SET @aux = load_file('$ls_file'); @@ -60,16 +62,15 @@ if ($found_garbage) --echo # worked incomplete. --echo # We found: # Print the list of files into the protocol - eval SELECT REPLACE(file_list,'$MYSQLTEST_VARDIR','\$MYSQLTEST_VARDIR') - AS "unified filelist" + eval SELECT file_list AS "unified filelist" FROM t0_definition WHERE state = 'old'; } # Do a manual cleanup, because the following tests should not suffer from # remaining files - --exec rm -f $MYSQLD_DATADIR/test/t1* || true + --remove_files_wildcard $MYSQLD_DATADIR/test t1* if ($with_directories) { - --exec rm -f $MYSQLTEST_VARDIR/tmp/t1* || true + --remove_files_wildcard $MYSQLTEST_VARDIR/tmp t1* } } --enable_query_log diff --git a/mysql-test/suite/parts/inc/partition_crash.inc b/mysql-test/suite/parts/inc/partition_crash.inc index f18b8728784..b8a7c61792b 100644 --- a/mysql-test/suite/parts/inc/partition_crash.inc +++ b/mysql-test/suite/parts/inc/partition_crash.inc @@ -3,7 +3,7 @@ --eval $create_statement --eval $insert_statement --echo # State before crash ---replace_result #p# #P# +--replace_result #p# #P# #sp# #SP# --list_files $DATADIR/test SHOW CREATE TABLE t1; --sorted_result @@ -14,13 +14,13 @@ SELECT * FROM t1; --error 2013 --eval $crash_statement --echo # State after crash (before recovery) ---replace_regex /sqlx.*\./sqlx-nnnn_nnnn./ /#p#/#P#/ +--replace_regex /sqlx.*\./sqlx-nnnn_nnnn./ /#p#/#P#/ /#sp#/#SP#/ /#tmp#/#TMP#/ --list_files $DATADIR/test --exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --enable_reconnect --source include/wait_until_connected_again.inc --echo # State after crash recovery ---replace_result #p# #P# +--replace_result #p# #P# #sp# #SP# --list_files $DATADIR/test SHOW CREATE TABLE t1; --sorted_result diff --git a/mysql-test/suite/parts/inc/partition_fail.inc b/mysql-test/suite/parts/inc/partition_fail.inc index 6942b40042a..2c154a90499 100644 --- a/mysql-test/suite/parts/inc/partition_fail.inc +++ b/mysql-test/suite/parts/inc/partition_fail.inc @@ -3,6 +3,7 @@ --eval $create_statement --eval $insert_statement --echo # State before failure +--replace_result #p# #P# #sp# #SP# --list_files $DATADIR/test SHOW CREATE TABLE t1; --sorted_result @@ -11,6 +12,7 @@ SELECT * FROM t1; --eval $fail_statement --enable_abort_on_error --echo # State after failure +--replace_result #p# #P# #sp# #SP# --list_files $DATADIR/test SHOW CREATE TABLE t1; --sorted_result diff --git a/mysql-test/suite/parts/inc/partition_layout.inc b/mysql-test/suite/parts/inc/partition_layout.inc index 67d0fd4c0e9..12fbfb9a46a 100644 --- a/mysql-test/suite/parts/inc/partition_layout.inc +++ b/mysql-test/suite/parts/inc/partition_layout.inc @@ -10,6 +10,6 @@ eval SHOW CREATE TABLE t1; if ($ls) { let $MYSQLD_DATADIR= `select @@datadir`; - --replace_result $MYSQLD_DATADIR MYSQLD_DATADIR + --replace_result $MYSQLD_DATADIR MYSQLD_DATADIR #p# #P# #sp# #SP# --list_files $MYSQLD_DATADIR/test t1* } diff --git a/mysql-test/suite/parts/inc/partition_layout_check1.inc b/mysql-test/suite/parts/inc/partition_layout_check1.inc index bca41b6f9c7..1b0b24f1088 100644 --- a/mysql-test/suite/parts/inc/partition_layout_check1.inc +++ b/mysql-test/suite/parts/inc/partition_layout_check1.inc @@ -69,7 +69,7 @@ if ($do_file_tests) if ($ls) { # Print the list of files into the protocol - replace_result $MYSQLD_DATADIR MYSQLD_DATADIR $MYSQLTEST_VARDIR MYSQLTEST_VARDIR; + replace_result $MYSQLD_DATADIR MYSQLD_DATADIR $MYSQLTEST_VARDIR MYSQLTEST_VARDIR #p# #P# #sp# #SP# part_n part_N; SELECT file_list AS "unified filelist" FROM t0_definition WHERE state = 'old'; } diff --git a/mysql-test/suite/parts/inc/partition_layout_check2.inc b/mysql-test/suite/parts/inc/partition_layout_check2.inc index 7ff871a4c45..b1ec56ceedd 100644 --- a/mysql-test/suite/parts/inc/partition_layout_check2.inc +++ b/mysql-test/suite/parts/inc/partition_layout_check2.inc @@ -65,7 +65,7 @@ let $run= `SELECT @aux`; if ($run) { --vertical_results - --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR + --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR #p# #P# #sp# #SP# SELECT state, REPLACE(create_command,'\n',' ') AS "Table definition", REPLACE(file_list ,'\n',' ') AS "File list" diff --git a/mysql-test/suite/parts/r/partition_recover_myisam.result b/mysql-test/suite/parts/r/partition_recover_myisam.result index f4cdc2a418a..3c73817ef2e 100644 --- a/mysql-test/suite/parts/r/partition_recover_myisam.result +++ b/mysql-test/suite/parts/r/partition_recover_myisam.result @@ -1,4 +1,4 @@ -call mtr.add_suppression("./test/t1_will_crash"); +call mtr.add_suppression("t1_will_crash"); call mtr.add_suppression("Got an error from unknown thread"); CREATE TABLE t1_will_crash (a INT, KEY (a)) ENGINE=MyISAM; INSERT INTO t1_will_crash VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11); diff --git a/mysql-test/suite/parts/r/partition_special_myisam.result b/mysql-test/suite/parts/r/partition_special_myisam.result index f8618fcbb6d..bc8036ba861 100644 --- a/mysql-test/suite/parts/r/partition_special_myisam.result +++ b/mysql-test/suite/parts/r/partition_special_myisam.result @@ -214,7 +214,7 @@ SET lock_wait_timeout = 2; ALTER TABLE t1 COALESCE PARTITION 2; ERROR HY000: Lock wait timeout exceeded; try restarting transaction # Connection 3 tries to load into the table: -LOAD DATA LOCAL INFILE '/tmp/load.in' INTO TABLE t1 (f); +LOAD DATA INFILE 'load.in' INTO TABLE t1 (f); # Connection 1 commits the transaction COMMIT; # Connection 3... diff --git a/mysql-test/suite/parts/t/part_supported_sql_func_innodb.test b/mysql-test/suite/parts/t/part_supported_sql_func_innodb.test index e8d263e369c..002da3c8f37 100644 --- a/mysql-test/suite/parts/t/part_supported_sql_func_innodb.test +++ b/mysql-test/suite/parts/t/part_supported_sql_func_innodb.test @@ -28,6 +28,9 @@ let $do_long_tests= 1; # The server must support partitioning. --source include/have_partition.inc +# This test takes long time, so only run it with the --big mtr-flag. +--source include/big_test.inc + #------------------------------------------------------------------------------# # Engine specific settings and requirements diff --git a/mysql-test/suite/parts/t/partition_alter1_1_2_innodb.test b/mysql-test/suite/parts/t/partition_alter1_1_2_innodb.test index 8e3dde286cf..6ac1803a972 100644 --- a/mysql-test/suite/parts/t/partition_alter1_1_2_innodb.test +++ b/mysql-test/suite/parts/t/partition_alter1_1_2_innodb.test @@ -46,6 +46,9 @@ let $more_pk_ui_tests= 0; # The server must support partitioning. --source include/have_partition.inc +# This test takes long time, so only run it with the --big mtr-flag. +--source include/big_test.inc + #------------------------------------------------------------------------------# # Engine specific settings and requirements diff --git a/mysql-test/suite/parts/t/partition_alter1_2_innodb.test b/mysql-test/suite/parts/t/partition_alter1_2_innodb.test index 76fe7eb0223..2cbe0ab77ab 100644 --- a/mysql-test/suite/parts/t/partition_alter1_2_innodb.test +++ b/mysql-test/suite/parts/t/partition_alter1_2_innodb.test @@ -46,6 +46,9 @@ let $more_pk_ui_tests= 0; # The server must support partitioning. --source include/have_partition.inc +# This test takes long time, so only run it with the --big mtr-flag. +--source include/big_test.inc + #------------------------------------------------------------------------------# # Engine specific settings and requirements diff --git a/mysql-test/suite/parts/t/partition_alter2_1_1_innodb.test b/mysql-test/suite/parts/t/partition_alter2_1_1_innodb.test index 9500f05b173..37e1cb4a099 100644 --- a/mysql-test/suite/parts/t/partition_alter2_1_1_innodb.test +++ b/mysql-test/suite/parts/t/partition_alter2_1_1_innodb.test @@ -45,6 +45,9 @@ let $only_part_1= 1; # The server must support partitioning. --source include/have_partition.inc +# This test takes long time, so only run it with the --big mtr-flag. +--source include/big_test.inc + #------------------------------------------------------------------------------# # Engine specific settings and requirements diff --git a/mysql-test/suite/parts/t/partition_alter2_1_2_innodb.test b/mysql-test/suite/parts/t/partition_alter2_1_2_innodb.test index 28bbcb3115b..6448a8ac734 100644 --- a/mysql-test/suite/parts/t/partition_alter2_1_2_innodb.test +++ b/mysql-test/suite/parts/t/partition_alter2_1_2_innodb.test @@ -45,6 +45,9 @@ let $only_part_2= 1; # The server must support partitioning. --source include/have_partition.inc +# This test takes long time, so only run it with the --big mtr-flag. +--source include/big_test.inc + #------------------------------------------------------------------------------# # Engine specific settings and requirements diff --git a/mysql-test/suite/parts/t/partition_alter2_2_2_innodb.test b/mysql-test/suite/parts/t/partition_alter2_2_2_innodb.test index a356b4e31a3..e3544c382a3 100644 --- a/mysql-test/suite/parts/t/partition_alter2_2_2_innodb.test +++ b/mysql-test/suite/parts/t/partition_alter2_2_2_innodb.test @@ -45,6 +45,9 @@ let $only_part_2= 1; # The server must support partitioning. --source include/have_partition.inc +# This test takes long time, so only run it with the --big mtr-flag. +--source include/big_test.inc + #------------------------------------------------------------------------------# # Engine specific settings and requirements diff --git a/mysql-test/suite/parts/t/partition_alter4_innodb.test b/mysql-test/suite/parts/t/partition_alter4_innodb.test index 3061e5c9e7f..1e28a2fc812 100644 --- a/mysql-test/suite/parts/t/partition_alter4_innodb.test +++ b/mysql-test/suite/parts/t/partition_alter4_innodb.test @@ -43,6 +43,9 @@ let $more_pk_ui_tests= 0; # The server must support partitioning. --source include/have_partition.inc +# This test takes long time, so only run it with the --big mtr-flag. +--source include/big_test.inc + #------------------------------------------------------------------------------# # Engine specific settings and requirements diff --git a/mysql-test/suite/parts/t/partition_debug_sync_innodb.test b/mysql-test/suite/parts/t/partition_debug_sync_innodb.test index 915a3f2ceb6..fce26132030 100644 --- a/mysql-test/suite/parts/t/partition_debug_sync_innodb.test +++ b/mysql-test/suite/parts/t/partition_debug_sync_innodb.test @@ -56,6 +56,7 @@ partition by range (a) insert into t1 values (1), (11), (21), (33); SELECT * FROM t1; SHOW CREATE TABLE t1; +--replace_result #p# #P# #sp# #SP# --list_files $MYSQLD_DATADIR/test SET DEBUG_SYNC='before_open_in_get_all_tables SIGNAL parked WAIT_FOR open'; @@ -78,6 +79,7 @@ ALTER TABLE t1 REORGANIZE PARTITION p0 INTO disconnect con1; connection default; --reap +--replace_result #p# #P# #sp# #SP# --list_files $MYSQLD_DATADIR/test SHOW CREATE TABLE t1; SELECT * FROM t1; diff --git a/mysql-test/suite/parts/t/partition_recover_myisam.test b/mysql-test/suite/parts/t/partition_recover_myisam.test index d06e1914949..ecc83629768 100644 --- a/mysql-test/suite/parts/t/partition_recover_myisam.test +++ b/mysql-test/suite/parts/t/partition_recover_myisam.test @@ -1,6 +1,6 @@ # test the auto-recover (--myisam-recover) of partitioned myisam tables -call mtr.add_suppression("./test/t1_will_crash"); +call mtr.add_suppression("t1_will_crash"); call mtr.add_suppression("Got an error from unknown thread"); --source include/have_partition.inc diff --git a/mysql-test/suite/parts/t/partition_special_myisam.test b/mysql-test/suite/parts/t/partition_special_myisam.test index 032722cbb7d..2eac5b3bf16 100644 --- a/mysql-test/suite/parts/t/partition_special_myisam.test +++ b/mysql-test/suite/parts/t/partition_special_myisam.test @@ -62,13 +62,14 @@ ALTER TABLE t1 COALESCE PARTITION 2; --connect (con3,localhost,root,,) -perl; -open( LD, ">" . "/tmp/load.in" ) || die "Could not open file for writing " . $ENV{'MYSQLTEST_DATADIR'} . "/test/load.in"; -print LD "1\n2\n3\n"; -close( LD ); +--let $MYSQLD_DATADIR= `SELECT @@datadir` +--write_file $MYSQLD_DATADIR/test/load.in +1 +2 +3 EOF --echo # Connection 3 tries to load into the table: -send LOAD DATA LOCAL INFILE '/tmp/load.in' INTO TABLE t1 (f); +send LOAD DATA INFILE 'load.in' INTO TABLE t1 (f); --connection default --real_sleep 1 From 40140c00b99cdfbec5b6bf9c37d677ee13152442 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 11:29:51 +0300 Subject: [PATCH 056/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: buf/buf0flu.c: In function 'buf_flush_delete_from_flush_rbt': buf/buf0flu.c:131:8: error: variable 'ret' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/buf/buf0flu.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/storage/innodb_plugin/buf/buf0flu.c b/storage/innodb_plugin/buf/buf0flu.c index d8c0497fa1e..a911fe3ee66 100644 --- a/storage/innodb_plugin/buf/buf0flu.c +++ b/storage/innodb_plugin/buf/buf0flu.c @@ -128,10 +128,15 @@ buf_flush_delete_from_flush_rbt( buf_page_t* bpage) /*!< in: bpage to be removed. */ { +#ifdef UNIV_DEBUG ibool ret = FALSE; +#endif /* UNIV_DEBUG */ ut_ad(buf_pool_mutex_own()); - ret = rbt_delete(buf_pool->flush_rbt, &bpage); +#ifdef UNIV_DEBUG + ret = +#endif /* UNIV_DEBUG */ + rbt_delete(buf_pool->flush_rbt, &bpage); ut_ad(ret); } From fb4623f0a709dc7200be976d7c7cdd4d7d15adca Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 11:30:57 +0300 Subject: [PATCH 057/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: buf/buf0flu.c: In function 'buf_flush_batch': buf/buf0flu.c:1274:9: error: variable 'old_page_count' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/buf/buf0flu.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/storage/innodb_plugin/buf/buf0flu.c b/storage/innodb_plugin/buf/buf0flu.c index a911fe3ee66..747ce65879d 100644 --- a/storage/innodb_plugin/buf/buf0flu.c +++ b/storage/innodb_plugin/buf/buf0flu.c @@ -1271,7 +1271,6 @@ buf_flush_batch( { buf_page_t* bpage; ulint page_count = 0; - ulint old_page_count; ulint space; ulint offset; @@ -1343,15 +1342,9 @@ flush_next: buf_pool_mutex_exit(); - old_page_count = page_count; - /* Try to flush also all the neighbors */ page_count += buf_flush_try_neighbors( space, offset, flush_type); - /* fprintf(stderr, - "Flush type %lu, page no %lu, neighb %lu\n", - flush_type, offset, - page_count - old_page_count); */ buf_pool_mutex_enter(); goto flush_next; From 50dd924d7d970aa59f50a71533e22285871f600b Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 11:33:49 +0300 Subject: [PATCH 058/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: dict/dict0crea.c: In function 'dict_create_index_tree_step': dict/dict0crea.c:630:16: error: variable 'table' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/dict/dict0crea.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innodb_plugin/dict/dict0crea.c b/storage/innodb_plugin/dict/dict0crea.c index 09353c45c8c..e63f8bc3e6a 100644 --- a/storage/innodb_plugin/dict/dict0crea.c +++ b/storage/innodb_plugin/dict/dict0crea.c @@ -627,7 +627,6 @@ dict_create_index_tree_step( { dict_index_t* index; dict_table_t* sys_indexes; - dict_table_t* table; dtuple_t* search_tuple; ulint zip_size; btr_pcur_t pcur; @@ -636,7 +635,6 @@ dict_create_index_tree_step( ut_ad(mutex_own(&(dict_sys->mutex))); index = node->index; - table = node->table; sys_indexes = dict_sys->sys_indexes; From 6ff48a61f23a1241d7db95e4f84f1a132a4f08d0 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 15 Sep 2010 14:56:22 +0200 Subject: [PATCH 059/159] Bug #56753 mtr silently ignores junk after backticks When stepping backward to end of `` expression, check for illegal chars --- client/mysqltest.cc | 6 ++++++ mysql-test/include/setup_fake_relay_log.inc | 2 +- mysql-test/r/mysqltest.result | 3 +++ .../suite/rpl/t/rpl_row_tbl_metadata.test | 4 ++-- mysql-test/t/mysqltest.test | 17 +++++++++++++++++ 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 31854737cbc..a84ad2ad9e8 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -2181,8 +2181,14 @@ void var_query_set(VAR *var, const char *query, const char** query_end) DBUG_ENTER("var_query_set"); LINT_INIT(res); + /* Only white space or ) allowed past ending ` */ while (end > query && *end != '`') + { + if (*end && (*end != ' ' && *end != '\t' && *end != '\n' && *end != ')')) + die("Spurious text after `query` expression"); --end; + } + if (query == end) die("Syntax error in query, missing '`'"); ++query; diff --git a/mysql-test/include/setup_fake_relay_log.inc b/mysql-test/include/setup_fake_relay_log.inc index 5b9e7f72fdd..fb035941a29 100644 --- a/mysql-test/include/setup_fake_relay_log.inc +++ b/mysql-test/include/setup_fake_relay_log.inc @@ -72,7 +72,7 @@ copy_file $fake_relay_log $_fake_relay_log; if (`SELECT LENGTH(@@secure_file_priv) > 0`) { - -- let $_file_priv_dir= `SELECT @@secure_file_priv`; + -- let $_file_priv_dir= `SELECT @@secure_file_priv` -- let $_suffix= `SELECT UUID()` -- let $_tmp_file= $_file_priv_dir/fake-index.$_suffix diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 1044127b06e..650cc069b7f 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -177,6 +177,9 @@ mysqltest: At line 1: End of line junk detected: "disconnect default # comment " mysqltest: At line 1: Extra delimiter ";" found mysqltest: At line 1: Extra delimiter ";" found +mysqltest: At line 1: Spurious text after `query` expression +mysqltest: At line 1: Spurious text after `query` expression +mysqltest: At line 2: Spurious text after `query` expression mysqltest: At line 1: Missing argument(s) to 'error' mysqltest: At line 1: Missing argument(s) to 'error' mysqltest: At line 1: The sqlstate definition must start with an uppercase S diff --git a/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test index be5ebb661ca..d854aa64dc5 100644 --- a/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test +++ b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test @@ -205,7 +205,7 @@ DROP TABLE `t1`; -- echo === Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. --- let $MYSQLD_DATADIR= `SELECT @@datadir`; +-- let $MYSQLD_DATADIR= `SELECT @@datadir` -- exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog -- remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog @@ -330,7 +330,7 @@ while($ntables) -- echo ### assertion: check that binlog is not corrupt. Using mysqlbinlog to -- echo ### detect failure. Before the patch mysqlbinlog would find -- echo ### a corrupted event, thence would fail. --- let $MYSQLD_DATADIR= `SELECT @@datadir`; +-- let $MYSQLD_DATADIR= `SELECT @@datadir` -- exec $MYSQL_BINLOG -v --hex $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug50018.binlog ## clean up diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 9da19ec00e0..597adffd035 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -494,6 +494,23 @@ remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql; --error 1 --exec echo "--disable_query_log;" | $MYSQL_TEST 2>&1 +# +# Extra text after `` +# +--error 1 +-- exec echo "let \$x= \`select 1\` BOO ;" | $MYSQL_TEST 2>&1 +--error 1 +-- exec echo "--let \$x= \`select 1\`;" | $MYSQL_TEST 2>&1 +--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql +# Missing ; in next line should be detected and cause failure +let $x= `select 1` +let $x= 2; +echo $x; +EOF +--error 1 +--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1 +remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql; + # Allow trailing # comment --sleep 1 # Wait for insert delayed to be executed. From 40ae790ba1042d4fd8a16675d6fb2941842e2a08 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 18:00:49 +0300 Subject: [PATCH 060/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: dict/dict0dict.c: In function 'dict_index_print_low': dict/dict0dict.c:4444:14: error: variable 'type_string' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/dict/dict0dict.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/dict0dict.c index 560534345f9..a3575c283cd 100644 --- a/storage/innodb_plugin/dict/dict0dict.c +++ b/storage/innodb_plugin/dict/dict0dict.c @@ -4441,7 +4441,6 @@ dict_index_print_low( { ib_int64_t n_vals; ulint i; - const char* type_string; ut_ad(mutex_own(&(dict_sys->mutex))); @@ -4456,14 +4455,6 @@ dict_index_print_low( dict_index_stat_mutex_exit(index); - if (dict_index_is_clust(index)) { - type_string = "clustered index"; - } else if (dict_index_is_unique(index)) { - type_string = "unique index"; - } else { - type_string = "secondary index"; - } - fprintf(stderr, " INDEX: name %s, id %lu %lu, fields %lu/%lu," " uniq %lu, type %lu\n" From d8cd874f79661f2dd1163d422050b261d3df6162 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 18:02:26 +0300 Subject: [PATCH 061/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: eval/eval0eval.c: In function 'eval_notfound': eval/eval0eval.c:388:14: error: variable 'arg2' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/eval/eval0eval.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innodb_plugin/eval/eval0eval.c b/storage/innodb_plugin/eval/eval0eval.c index 589b0fa1576..2aad7951535 100644 --- a/storage/innodb_plugin/eval/eval0eval.c +++ b/storage/innodb_plugin/eval/eval0eval.c @@ -385,13 +385,11 @@ eval_notfound( func_node_t* func_node) /*!< in: function node */ { que_node_t* arg1; - que_node_t* arg2; sym_node_t* cursor; sel_node_t* sel_node; ibool ibool_val; arg1 = func_node->args; - arg2 = que_node_get_next(arg1); ut_ad(func_node->func == PARS_NOTFOUND_TOKEN); From ab5570d561621b809a1780cf91b4e7a3a68f9014 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 18:03:24 +0300 Subject: [PATCH 062/159] Remove redundant variable --- storage/innodb_plugin/eval/eval0eval.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/storage/innodb_plugin/eval/eval0eval.c b/storage/innodb_plugin/eval/eval0eval.c index 2aad7951535..dcd416adeee 100644 --- a/storage/innodb_plugin/eval/eval0eval.c +++ b/storage/innodb_plugin/eval/eval0eval.c @@ -384,16 +384,13 @@ eval_notfound( /*==========*/ func_node_t* func_node) /*!< in: function node */ { - que_node_t* arg1; sym_node_t* cursor; sel_node_t* sel_node; ibool ibool_val; - arg1 = func_node->args; - ut_ad(func_node->func == PARS_NOTFOUND_TOKEN); - cursor = arg1; + cursor = func_node->args; ut_ad(que_node_get_type(cursor) == QUE_NODE_SYMBOL); From 7ed6878c6d3a00f421d3b7951f05880ff3f39d0b Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 18:06:46 +0300 Subject: [PATCH 063/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: handler/ha_innodb.cc: In function 'bool innodb_show_status(handlerton*, THD*, bool (*)(THD*, const char*, uint, const char*, uint, const char*, uint))': handler/ha_innodb.cc:8851:7: error: variable 'result' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/handler/ha_innodb.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index c7474109d4f..485c706d7c1 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -8848,12 +8848,9 @@ innodb_show_status( mutex_exit(&srv_monitor_file_mutex); - bool result = FALSE; + stat_print(thd, innobase_hton_name, (uint) strlen(innobase_hton_name), + STRING_WITH_LEN(""), str, flen); - if (stat_print(thd, innobase_hton_name, (uint) strlen(innobase_hton_name), - STRING_WITH_LEN(""), str, flen)) { - result= TRUE; - } my_free(str, MYF(0)); DBUG_RETURN(FALSE); From 7d0b8b5e5fb75f8ec2812d0ced07419f03e207c0 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 18:10:10 +0300 Subject: [PATCH 064/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: handler/ha_innodb.cc: In function 'void innobase_drop_database(handlerton*, char*)': handler/ha_innodb.cc:7010:6: error: variable 'error' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/handler/ha_innodb.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 485c706d7c1..a7635a402a6 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -7007,7 +7007,6 @@ innobase_drop_database( ulint len = 0; trx_t* trx; char* ptr; - int error; char* namebuf; THD* thd = current_thd; @@ -7050,7 +7049,7 @@ innobase_drop_database( #else trx = innobase_trx_allocate(thd); #endif - error = row_drop_database_for_mysql(namebuf, trx); + row_drop_database_for_mysql(namebuf, trx); my_free(namebuf, MYF(0)); /* Flush the log to reduce probability that the .frm files and From a51ef6f673181a54225bc721ddd00af0e109fc93 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 18:25:24 +0300 Subject: [PATCH 065/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: handler/i_s.cc: In function 'int trx_i_s_common_fill_table(THD*, TABLE_LIST*, COND*)': handler/i_s.cc:931:8: error: variable 'ret' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/handler/i_s.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler/i_s.cc index 524fe696de2..1ac79860351 100644 --- a/storage/innodb_plugin/handler/i_s.cc +++ b/storage/innodb_plugin/handler/i_s.cc @@ -1013,6 +1013,7 @@ trx_i_s_common_fill_table( see http://bugs.mysql.com/29900 ; when that bug is resolved we can enable the DBUG_RETURN(ret) above */ DBUG_RETURN(0); + ret++; // silence a gcc46 warning #endif } From ad6165a9d44b4f1f7b28dd2b7d081a5ede628997 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 18:31:16 +0300 Subject: [PATCH 066/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: log/log0recv.c: In function 'recv_recovery_from_checkpoint_start_func': log/log0recv.c:2894:14: error: variable 'archived_lsn' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/log/log0recv.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/storage/innodb_plugin/log/log0recv.c b/storage/innodb_plugin/log/log0recv.c index a727d6be768..9e31eb1b4e0 100644 --- a/storage/innodb_plugin/log/log0recv.c +++ b/storage/innodb_plugin/log/log0recv.c @@ -2891,7 +2891,9 @@ recv_recovery_from_checkpoint_start_func( ib_uint64_t old_scanned_lsn; ib_uint64_t group_scanned_lsn; ib_uint64_t contiguous_lsn; +#ifdef UNIV_LOG_ARCHIVE ib_uint64_t archived_lsn; +#endif /* UNIV_LOG_ARCHIVE */ byte* buf; byte log_hdr_buf[LOG_FILE_HDR_SIZE]; ulint err; @@ -2946,7 +2948,9 @@ recv_recovery_from_checkpoint_start_func( checkpoint_lsn = mach_read_ull(buf + LOG_CHECKPOINT_LSN); checkpoint_no = mach_read_ull(buf + LOG_CHECKPOINT_NO); +#ifdef UNIV_LOG_ARCHIVE archived_lsn = mach_read_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN); +#endif /* UNIV_LOG_ARCHIVE */ /* Read the first log file header to print a note if this is a recovery from a restored InnoDB Hot Backup */ From 88c37655fb35810fc60546f627234d0713661461 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 18:32:12 +0300 Subject: [PATCH 067/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: log/log0recv.c: In function 'recv_synchronize_groups': log/log0recv.c:562:14: error: variable 'limit_lsn' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/log/log0recv.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innodb_plugin/log/log0recv.c b/storage/innodb_plugin/log/log0recv.c index 9e31eb1b4e0..c1d12dad413 100644 --- a/storage/innodb_plugin/log/log0recv.c +++ b/storage/innodb_plugin/log/log0recv.c @@ -559,10 +559,8 @@ recv_synchronize_groups( ib_uint64_t start_lsn; ib_uint64_t end_lsn; ib_uint64_t recovered_lsn; - ib_uint64_t limit_lsn; recovered_lsn = recv_sys->recovered_lsn; - limit_lsn = recv_sys->limit_lsn; /* Read the last recovered log block to the recovery system buffer: the block is always incomplete */ From fa1b367bcff895c2d35d2a472d05adb466ce48db Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 18:35:11 +0300 Subject: [PATCH 068/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warnings: os/os0file.c: In function 'os_file_create': os/os0file.c:1371:14: error: variable 'purpose_str' set but not used [-Werror=unused-but-set-variable] os/os0file.c:1370:14: error: variable 'type_str' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/os/os0file.c | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/storage/innodb_plugin/os/os0file.c b/storage/innodb_plugin/os/os0file.c index 9f937b9def2..6a0d6ea5363 100644 --- a/storage/innodb_plugin/os/os0file.c +++ b/storage/innodb_plugin/os/os0file.c @@ -1367,8 +1367,6 @@ try_again: int create_flag; ibool retry; const char* mode_str = NULL; - const char* type_str = NULL; - const char* purpose_str = NULL; try_again: ut_a(name); @@ -1388,26 +1386,9 @@ try_again: ut_error; } - if (type == OS_LOG_FILE) { - type_str = "LOG"; - } else if (type == OS_DATA_FILE) { - type_str = "DATA"; - } else { - ut_error; - } + ut_a(type == OS_LOG_FILE || type == OS_DATA_FILE); + ut_a(purpose == OS_FILE_AIO || purpose == OS_FILE_NORMAL); - if (purpose == OS_FILE_AIO) { - purpose_str = "AIO"; - } else if (purpose == OS_FILE_NORMAL) { - purpose_str = "NORMAL"; - } else { - ut_error; - } - -#if 0 - fprintf(stderr, "Opening file %s, mode %s, type %s, purpose %s\n", - name, mode_str, type_str, purpose_str); -#endif #ifdef O_SYNC /* We let O_SYNC only affect log files; note that we map O_DSYNC to O_SYNC because the datasync options seemed to corrupt files in 2001 From dac4573273a487b2d3b4bb76144159e350934b17 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 18:35:59 +0300 Subject: [PATCH 069/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: que/que0que.c: In function 'que_run_threads_low': que/que0que.c:1287:9: error: variable 'cumul_resource' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/que/que0que.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/storage/innodb_plugin/que/que0que.c b/storage/innodb_plugin/que/que0que.c index 2fe046fa9b8..b616b3d9c14 100644 --- a/storage/innodb_plugin/que/que0que.c +++ b/storage/innodb_plugin/que/que0que.c @@ -1284,18 +1284,13 @@ que_run_threads_low( que_thr_t* thr) /*!< in: query thread */ { que_thr_t* next_thr; - ulint cumul_resource; ulint loop_count; ut_ad(thr->state == QUE_THR_RUNNING); ut_a(thr_get_trx(thr)->error_state == DB_SUCCESS); ut_ad(!mutex_own(&kernel_mutex)); - /* cumul_resource counts how much resources the OS thread (NOT the - query thread) has spent in this function */ - loop_count = QUE_MAX_LOOPS_WITHOUT_CHECK; - cumul_resource = 0; loop: /* Check that there is enough space in the log to accommodate possible log entries by this query step; if the operation can touch From 8d543ffa0b131faca40324d59a969e53601ce872 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 18:37:24 +0300 Subject: [PATCH 070/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: row/row0purge.c: In function 'row_purge_step': row/row0purge.c:687:9: error: variable 'err' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/row/row0purge.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/storage/innodb_plugin/row/row0purge.c b/storage/innodb_plugin/row/row0purge.c index 835af990672..31b255cf2d4 100644 --- a/storage/innodb_plugin/row/row0purge.c +++ b/storage/innodb_plugin/row/row0purge.c @@ -684,7 +684,9 @@ row_purge_step( que_thr_t* thr) /*!< in: query thread */ { purge_node_t* node; +#ifdef UNIV_DEBUG ulint err; +#endif /* UNIV_DEBUG */ ut_ad(thr); @@ -692,7 +694,10 @@ row_purge_step( ut_ad(que_node_get_type(node) == QUE_NODE_PURGE); - err = row_purge(node, thr); +#ifdef UNIV_DEBUG + err = +#endif /* UNIV_DEBUG */ + row_purge(node, thr); ut_ad(err == DB_SUCCESS); From 92c05f1b51953d8cb40a3e829d7411439f5a663b Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 18:41:35 +0300 Subject: [PATCH 071/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: row/row0umod.c: In function 'row_undo_mod_clust_low': row/row0umod.c:117:9: error: variable 'success' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/row/row0umod.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/storage/innodb_plugin/row/row0umod.c b/storage/innodb_plugin/row/row0umod.c index 8464b0f95cc..5998dadd16d 100644 --- a/storage/innodb_plugin/row/row0umod.c +++ b/storage/innodb_plugin/row/row0umod.c @@ -114,12 +114,17 @@ row_undo_mod_clust_low( btr_pcur_t* pcur; btr_cur_t* btr_cur; ulint err; +#ifdef UNIV_DEBUG ibool success; +#endif /* UNIV_DEBUG */ pcur = &(node->pcur); btr_cur = btr_pcur_get_btr_cur(pcur); - success = btr_pcur_restore_position(mode, pcur, mtr); +#ifdef UNIV_DEBUG + success = +#endif /* UNIV_DEBUG */ + btr_pcur_restore_position(mode, pcur, mtr); ut_ad(success); From 6c0ad7212b710f82554af7f4f8d9d26362d4f3fd Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 18:43:07 +0300 Subject: [PATCH 072/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: row/row0vers.c: In function 'row_vers_impl_x_locked_off_kernel': row/row0vers.c:74:9: error: variable 'err' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/row/row0vers.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/storage/innodb_plugin/row/row0vers.c b/storage/innodb_plugin/row/row0vers.c index a4fbb5289aa..b6d35363f08 100644 --- a/storage/innodb_plugin/row/row0vers.c +++ b/storage/innodb_plugin/row/row0vers.c @@ -71,7 +71,9 @@ row_vers_impl_x_locked_off_kernel( warning */ trx_t* trx; ulint rec_del; +#ifdef UNIV_DEBUG ulint err; +#endif /* UNIV_DEBUG */ mtr_t mtr; ulint comp; @@ -169,9 +171,12 @@ row_vers_impl_x_locked_off_kernel( heap2 = heap; heap = mem_heap_create(1024); - err = trx_undo_prev_version_build(clust_rec, &mtr, version, - clust_index, clust_offsets, - heap, &prev_version); +#ifdef UNIV_DEBUG + err = +#endif /* UNIV_DEBUG */ + trx_undo_prev_version_build(clust_rec, &mtr, version, + clust_index, clust_offsets, + heap, &prev_version); mem_heap_free(heap2); /* free version and clust_offsets */ if (prev_version == NULL) { From 85df29122dbe629692d857c01bd486398312b05a Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 18:44:55 +0300 Subject: [PATCH 073/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: trx/trx0purge.c: In function 'trx_purge_add_update_undo_to_history': trx/trx0purge.c:309:16: error: variable 'page_header' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/trx/trx0purge.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innodb_plugin/trx/trx0purge.c b/storage/innodb_plugin/trx/trx0purge.c index abbfa3d7f81..09c9755c74c 100644 --- a/storage/innodb_plugin/trx/trx0purge.c +++ b/storage/innodb_plugin/trx/trx0purge.c @@ -306,7 +306,6 @@ trx_purge_add_update_undo_to_history( trx_rsegf_t* rseg_header; trx_usegf_t* seg_header; trx_ulogf_t* undo_header; - trx_upagef_t* page_header; ulint hist_size; undo = trx->update_undo; @@ -322,7 +321,6 @@ trx_purge_add_update_undo_to_history( undo_header = undo_page + undo->hdr_offset; seg_header = undo_page + TRX_UNDO_SEG_HDR; - page_header = undo_page + TRX_UNDO_PAGE_HDR; if (undo->state != TRX_UNDO_CACHED) { /* The undo log segment will not be reused */ From db656f084c3cd138c8e487ba7575c62b3e279265 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 18:45:57 +0300 Subject: [PATCH 074/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: trx/trx0purge.c: In function 'trx_purge_add_update_undo_to_history': trx/trx0purge.c:307:15: error: variable 'seg_header' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/trx/trx0purge.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/storage/innodb_plugin/trx/trx0purge.c b/storage/innodb_plugin/trx/trx0purge.c index 09c9755c74c..43dd051c2ee 100644 --- a/storage/innodb_plugin/trx/trx0purge.c +++ b/storage/innodb_plugin/trx/trx0purge.c @@ -304,7 +304,9 @@ trx_purge_add_update_undo_to_history( trx_undo_t* undo; trx_rseg_t* rseg; trx_rsegf_t* rseg_header; +#ifdef UNIV_DEBUG trx_usegf_t* seg_header; +#endif /* UNIV_DEBUG */ trx_ulogf_t* undo_header; ulint hist_size; @@ -320,7 +322,9 @@ trx_purge_add_update_undo_to_history( rseg->page_no, mtr); undo_header = undo_page + undo->hdr_offset; +#ifdef UNIV_DEBUG seg_header = undo_page + TRX_UNDO_SEG_HDR; +#endif /* UNIV_DEBUG */ if (undo->state != TRX_UNDO_CACHED) { /* The undo log segment will not be reused */ From 7d39b69f5959116506785a54c7a567c5e6c66f56 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 18:47:14 +0300 Subject: [PATCH 075/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: trx/trx0purge.c: In function 'trx_purge_rseg_get_next_history_log': trx/trx0purge.c:660:15: error: variable 'seg_hdr' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/trx/trx0purge.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innodb_plugin/trx/trx0purge.c b/storage/innodb_plugin/trx/trx0purge.c index 43dd051c2ee..38966cb5db5 100644 --- a/storage/innodb_plugin/trx/trx0purge.c +++ b/storage/innodb_plugin/trx/trx0purge.c @@ -657,7 +657,6 @@ trx_purge_rseg_get_next_history_log( { page_t* undo_page; trx_ulogf_t* log_hdr; - trx_usegf_t* seg_hdr; fil_addr_t prev_log_addr; trx_id_t trx_no; ibool del_marks; @@ -678,7 +677,6 @@ trx_purge_rseg_get_next_history_log( undo_page = trx_undo_page_get_s_latched(rseg->space, rseg->zip_size, rseg->last_page_no, &mtr); log_hdr = undo_page + rseg->last_offset; - seg_hdr = undo_page + TRX_UNDO_SEG_HDR; /* Increase the purge page count by one for every handled log */ From 7cfe9f4fbd870b1dd64553d509e4029716deb37f Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 19:05:35 +0300 Subject: [PATCH 076/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: trx/trx0purge.c: In function 'trx_purge_rec_release': trx/trx0purge.c:1071:18: error: variable 'arr' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/trx/trx0purge.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/storage/innodb_plugin/trx/trx0purge.c b/storage/innodb_plugin/trx/trx0purge.c index 38966cb5db5..1a70750083a 100644 --- a/storage/innodb_plugin/trx/trx0purge.c +++ b/storage/innodb_plugin/trx/trx0purge.c @@ -1068,12 +1068,8 @@ trx_purge_rec_release( /*==================*/ trx_undo_inf_t* cell) /*!< in: storage cell */ { - trx_undo_arr_t* arr; - mutex_enter(&(purge_sys->mutex)); - arr = purge_sys->arr; - trx_purge_arr_remove_info(cell); mutex_exit(&(purge_sys->mutex)); From 8968ca7f009ae4b0a085c832588509a5bc5166a5 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 19:06:31 +0300 Subject: [PATCH 077/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warnings: trx/trx0roll.c: In function 'trx_undo_arr_remove_info': trx/trx0roll.c:744:9: error: variable 'n' set but not used [-Werror=unused-but-set-variable] trx/trx0roll.c:743:9: error: variable 'n_used' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/trx/trx0roll.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/storage/innodb_plugin/trx/trx0roll.c b/storage/innodb_plugin/trx/trx0roll.c index c925478cdf4..1a43e419214 100644 --- a/storage/innodb_plugin/trx/trx0roll.c +++ b/storage/innodb_plugin/trx/trx0roll.c @@ -740,13 +740,8 @@ trx_undo_arr_remove_info( undo_no_t undo_no)/*!< in: undo number */ { trx_undo_inf_t* cell; - ulint n_used; - ulint n; ulint i; - n_used = arr->n_used; - n = 0; - for (i = 0;; i++) { cell = trx_undo_arr_get_nth_info(arr, i); From c8a205c68bdfa6e2be3c425f1fbd378e9821ad89 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 19:47:35 +0300 Subject: [PATCH 078/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: trx/trx0sys.c: In function 'trx_sys_create_doublewrite_buf': trx/trx0sys.c:244:15: error: variable 'new_block' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/trx/trx0sys.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/storage/innodb_plugin/trx/trx0sys.c b/storage/innodb_plugin/trx/trx0sys.c index 410c55f132d..d20f436b71b 100644 --- a/storage/innodb_plugin/trx/trx0sys.c +++ b/storage/innodb_plugin/trx/trx0sys.c @@ -241,7 +241,9 @@ trx_sys_create_doublewrite_buf(void) { buf_block_t* block; buf_block_t* block2; +#ifdef UNIV_DEBUG buf_block_t* new_block; +#endif /* UNIV_DEBUG */ byte* doublewrite; byte* fseg_header; ulint page_no; @@ -344,8 +346,11 @@ start_again: the page position in the tablespace, then the page has not been written to in doublewrite. */ - new_block = buf_page_get(TRX_SYS_SPACE, 0, page_no, - RW_X_LATCH, &mtr); +#ifdef UNIV_DEBUG + new_block = +#endif /* UNIV_DEBUG */ + buf_page_get(TRX_SYS_SPACE, 0, page_no, + RW_X_LATCH, &mtr); buf_block_dbg_add_level(new_block, SYNC_NO_ORDER_CHECK); From 7e2a00b27e624bd507a88228f4c49f3712724b55 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 19:48:37 +0300 Subject: [PATCH 079/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: trx/trx0trx.c: In function 'trx_prepare_off_kernel': trx/trx0trx.c:1808:11: error: variable 'update_hdr_page' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/trx/trx0trx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storage/innodb_plugin/trx/trx0trx.c b/storage/innodb_plugin/trx/trx0trx.c index 9722bb59a5e..ee744fd58b1 100644 --- a/storage/innodb_plugin/trx/trx0trx.c +++ b/storage/innodb_plugin/trx/trx0trx.c @@ -1805,7 +1805,6 @@ trx_prepare_off_kernel( /*===================*/ trx_t* trx) /*!< in: transaction */ { - page_t* update_hdr_page; trx_rseg_t* rseg; ib_uint64_t lsn = 0; mtr_t mtr; @@ -1838,7 +1837,7 @@ trx_prepare_off_kernel( } if (trx->update_undo) { - update_hdr_page = trx_undo_set_state_at_prepare( + trx_undo_set_state_at_prepare( trx, trx->update_undo, &mtr); } From e4996035b2e3305717466b1a08bdf5423ec52d2d Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 19:49:25 +0300 Subject: [PATCH 080/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: trx/trx0undo.c: In function 'trx_undo_set_state_at_prepare': trx/trx0undo.c:1871:16: error: variable 'page_hdr' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/trx/trx0undo.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innodb_plugin/trx/trx0undo.c b/storage/innodb_plugin/trx/trx0undo.c index eb5112c4d31..32f51b79a74 100644 --- a/storage/innodb_plugin/trx/trx0undo.c +++ b/storage/innodb_plugin/trx/trx0undo.c @@ -1868,7 +1868,6 @@ trx_undo_set_state_at_prepare( mtr_t* mtr) /*!< in: mtr */ { trx_usegf_t* seg_hdr; - trx_upagef_t* page_hdr; trx_ulogf_t* undo_header; page_t* undo_page; ulint offset; @@ -1886,7 +1885,6 @@ trx_undo_set_state_at_prepare( undo->hdr_page_no, mtr); seg_hdr = undo_page + TRX_UNDO_SEG_HDR; - page_hdr = undo_page + TRX_UNDO_PAGE_HDR; /*------------------------------*/ undo->state = TRX_UNDO_PREPARED; From da98776bfbb9a9827f197a63eddd337db1df7dd9 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 19:50:05 +0300 Subject: [PATCH 081/159] (partially) Fix Bug#55227 Fix compiler warnings in innodb with gcc 4.6 Fix compiler warning: trx/trx0undo.c: In function 'trx_undo_truncate_end': trx/trx0undo.c:1069:14: error: variable 'rseg' set but not used [-Werror=unused-but-set-variable] --- storage/innodb_plugin/trx/trx0undo.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/storage/innodb_plugin/trx/trx0undo.c b/storage/innodb_plugin/trx/trx0undo.c index 32f51b79a74..c8a4b15e48b 100644 --- a/storage/innodb_plugin/trx/trx0undo.c +++ b/storage/innodb_plugin/trx/trx0undo.c @@ -1066,14 +1066,11 @@ trx_undo_truncate_end( ulint last_page_no; trx_undo_rec_t* rec; trx_undo_rec_t* trunc_here; - trx_rseg_t* rseg; mtr_t mtr; ut_ad(mutex_own(&(trx->undo_mutex))); ut_ad(mutex_own(&(trx->rseg->mutex))); - rseg = trx->rseg; - for (;;) { mtr_start(&mtr); From 844a8098aa43d6f8e5dcf3b591f33579f42e968f Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 15 Sep 2010 19:58:36 +0300 Subject: [PATCH 082/159] Fix typo, should be UNIV_SYNC_DEBUG. --- storage/innodb_plugin/trx/trx0sys.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/storage/innodb_plugin/trx/trx0sys.c b/storage/innodb_plugin/trx/trx0sys.c index d20f436b71b..6eb356947cc 100644 --- a/storage/innodb_plugin/trx/trx0sys.c +++ b/storage/innodb_plugin/trx/trx0sys.c @@ -241,9 +241,9 @@ trx_sys_create_doublewrite_buf(void) { buf_block_t* block; buf_block_t* block2; -#ifdef UNIV_DEBUG +#ifdef UNIV_SYNC_DEBUG buf_block_t* new_block; -#endif /* UNIV_DEBUG */ +#endif /* UNIV_SYNC_DEBUG */ byte* doublewrite; byte* fseg_header; ulint page_no; @@ -346,9 +346,9 @@ start_again: the page position in the tablespace, then the page has not been written to in doublewrite. */ -#ifdef UNIV_DEBUG +#ifdef UNIV_SYNC_DEBUG new_block = -#endif /* UNIV_DEBUG */ +#endif /* UNIV_SYNC_DEBUG */ buf_page_get(TRX_SYS_SPACE, 0, page_no, RW_X_LATCH, &mtr); buf_block_dbg_add_level(new_block, From bc4c38ac43b8803cbd7097e04490802d8ca262dc Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Thu, 16 Sep 2010 19:24:32 -0700 Subject: [PATCH 083/159] Temporarily backout the Information Schema System Table Information Schema interface related change, will put back in once gain approval. --- mysql-test/r/mysqlshow.result | 30 +- .../innodb/r/innodb-system-table-view.result | 110 -- .../t/innodb-system-table-view-master.opt | 3 - .../innodb/t/innodb-system-table-view.test | 94 - storage/innobase/handler/ha_innodb.cc | 10 +- storage/innobase/handler/i_s.cc | 1628 ----------------- storage/innobase/handler/i_s.h | 7 - 7 files changed, 9 insertions(+), 1873 deletions(-) delete mode 100644 mysql-test/suite/innodb/r/innodb-system-table-view.result delete mode 100644 mysql-test/suite/innodb/t/innodb-system-table-view-master.opt delete mode 100644 mysql-test/suite/innodb/t/innodb-system-table-view.test diff --git a/mysql-test/r/mysqlshow.result b/mysql-test/r/mysqlshow.result index f7b5869a3e3..4293465df67 100644 --- a/mysql-test/r/mysqlshow.result +++ b/mysql-test/r/mysqlshow.result @@ -109,20 +109,13 @@ Database: information_schema | TRIGGERS | | USER_PRIVILEGES | | VIEWS | -| INNODB_SYS_FIELDS | -| INNODB_TRX | -| INNODB_SYS_INDEXES | -| INNODB_LOCK_WAITS | -| INNODB_SYS_TABLESTATS | -| INNODB_CMP | -| INNODB_SYS_COLUMNS | | INNODB_CMP_RESET | -| INNODB_SYS_FOREIGN_COLS | -| INNODB_LOCKS | +| INNODB_TRX | | INNODB_CMPMEM_RESET | +| INNODB_LOCK_WAITS | | INNODB_CMPMEM | -| INNODB_SYS_FOREIGN | -| INNODB_SYS_TABLES | +| INNODB_CMP | +| INNODB_LOCKS | +---------------------------------------+ Database: INFORMATION_SCHEMA +---------------------------------------+ @@ -158,20 +151,13 @@ Database: INFORMATION_SCHEMA | TRIGGERS | | USER_PRIVILEGES | | VIEWS | -| INNODB_SYS_FIELDS | -| INNODB_TRX | -| INNODB_SYS_INDEXES | -| INNODB_LOCK_WAITS | -| INNODB_SYS_TABLESTATS | -| INNODB_CMP | -| INNODB_SYS_COLUMNS | | INNODB_CMP_RESET | -| INNODB_SYS_FOREIGN_COLS | -| INNODB_LOCKS | +| INNODB_TRX | | INNODB_CMPMEM_RESET | +| INNODB_LOCK_WAITS | | INNODB_CMPMEM | -| INNODB_SYS_FOREIGN | -| INNODB_SYS_TABLES | +| INNODB_CMP | +| INNODB_LOCKS | +---------------------------------------+ Wildcard: inf_rmation_schema +--------------------+ diff --git a/mysql-test/suite/innodb/r/innodb-system-table-view.result b/mysql-test/suite/innodb/r/innodb-system-table-view.result deleted file mode 100644 index ffa57ee32ce..00000000000 --- a/mysql-test/suite/innodb/r/innodb-system-table-view.result +++ /dev/null @@ -1,110 +0,0 @@ -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES; -TABLE_ID NAME FLAG N_COLS SPACE -11 SYS_FOREIGN 0 7 0 -12 SYS_FOREIGN_COLS 0 7 0 -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES; -INDEX_ID NAME TABLE_ID TYPE N_FIELDS PAGE_NO SPACE -11 ID_IND 11 3 1 302 0 -12 FOR_IND 11 0 1 303 0 -13 REF_IND 11 0 1 304 0 -14 ID_IND 12 3 2 305 0 -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS; -TABLE_ID NAME POS MTYPE PRTYPE LEN -11 ID 0 1 524292 0 -11 FOR_NAME 1 1 524292 0 -11 REF_NAME 2 1 524292 0 -11 N_COLS 3 6 0 4 -12 ID 0 1 524292 0 -12 POS 1 6 0 4 -12 FOR_COL_NAME 2 1 524292 0 -12 REF_COL_NAME 3 1 524292 0 -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS; -INDEX_ID NAME POS -11 ID 0 -12 FOR_NAME 0 -13 REF_NAME 0 -14 ID 0 -14 POS 1 -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS; -TABLE_ID NAME STATS_INITIALIZED NUM_ROWS CLUST_INDEX_SIZE OTHER_INDEX_SIZE MODIFIED_COUNTER AUTOINC MYSQL_HANDLES_OPENED -11 SYS_FOREIGN Uninitialized 0 0 0 0 0 0 -12 SYS_FOREIGN_COLS Uninitialized 0 0 0 0 0 0 -CREATE TABLE parent (id INT NOT NULL, -PRIMARY KEY (id)) ENGINE=INNODB; -CREATE TABLE child (id INT, parent_id INT, -INDEX par_ind (parent_id), -CONSTRAINT constraint_test -FOREIGN KEY (parent_id) REFERENCES parent(id) -ON DELETE CASCADE) ENGINE=INNODB; -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -test/constraint_test test/child test/parent 1 1 -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -test/constraint_test parent_id id 0 -INSERT INTO parent VALUES(1); -SELECT name, num_rows, mysql_handles_opened -FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS -WHERE name LIKE "%parent"; -name num_rows mysql_handles_opened -test/parent 1 1 -SELECT NAME, FLAG, N_COLS, SPACE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES; -NAME FLAG N_COLS SPACE -SYS_FOREIGN 0 7 0 -SYS_FOREIGN_COLS 0 7 0 -test/child 1 5 0 -test/parent 1 4 0 -SELECT name, n_fields -from INFORMATION_SCHEMA.INNODB_SYS_INDEXES -WHERE table_id In (SELECT table_id from -INFORMATION_SCHEMA.INNODB_SYS_TABLES -WHERE name LIKE "%parent%"); -name n_fields -PRIMARY 1 -SELECT name, n_fields -from INFORMATION_SCHEMA.INNODB_SYS_INDEXES -WHERE table_id In (SELECT table_id from -INFORMATION_SCHEMA.INNODB_SYS_TABLES -WHERE name LIKE "%child%"); -name n_fields -GEN_CLUST_INDEX 0 -par_ind 1 -SELECT name, pos, mtype, len -from INFORMATION_SCHEMA.INNODB_SYS_COLUMNS -WHERE table_id In (SELECT table_id from -INFORMATION_SCHEMA.INNODB_SYS_TABLES -WHERE name LIKE "%child%"); -name pos mtype len -id 0 6 4 -parent_id 1 6 4 -DROP TABLE child; -DROP TABLE parent; -CREATE TABLE parent (id INT NOT NULL, newid INT NOT NULL, -PRIMARY KEY (id, newid)) ENGINE=INNODB; -CREATE TABLE child (id INT, parent_id INT, -INDEX par_ind (parent_id), -CONSTRAINT constraint_test -FOREIGN KEY (id, parent_id) REFERENCES parent(id, newid) -ON DELETE CASCADE) ENGINE=INNODB; -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; -ID FOR_NAME REF_NAME N_COLS TYPE -test/constraint_test test/child test/parent 2 1 -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; -ID FOR_COL_NAME REF_COL_NAME POS -test/constraint_test id id 0 -test/constraint_test parent_id newid 1 -INSERT INTO parent VALUES(1, 9); -SELECT * FROM parent WHERE id IN (SELECT id FROM parent); -id newid -1 9 -SELECT name, num_rows, mysql_handles_opened -FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS -WHERE name LIKE "%parent"; -name num_rows mysql_handles_opened -test/parent 1 2 -DROP TABLE child; -DROP TABLE parent; diff --git a/mysql-test/suite/innodb/t/innodb-system-table-view-master.opt b/mysql-test/suite/innodb/t/innodb-system-table-view-master.opt deleted file mode 100644 index 303ec1be1d0..00000000000 --- a/mysql-test/suite/innodb/t/innodb-system-table-view-master.opt +++ /dev/null @@ -1,3 +0,0 @@ ---default-storage-engine=MyISAM ---innodb-strict-mode=0 ---innodb-file-per-table=0 diff --git a/mysql-test/suite/innodb/t/innodb-system-table-view.test b/mysql-test/suite/innodb/t/innodb-system-table-view.test deleted file mode 100644 index e570a33b59d..00000000000 --- a/mysql-test/suite/innodb/t/innodb-system-table-view.test +++ /dev/null @@ -1,94 +0,0 @@ -# This is the test for Information Schema System Table View -# that displays the InnoDB system table content through -# information schema tables. - ---source include/have_innodb.inc - -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES; - -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES; - -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS; - -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS; - -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; - -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; - -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS; - -# Create a foreign key constraint, and verify the information -# in INFORMATION_SCHEMA.INNODB_SYS_FOREIGN and -# INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS -CREATE TABLE parent (id INT NOT NULL, - PRIMARY KEY (id)) ENGINE=INNODB; - -CREATE TABLE child (id INT, parent_id INT, - INDEX par_ind (parent_id), - CONSTRAINT constraint_test - FOREIGN KEY (parent_id) REFERENCES parent(id) - ON DELETE CASCADE) ENGINE=INNODB; - -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; - -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; - -# Insert a row in the table "parent", and see whether that reflected in -# INNODB_SYS_TABLESTATS -INSERT INTO parent VALUES(1); - -SELECT name, num_rows, mysql_handles_opened -FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS -WHERE name LIKE "%parent"; - -SELECT NAME, FLAG, N_COLS, SPACE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES; - -SELECT name, n_fields -from INFORMATION_SCHEMA.INNODB_SYS_INDEXES -WHERE table_id In (SELECT table_id from - INFORMATION_SCHEMA.INNODB_SYS_TABLES - WHERE name LIKE "%parent%"); - -SELECT name, n_fields -from INFORMATION_SCHEMA.INNODB_SYS_INDEXES -WHERE table_id In (SELECT table_id from - INFORMATION_SCHEMA.INNODB_SYS_TABLES - WHERE name LIKE "%child%"); - -SELECT name, pos, mtype, len -from INFORMATION_SCHEMA.INNODB_SYS_COLUMNS -WHERE table_id In (SELECT table_id from - INFORMATION_SCHEMA.INNODB_SYS_TABLES - WHERE name LIKE "%child%"); - -DROP TABLE child; - -DROP TABLE parent; - -# Create table with 2 columns in the foreign key constraint -CREATE TABLE parent (id INT NOT NULL, newid INT NOT NULL, - PRIMARY KEY (id, newid)) ENGINE=INNODB; - -CREATE TABLE child (id INT, parent_id INT, - INDEX par_ind (parent_id), - CONSTRAINT constraint_test - FOREIGN KEY (id, parent_id) REFERENCES parent(id, newid) - ON DELETE CASCADE) ENGINE=INNODB; - -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN; - -SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS; - -INSERT INTO parent VALUES(1, 9); - -# Nested query will open the table handle twice -SELECT * FROM parent WHERE id IN (SELECT id FROM parent); - -SELECT name, num_rows, mysql_handles_opened -FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS -WHERE name LIKE "%parent"; - -DROP TABLE child; - -DROP TABLE parent; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index df6032fbd40..7a5608bd95c 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -11177,15 +11177,7 @@ i_s_innodb_lock_waits, i_s_innodb_cmp, i_s_innodb_cmp_reset, i_s_innodb_cmpmem, -i_s_innodb_cmpmem_reset, -i_s_innodb_sys_tables, -i_s_innodb_sys_tablestats, -i_s_innodb_sys_indexes, -i_s_innodb_sys_columns, -i_s_innodb_sys_fields, -i_s_innodb_sys_foreign, -i_s_innodb_sys_foreign_cols - +i_s_innodb_cmpmem_reset mysql_declare_plugin_end; /** @brief Initialize the default value of innodb_commit_concurrency. diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 0733a558080..e31d6b3c523 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -36,11 +36,9 @@ Created July 18, 2007 Vasil Dimov #include extern "C" { -#include "btr0pcur.h" /* for file sys_tables related info. */ #include "btr0types.h" #include "buf0buddy.h" /* for i_s_cmpmem */ #include "buf0buf.h" /* for buf_pool and PAGE_ZIP_MIN_SIZE */ -#include "dict0load.h" /* for file sys_tables related info. */ #include "dict0mem.h" #include "dict0types.h" #include "ha_prototypes.h" /* for innobase_convert_name() */ @@ -1783,1629 +1781,3 @@ i_s_common_deinit( DBUG_RETURN(0); } - -/* Fields of the dynamic table INFORMATION_SCHEMA.SYS_TABLES */ -static ST_FIELD_INFO innodb_sys_tables_fields_info[] = -{ -#define SYS_TABLE_ID 0 - {STRUCT_FLD(field_name, "TABLE_ID"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_TABLE_NAME 1 - {STRUCT_FLD(field_name, "NAME"), - STRUCT_FLD(field_length, NAME_LEN + 1), - STRUCT_FLD(field_type, MYSQL_TYPE_STRING), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_TABLE_FLAG 2 - {STRUCT_FLD(field_name, "FLAG"), - STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_TABLE_NUM_COLUMN 3 - {STRUCT_FLD(field_name, "N_COLS"), - STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_TABLE_SPACE 4 - {STRUCT_FLD(field_name, "SPACE"), - STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - - END_OF_ST_FIELD_INFO -}; - -/**********************************************************************//** -Populate information_schema.innodb_sys_tables table with information -from SYS_TABLES. -@return 0 on success */ -static -int -i_s_dict_fill_sys_tables( -/*=====================*/ - THD* thd, /*!< in: thread */ - dict_table_t* table, /*!< in: table */ - TABLE* table_to_fill) /*!< in/out: fill this table */ -{ - Field** fields; - - DBUG_ENTER("i_s_dict_fill_sys_tables"); - - fields = table_to_fill->field; - - OK(fields[SYS_TABLE_ID]->store(longlong(table->id), TRUE)); - - OK(field_store_string(fields[SYS_TABLE_NAME], table->name)); - - OK(fields[SYS_TABLE_FLAG]->store(table->flags)); - - OK(fields[SYS_TABLE_NUM_COLUMN]->store(table->n_cols)); - - OK(fields[SYS_TABLE_SPACE]->store(table->space)); - - OK(schema_table_store_record(thd, table_to_fill)); - - DBUG_RETURN(0); -} -/*******************************************************************//** -Function to go through each record in SYS_TABLES table, and fill the -information_schema.innodb_sys_tables table with related table information -@return 0 on success */ -static -int -i_s_sys_tables_fill_table( -/*======================*/ - THD* thd, /*!< in: thread */ - TABLE_LIST* tables, /*!< in/out: tables to fill */ - COND* cond) /*!< in: condition (not used) */ -{ - btr_pcur_t pcur; - const rec_t* rec; - mem_heap_t* heap; - mtr_t mtr; - - DBUG_ENTER("i_s_sys_tables_fill_table"); - - /* deny access to non-superusers */ - if (check_global_access(thd, PROCESS_ACL)) { - - DBUG_RETURN(0); - } - - heap = mem_heap_create(1000); - mutex_enter(&(dict_sys->mutex)); - mtr_start(&mtr); - - rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES); - - while (rec) { - const char* err_msg; - dict_table_t* table_rec; - - /* Create and populate a dict_table_t structure with - information from SYS_TABLES row */ - err_msg = dict_process_sys_tables_rec( - heap, rec, &table_rec, DICT_TABLE_LOAD_FROM_RECORD); - - mtr_commit(&mtr); - mutex_exit(&dict_sys->mutex); - - if (!err_msg) { - i_s_dict_fill_sys_tables(thd, table_rec, tables->table); - } else { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_CANT_FIND_SYSTEM_REC, - err_msg); - } - - /* Since dict_process_sys_tables_rec() is called with - DICT_TABLE_LOAD_FROM_RECORD, the table_rec is created in - dict_process_sys_tables_rec(), we will need to free it */ - if (table_rec) { - dict_mem_table_free(table_rec); - } - - mem_heap_empty(heap); - - /* Get the next record */ - mutex_enter(&dict_sys->mutex); - mtr_start(&mtr); - rec = dict_getnext_system(&pcur, &mtr); - } - - mtr_commit(&mtr); - mutex_exit(&dict_sys->mutex); - mem_heap_free(heap); - - DBUG_RETURN(0); -} - -/*******************************************************************//** -Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_tables -@return 0 on success */ -static -int -innodb_sys_tables_init( -/*===================*/ - void* p) /*!< in/out: table schema object */ -{ - ST_SCHEMA_TABLE* schema; - - DBUG_ENTER("innodb_sys_tables_init"); - - schema = (ST_SCHEMA_TABLE*) p; - - schema->fields_info = innodb_sys_tables_fields_info; - schema->fill_table = i_s_sys_tables_fill_table; - - DBUG_RETURN(0); -} - -UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_tables = -{ - /* the plugin type (a MYSQL_XXX_PLUGIN value) */ - /* int */ - STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), - - /* pointer to type-specific plugin descriptor */ - /* void* */ - STRUCT_FLD(info, &i_s_info), - - /* plugin name */ - /* const char* */ - STRUCT_FLD(name, "INNODB_SYS_TABLES"), - - /* plugin author (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(author, plugin_author), - - /* general descriptive text (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(descr, "InnoDB SYS_TABLES"), - - /* the plugin license (PLUGIN_LICENSE_XXX) */ - /* int */ - STRUCT_FLD(license, PLUGIN_LICENSE_GPL), - - /* the function to invoke when plugin is loaded */ - /* int (*)(void*); */ - STRUCT_FLD(init, innodb_sys_tables_init), - - /* the function to invoke when plugin is unloaded */ - /* int (*)(void*); */ - STRUCT_FLD(deinit, i_s_common_deinit), - - /* plugin version (for SHOW PLUGINS) */ - /* unsigned int */ - STRUCT_FLD(version, INNODB_VERSION_SHORT), - - /* struct st_mysql_show_var* */ - STRUCT_FLD(status_vars, NULL), - - /* struct st_mysql_sys_var** */ - STRUCT_FLD(system_vars, NULL), - - /* reserved for dependency checking */ - /* void* */ - STRUCT_FLD(__reserved1, NULL) -}; - -/* Fields of the dynamic table INFORMATION_SCHEMA.SYS_TABLESTATS */ -static ST_FIELD_INFO innodb_sys_tablestats_fields_info[] = -{ -#define SYS_TABLESTATS_ID 0 - {STRUCT_FLD(field_name, "TABLE_ID"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_TABLESTATS_NAME 1 - {STRUCT_FLD(field_name, "NAME"), - STRUCT_FLD(field_length, NAME_LEN + 1), - STRUCT_FLD(field_type, MYSQL_TYPE_STRING), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_TABLESTATS_INIT 2 - {STRUCT_FLD(field_name, "STATS_INITIALIZED"), - STRUCT_FLD(field_length, NAME_LEN + 1), - STRUCT_FLD(field_type, MYSQL_TYPE_STRING), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_TABLESTATS_NROW 3 - {STRUCT_FLD(field_name, "NUM_ROWS"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_TABLESTATS_CLUST_SIZE 4 - {STRUCT_FLD(field_name, "CLUST_INDEX_SIZE"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_TABLESTATS_INDEX_SIZE 5 - {STRUCT_FLD(field_name, "OTHER_INDEX_SIZE"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_TABLESTATS_MODIFIED 6 - {STRUCT_FLD(field_name, "MODIFIED_COUNTER"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_TABLESTATS_AUTONINC 7 - {STRUCT_FLD(field_name, "AUTOINC"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_TABLESTATS_MYSQL_OPEN_HANDLE 8 - {STRUCT_FLD(field_name, "MYSQL_HANDLES_OPENED"), - STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - - END_OF_ST_FIELD_INFO -}; - -/**********************************************************************//** -Populate information_schema.innodb_sys_tablestats table with information -from SYS_TABLES. -@return 0 on success */ -static -int -i_s_dict_fill_sys_tablestats( -/*=========================*/ - THD* thd, /*!< in: thread */ - dict_table_t* table, /*!< in: table */ - TABLE* table_to_fill) /*!< in/out: fill this table */ -{ - Field** fields; - - DBUG_ENTER("i_s_dict_fill_sys_tablestats"); - - fields = table_to_fill->field; - - OK(fields[SYS_TABLESTATS_ID]->store(longlong(table->id), TRUE)); - - OK(field_store_string(fields[SYS_TABLESTATS_NAME], table->name)); - - if (table->stat_initialized) { - OK(field_store_string(fields[SYS_TABLESTATS_INIT], - "Initialized")); - } else { - OK(field_store_string(fields[SYS_TABLESTATS_INIT], - "Uninitialized")); - } - - OK(fields[SYS_TABLESTATS_NROW]->store(table->stat_n_rows, TRUE)); - - OK(fields[SYS_TABLESTATS_CLUST_SIZE]->store( - table->stat_clustered_index_size)); - - OK(fields[SYS_TABLESTATS_INDEX_SIZE]->store( - table->stat_sum_of_other_index_sizes)); - - OK(fields[SYS_TABLESTATS_MODIFIED]->store( - table->stat_modified_counter)); - - OK(fields[SYS_TABLESTATS_AUTONINC]->store(table->autoinc, TRUE)); - - OK(fields[SYS_TABLESTATS_MYSQL_OPEN_HANDLE]->store( - table->n_mysql_handles_opened)); - - OK(schema_table_store_record(thd, table_to_fill)); - - DBUG_RETURN(0); -} -/*******************************************************************//** -Function to go through each record in SYS_TABLES table, and fill the -information_schema.innodb_sys_tablestats table with table statistics -related information -@return 0 on success */ -static -int -i_s_sys_tables_fill_table_stats( -/*============================*/ - THD* thd, /*!< in: thread */ - TABLE_LIST* tables, /*!< in/out: tables to fill */ - COND* cond) /*!< in: condition (not used) */ -{ - btr_pcur_t pcur; - const rec_t* rec; - mem_heap_t* heap; - mtr_t mtr; - - DBUG_ENTER("i_s_sys_tables_fill_table_stats"); - - /* deny access to non-superusers */ - if (check_global_access(thd, PROCESS_ACL)) { - - DBUG_RETURN(0); - } - - heap = mem_heap_create(1000); - mutex_enter(&dict_sys->mutex); - mtr_start(&mtr); - - rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES); - - while (rec) { - const char* err_msg; - dict_table_t* table_rec; - - /* Fetch the dict_table_t structure corresponding to - this SYS_TABLES record */ - err_msg = dict_process_sys_tables_rec( - heap, rec, &table_rec, DICT_TABLE_LOAD_FROM_CACHE); - - mtr_commit(&mtr); - mutex_exit(&dict_sys->mutex); - - if (!err_msg) { - i_s_dict_fill_sys_tablestats(thd, table_rec, - tables->table); - } else { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_CANT_FIND_SYSTEM_REC, - err_msg); - } - - mem_heap_empty(heap); - - /* Get the next record */ - mutex_enter(&dict_sys->mutex); - mtr_start(&mtr); - rec = dict_getnext_system(&pcur, &mtr); - } - - mtr_commit(&mtr); - mutex_exit(&dict_sys->mutex); - mem_heap_free(heap); - - DBUG_RETURN(0); -} - -/*******************************************************************//** -Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_tablestats -@return 0 on success */ -static -int -innodb_sys_tablestats_init( -/*=======================*/ - void* p) /*!< in/out: table schema object */ -{ - ST_SCHEMA_TABLE* schema; - - DBUG_ENTER("innodb_sys_tablestats_init"); - - schema = (ST_SCHEMA_TABLE*) p; - - schema->fields_info = innodb_sys_tablestats_fields_info; - schema->fill_table = i_s_sys_tables_fill_table_stats; - - DBUG_RETURN(0); -} - -UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_tablestats = -{ - /* the plugin type (a MYSQL_XXX_PLUGIN value) */ - /* int */ - STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), - - /* pointer to type-specific plugin descriptor */ - /* void* */ - STRUCT_FLD(info, &i_s_info), - - /* plugin name */ - /* const char* */ - STRUCT_FLD(name, "INNODB_SYS_TABLESTATS"), - - /* plugin author (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(author, plugin_author), - - /* general descriptive text (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(descr, "InnoDB SYS_TABLESTATS"), - - /* the plugin license (PLUGIN_LICENSE_XXX) */ - /* int */ - STRUCT_FLD(license, PLUGIN_LICENSE_GPL), - - /* the function to invoke when plugin is loaded */ - /* int (*)(void*); */ - STRUCT_FLD(init, innodb_sys_tablestats_init), - - /* the function to invoke when plugin is unloaded */ - /* int (*)(void*); */ - STRUCT_FLD(deinit, i_s_common_deinit), - - /* plugin version (for SHOW PLUGINS) */ - /* unsigned int */ - STRUCT_FLD(version, INNODB_VERSION_SHORT), - - /* struct st_mysql_show_var* */ - STRUCT_FLD(status_vars, NULL), - - /* struct st_mysql_sys_var** */ - STRUCT_FLD(system_vars, NULL), - - /* reserved for dependency checking */ - /* void* */ - STRUCT_FLD(__reserved1, NULL) -}; - -/* Fields of the dynamic table INFORMATION_SCHEMA.SYS_INDEXES */ -static ST_FIELD_INFO innodb_sysindex_fields_info[] = -{ -#define SYS_INDEX_ID 0 - {STRUCT_FLD(field_name, "INDEX_ID"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_INDEX_NAME 1 - {STRUCT_FLD(field_name, "NAME"), - STRUCT_FLD(field_length, NAME_LEN + 1), - STRUCT_FLD(field_type, MYSQL_TYPE_STRING), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_INDEX_TABLE_ID 2 - {STRUCT_FLD(field_name, "TABLE_ID"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_INDEX_TYPE 3 - {STRUCT_FLD(field_name, "TYPE"), - STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_INDEX_NUM_FIELDS 4 - {STRUCT_FLD(field_name, "N_FIELDS"), - STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_INDEX_PAGE_NO 5 - {STRUCT_FLD(field_name, "PAGE_NO"), - STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_INDEX_SPACE 6 - {STRUCT_FLD(field_name, "SPACE"), - STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - - END_OF_ST_FIELD_INFO -}; - -/**********************************************************************//** -Function to populate the information_schema.innodb_sys_indexes table with -collected index information -@return 0 on success */ -static -int -i_s_dict_fill_sys_indexes( -/*======================*/ - THD* thd, /*!< in: thread */ - table_id_t table_id, /*!< in: table id */ - dict_index_t* index, /*!< in: populated dict_index_t - struct with index info */ - TABLE* table_to_fill) /*!< in/out: fill this table */ -{ - Field** fields; - - DBUG_ENTER("i_s_dict_fill_sys_indexes"); - - fields = table_to_fill->field; - - OK(fields[SYS_INDEX_ID]->store(longlong(index->id), TRUE)); - - OK(field_store_string(fields[SYS_INDEX_NAME], index->name)); - - OK(fields[SYS_INDEX_TABLE_ID]->store(longlong(table_id), TRUE)); - - OK(fields[SYS_INDEX_TYPE]->store(index->type)); - - OK(fields[SYS_INDEX_NUM_FIELDS]->store(index->n_fields)); - - OK(fields[SYS_INDEX_PAGE_NO]->store(index->page)); - - OK(fields[SYS_INDEX_SPACE]->store(index->space)); - - OK(schema_table_store_record(thd, table_to_fill)); - - DBUG_RETURN(0); -} -/*******************************************************************//** -Function to go through each record in SYS_INDEXES table, and fill the -information_schema.innodb_sys_indexes table with related index information -@return 0 on success */ -static -int -i_s_sys_indexes_fill_table( -/*=======================*/ - THD* thd, /*!< in: thread */ - TABLE_LIST* tables, /*!< in/out: tables to fill */ - COND* cond) /*!< in: condition (not used) */ -{ - btr_pcur_t pcur; - const rec_t* rec; - mem_heap_t* heap; - mtr_t mtr; - - DBUG_ENTER("i_s_sys_indexes_fill_table"); - - /* deny access to non-superusers */ - if (check_global_access(thd, PROCESS_ACL)) { - - DBUG_RETURN(0); - } - - heap = mem_heap_create(1000); - mutex_enter(&dict_sys->mutex); - mtr_start(&mtr); - - /* Start scan the SYS_INDEXES table */ - rec = dict_startscan_system(&pcur, &mtr, SYS_INDEXES); - - /* Process each record in the table */ - while (rec) { - const char* err_msg;; - table_id_t table_id; - dict_index_t index_rec; - - /* Populate a dict_index_t structure with information from - a SYS_INDEXES row */ - err_msg = dict_process_sys_indexes_rec(heap, rec, &index_rec, - &table_id); - - mtr_commit(&mtr); - mutex_exit(&dict_sys->mutex); - - if (!err_msg) { - i_s_dict_fill_sys_indexes(thd, table_id, &index_rec, - tables->table); - } else { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_CANT_FIND_SYSTEM_REC, - err_msg); - } - - mem_heap_empty(heap); - - /* Get the next record */ - mutex_enter(&dict_sys->mutex); - mtr_start(&mtr); - rec = dict_getnext_system(&pcur, &mtr); - } - - mtr_commit(&mtr); - mutex_exit(&dict_sys->mutex); - mem_heap_free(heap); - - DBUG_RETURN(0); -} -/*******************************************************************//** -Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_indexes -@return 0 on success */ -static -int -innodb_sys_indexes_init( -/*====================*/ - void* p) /*!< in/out: table schema object */ -{ - ST_SCHEMA_TABLE* schema; - - DBUG_ENTER("innodb_sys_index_init"); - - schema = (ST_SCHEMA_TABLE*) p; - - schema->fields_info = innodb_sysindex_fields_info; - schema->fill_table = i_s_sys_indexes_fill_table; - - DBUG_RETURN(0); -} - -UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_indexes = -{ - /* the plugin type (a MYSQL_XXX_PLUGIN value) */ - /* int */ - STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), - - /* pointer to type-specific plugin descriptor */ - /* void* */ - STRUCT_FLD(info, &i_s_info), - - /* plugin name */ - /* const char* */ - STRUCT_FLD(name, "INNODB_SYS_INDEXES"), - - /* plugin author (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(author, plugin_author), - - /* general descriptive text (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(descr, "InnoDB SYS_INDEXES"), - - /* the plugin license (PLUGIN_LICENSE_XXX) */ - /* int */ - STRUCT_FLD(license, PLUGIN_LICENSE_GPL), - - /* the function to invoke when plugin is loaded */ - /* int (*)(void*); */ - STRUCT_FLD(init, innodb_sys_indexes_init), - - /* the function to invoke when plugin is unloaded */ - /* int (*)(void*); */ - STRUCT_FLD(deinit, i_s_common_deinit), - - /* plugin version (for SHOW PLUGINS) */ - /* unsigned int */ - STRUCT_FLD(version, INNODB_VERSION_SHORT), - - /* struct st_mysql_show_var* */ - STRUCT_FLD(status_vars, NULL), - - /* struct st_mysql_sys_var** */ - STRUCT_FLD(system_vars, NULL), - - /* reserved for dependency checking */ - /* void* */ - STRUCT_FLD(__reserved1, NULL) -}; - -/* Fields of the dynamic table INFORMATION_SCHEMA.SYS_COLUMNS */ -static ST_FIELD_INFO innodb_sys_columns_fields_info[] = -{ -#define SYS_COLUMN_TABLE_ID 0 - {STRUCT_FLD(field_name, "TABLE_ID"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_COLUMN_NAME 1 - {STRUCT_FLD(field_name, "NAME"), - STRUCT_FLD(field_length, NAME_LEN + 1), - STRUCT_FLD(field_type, MYSQL_TYPE_STRING), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_COLUMN_POSITION 2 - {STRUCT_FLD(field_name, "POS"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_COLUMN_MTYPE 3 - {STRUCT_FLD(field_name, "MTYPE"), - STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_COLUMN__PRTYPE 4 - {STRUCT_FLD(field_name, "PRTYPE"), - STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_COLUMN_COLUMN_LEN 5 - {STRUCT_FLD(field_name, "LEN"), - STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - - END_OF_ST_FIELD_INFO -}; - -/**********************************************************************//** -Function to populate the information_schema.innodb_sys_columns with -related column information -@return 0 on success */ -static -int -i_s_dict_fill_sys_columns( -/*======================*/ - THD* thd, /*!< in: thread */ - table_id_t table_id, /*!< in: table ID */ - const char* col_name, /*!< in: column name */ - dict_col_t* column, /*!< in: dict_col_t struct holding - more column information */ - TABLE* table_to_fill) /*!< in/out: fill this table */ -{ - Field** fields; - - DBUG_ENTER("i_s_dict_fill_sys_columns"); - - fields = table_to_fill->field; - - OK(fields[SYS_COLUMN_TABLE_ID]->store(longlong(table_id), TRUE)); - - OK(field_store_string(fields[SYS_COLUMN_NAME], col_name)); - - OK(fields[SYS_COLUMN_POSITION]->store(column->ind)); - - OK(fields[SYS_COLUMN_MTYPE]->store(column->mtype)); - - OK(fields[SYS_COLUMN__PRTYPE]->store(column->prtype)); - - OK(fields[SYS_COLUMN_COLUMN_LEN]->store(column->len)); - - OK(schema_table_store_record(thd, table_to_fill)); - - DBUG_RETURN(0); -} -/*******************************************************************//** -Function to fill information_schema.innodb_sys_columns with information -collected by scanning SYS_COLUMNS table. -@return 0 on success */ -static -int -i_s_sys_columns_fill_table( -/*=======================*/ - THD* thd, /*!< in: thread */ - TABLE_LIST* tables, /*!< in/out: tables to fill */ - COND* cond) /*!< in: condition (not used) */ -{ - btr_pcur_t pcur; - const rec_t* rec; - const char* col_name; - mem_heap_t* heap; - mtr_t mtr; - - DBUG_ENTER("i_s_sys_columns_fill_table"); - - /* deny access to non-superusers */ - if (check_global_access(thd, PROCESS_ACL)) { - - DBUG_RETURN(0); - } - - heap = mem_heap_create(1000); - mutex_enter(&dict_sys->mutex); - mtr_start(&mtr); - - rec = dict_startscan_system(&pcur, &mtr, SYS_COLUMNS); - - while (rec) { - const char* err_msg; - dict_col_t column_rec; - table_id_t table_id; - - /* populate a dict_col_t structure with information from - a SYS_COLUMNS row */ - err_msg = dict_process_sys_columns_rec(heap, rec, &column_rec, - &table_id, &col_name); - - mtr_commit(&mtr); - mutex_exit(&dict_sys->mutex); - - if (!err_msg) { - i_s_dict_fill_sys_columns(thd, table_id, col_name, - &column_rec, - tables->table); - } else { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_CANT_FIND_SYSTEM_REC, - err_msg); - } - - mem_heap_empty(heap); - - /* Get the next record */ - mutex_enter(&dict_sys->mutex); - mtr_start(&mtr); - rec = dict_getnext_system(&pcur, &mtr); - } - - mtr_commit(&mtr); - mutex_exit(&dict_sys->mutex); - mem_heap_free(heap); - - DBUG_RETURN(0); -} -/*******************************************************************//** -Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_columns -@return 0 on success */ -static -int -innodb_sys_columns_init( -/*====================*/ - void* p) /*!< in/out: table schema object */ -{ - ST_SCHEMA_TABLE* schema; - - DBUG_ENTER("innodb_sys_columns_init"); - - schema = (ST_SCHEMA_TABLE*) p; - - schema->fields_info = innodb_sys_columns_fields_info; - schema->fill_table = i_s_sys_columns_fill_table; - - DBUG_RETURN(0); -} - -UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_columns = -{ - /* the plugin type (a MYSQL_XXX_PLUGIN value) */ - /* int */ - STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), - - /* pointer to type-specific plugin descriptor */ - /* void* */ - STRUCT_FLD(info, &i_s_info), - - /* plugin name */ - /* const char* */ - STRUCT_FLD(name, "INNODB_SYS_COLUMNS"), - - /* plugin author (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(author, plugin_author), - - /* general descriptive text (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(descr, "InnoDB SYS_COLUMNS"), - - /* the plugin license (PLUGIN_LICENSE_XXX) */ - /* int */ - STRUCT_FLD(license, PLUGIN_LICENSE_GPL), - - /* the function to invoke when plugin is loaded */ - /* int (*)(void*); */ - STRUCT_FLD(init, innodb_sys_columns_init), - - /* the function to invoke when plugin is unloaded */ - /* int (*)(void*); */ - STRUCT_FLD(deinit, i_s_common_deinit), - - /* plugin version (for SHOW PLUGINS) */ - /* unsigned int */ - STRUCT_FLD(version, INNODB_VERSION_SHORT), - - /* struct st_mysql_show_var* */ - STRUCT_FLD(status_vars, NULL), - - /* struct st_mysql_sys_var** */ - STRUCT_FLD(system_vars, NULL), - - /* reserved for dependency checking */ - /* void* */ - STRUCT_FLD(__reserved1, NULL) -}; -/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_sys_fields */ -static ST_FIELD_INFO innodb_sys_fields_fields_info[] = -{ -#define SYS_FIELD_INDEX_ID 0 - {STRUCT_FLD(field_name, "INDEX_ID"), - STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_FIELD_NAME 1 - {STRUCT_FLD(field_name, "NAME"), - STRUCT_FLD(field_length, NAME_LEN + 1), - STRUCT_FLD(field_type, MYSQL_TYPE_STRING), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_FIELD_POS 2 - {STRUCT_FLD(field_name, "POS"), - STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - - END_OF_ST_FIELD_INFO -}; - -/**********************************************************************//** -Function to fill information_schema.innodb_sys_fields with information -collected by scanning SYS_FIELDS table. -@return 0 on success */ -static -int -i_s_dict_fill_sys_fields( -/*=====================*/ - THD* thd, /*!< in: thread */ - index_id_t index_id, /*!< in: index id for the field */ - dict_field_t* field, /*!< in: table */ - ulint pos, /*!< in: Field position */ - TABLE* table_to_fill) /*!< in/out: fill this table */ -{ - Field** fields; - - DBUG_ENTER("i_s_dict_fill_sys_fields"); - - fields = table_to_fill->field; - - OK(fields[SYS_FIELD_INDEX_ID]->store(longlong(index_id), TRUE)); - - OK(field_store_string(fields[SYS_FIELD_NAME], field->name)); - - OK(fields[SYS_FIELD_POS]->store(pos)); - - OK(schema_table_store_record(thd, table_to_fill)); - - DBUG_RETURN(0); -} -/*******************************************************************//** -Function to go through each record in SYS_FIELDS table, and fill the -information_schema.innodb_sys_fields table with related index field -information -@return 0 on success */ -static -int -i_s_sys_fields_fill_table( -/*======================*/ - THD* thd, /*!< in: thread */ - TABLE_LIST* tables, /*!< in/out: tables to fill */ - COND* cond) /*!< in: condition (not used) */ -{ - btr_pcur_t pcur; - const rec_t* rec; - mem_heap_t* heap; - index_id_t last_id; - mtr_t mtr; - - DBUG_ENTER("i_s_sys_fields_fill_table"); - - /* deny access to non-superusers */ - if (check_global_access(thd, PROCESS_ACL)) { - - DBUG_RETURN(0); - } - - heap = mem_heap_create(1000); - mutex_enter(&dict_sys->mutex); - mtr_start(&mtr); - - /* will save last index id so that we know whether we move to - the next index. This is used to calculate prefix length */ - last_id = 0; - - rec = dict_startscan_system(&pcur, &mtr, SYS_FIELDS); - - while (rec) { - ulint pos; - const char* err_msg; - index_id_t index_id; - dict_field_t field_rec; - - /* Populate a dict_field_t structure with information from - a SYS_FIELDS row */ - err_msg = dict_process_sys_fields_rec(heap, rec, &field_rec, - &pos, &index_id, last_id); - - mtr_commit(&mtr); - mutex_exit(&dict_sys->mutex); - - if (!err_msg) { - i_s_dict_fill_sys_fields(thd, index_id, &field_rec, - pos, tables->table); - last_id = index_id; - } else { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_CANT_FIND_SYSTEM_REC, - err_msg); - } - - mem_heap_empty(heap); - - /* Get the next record */ - mutex_enter(&dict_sys->mutex); - mtr_start(&mtr); - rec = dict_getnext_system(&pcur, &mtr); - } - - mtr_commit(&mtr); - mutex_exit(&dict_sys->mutex); - mem_heap_free(heap); - - DBUG_RETURN(0); -} -/*******************************************************************//** -Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_fields -@return 0 on success */ -static -int -innodb_sys_fields_init( -/*===================*/ - void* p) /*!< in/out: table schema object */ -{ - ST_SCHEMA_TABLE* schema; - - DBUG_ENTER("innodb_sys_field_init"); - - schema = (ST_SCHEMA_TABLE*) p; - - schema->fields_info = innodb_sys_fields_fields_info; - schema->fill_table = i_s_sys_fields_fill_table; - - DBUG_RETURN(0); -} - -UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_fields = -{ - /* the plugin type (a MYSQL_XXX_PLUGIN value) */ - /* int */ - STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), - - /* pointer to type-specific plugin descriptor */ - /* void* */ - STRUCT_FLD(info, &i_s_info), - - /* plugin name */ - /* const char* */ - STRUCT_FLD(name, "INNODB_SYS_FIELDS"), - - /* plugin author (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(author, plugin_author), - - /* general descriptive text (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(descr, "InnoDB SYS_FIELDS"), - - /* the plugin license (PLUGIN_LICENSE_XXX) */ - /* int */ - STRUCT_FLD(license, PLUGIN_LICENSE_GPL), - - /* the function to invoke when plugin is loaded */ - /* int (*)(void*); */ - STRUCT_FLD(init, innodb_sys_fields_init), - - /* the function to invoke when plugin is unloaded */ - /* int (*)(void*); */ - STRUCT_FLD(deinit, i_s_common_deinit), - - /* plugin version (for SHOW PLUGINS) */ - /* unsigned int */ - STRUCT_FLD(version, INNODB_VERSION_SHORT), - - /* struct st_mysql_show_var* */ - STRUCT_FLD(status_vars, NULL), - - /* struct st_mysql_sys_var** */ - STRUCT_FLD(system_vars, NULL), - - /* reserved for dependency checking */ - /* void* */ - STRUCT_FLD(__reserved1, NULL) -}; - -/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_sys_foreign */ -static ST_FIELD_INFO innodb_sys_foreign_fields_info[] = -{ -#define SYS_FOREIGN_ID 0 - {STRUCT_FLD(field_name, "ID"), - STRUCT_FLD(field_length, NAME_LEN + 1), - STRUCT_FLD(field_type, MYSQL_TYPE_STRING), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_FOREIGN_FOR_NAME 1 - {STRUCT_FLD(field_name, "FOR_NAME"), - STRUCT_FLD(field_length, NAME_LEN + 1), - STRUCT_FLD(field_type, MYSQL_TYPE_STRING), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_FOREIGN_REF_NAME 2 - {STRUCT_FLD(field_name, "REF_NAME"), - STRUCT_FLD(field_length, NAME_LEN + 1), - STRUCT_FLD(field_type, MYSQL_TYPE_STRING), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_FOREIGN_NUM_COL 3 - {STRUCT_FLD(field_name, "N_COLS"), - STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_FOREIGN_TYPE 4 - {STRUCT_FLD(field_name, "TYPE"), - STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - - END_OF_ST_FIELD_INFO -}; - -/**********************************************************************//** -Function to fill information_schema.innodb_sys_foreign with information -collected by scanning SYS_FOREIGN table. -@return 0 on success */ -static -int -i_s_dict_fill_sys_foreign( -/*======================*/ - THD* thd, /*!< in: thread */ - dict_foreign_t* foreign, /*!< in: table */ - TABLE* table_to_fill) /*!< in/out: fill this table */ -{ - Field** fields; - - DBUG_ENTER("i_s_dict_fill_sys_foreign"); - - fields = table_to_fill->field; - - OK(field_store_string(fields[SYS_FOREIGN_ID], foreign->id)); - - OK(field_store_string(fields[SYS_FOREIGN_FOR_NAME], - foreign->foreign_table_name)); - - OK(field_store_string(fields[SYS_FOREIGN_REF_NAME], - foreign->referenced_table_name)); - - OK(fields[SYS_FOREIGN_NUM_COL]->store(foreign->n_fields)); - - OK(fields[SYS_FOREIGN_TYPE]->store(foreign->type)); - - OK(schema_table_store_record(thd, table_to_fill)); - - DBUG_RETURN(0); -} -/*******************************************************************//** -Function to populate INFORMATION_SCHEMA.innodb_sys_foreign table. Loop -through each record in SYS_FOREIGN, and extract the foreign key -information. -@return 0 on success */ -static -int -i_s_sys_foreign_fill_table( -/*=======================*/ - THD* thd, /*!< in: thread */ - TABLE_LIST* tables, /*!< in/out: tables to fill */ - COND* cond) /*!< in: condition (not used) */ -{ - btr_pcur_t pcur; - const rec_t* rec; - mem_heap_t* heap; - mtr_t mtr; - - DBUG_ENTER("i_s_sys_foreign_fill_table"); - - /* deny access to non-superusers */ - if (check_global_access(thd, PROCESS_ACL)) { - - DBUG_RETURN(0); - } - - heap = mem_heap_create(1000); - mutex_enter(&dict_sys->mutex); - mtr_start(&mtr); - - rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN); - - while (rec) { - const char* err_msg; - dict_foreign_t foreign_rec; - - /* Populate a dict_foreign_t structure with information from - a SYS_FOREIGN row */ - err_msg = dict_process_sys_foreign_rec(heap, rec, &foreign_rec); - - mtr_commit(&mtr); - mutex_exit(&dict_sys->mutex); - - if (!err_msg) { - i_s_dict_fill_sys_foreign(thd, &foreign_rec, - tables->table); - } else { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_CANT_FIND_SYSTEM_REC, - err_msg); - } - - mem_heap_empty(heap); - - /* Get the next record */ - mtr_start(&mtr); - mutex_enter(&dict_sys->mutex); - rec = dict_getnext_system(&pcur, &mtr); - } - - mtr_commit(&mtr); - mutex_exit(&dict_sys->mutex); - mem_heap_free(heap); - - DBUG_RETURN(0); -} -/*******************************************************************//** -Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_foreign -@return 0 on success */ -static -int -innodb_sys_foreign_init( -/*====================*/ - void* p) /*!< in/out: table schema object */ -{ - ST_SCHEMA_TABLE* schema; - - DBUG_ENTER("innodb_sys_foreign_init"); - - schema = (ST_SCHEMA_TABLE*) p; - - schema->fields_info = innodb_sys_foreign_fields_info; - schema->fill_table = i_s_sys_foreign_fill_table; - - DBUG_RETURN(0); -} - -UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_foreign = -{ - /* the plugin type (a MYSQL_XXX_PLUGIN value) */ - /* int */ - STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), - - /* pointer to type-specific plugin descriptor */ - /* void* */ - STRUCT_FLD(info, &i_s_info), - - /* plugin name */ - /* const char* */ - STRUCT_FLD(name, "INNODB_SYS_FOREIGN"), - - /* plugin author (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(author, plugin_author), - - /* general descriptive text (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(descr, "InnoDB SYS_FOREIGN"), - - /* the plugin license (PLUGIN_LICENSE_XXX) */ - /* int */ - STRUCT_FLD(license, PLUGIN_LICENSE_GPL), - - /* the function to invoke when plugin is loaded */ - /* int (*)(void*); */ - STRUCT_FLD(init, innodb_sys_foreign_init), - - /* the function to invoke when plugin is unloaded */ - /* int (*)(void*); */ - STRUCT_FLD(deinit, i_s_common_deinit), - - /* plugin version (for SHOW PLUGINS) */ - /* unsigned int */ - STRUCT_FLD(version, INNODB_VERSION_SHORT), - - /* struct st_mysql_show_var* */ - STRUCT_FLD(status_vars, NULL), - - /* struct st_mysql_sys_var** */ - STRUCT_FLD(system_vars, NULL), - - /* reserved for dependency checking */ - /* void* */ - STRUCT_FLD(__reserved1, NULL) -}; -/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_sys_foreign_cols */ -static ST_FIELD_INFO innodb_sys_foreign_cols_fields_info[] = -{ -#define SYS_FOREIGN_COL_ID 0 - {STRUCT_FLD(field_name, "ID"), - STRUCT_FLD(field_length, NAME_LEN + 1), - STRUCT_FLD(field_type, MYSQL_TYPE_STRING), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_FOREIGN_COL_FOR_NAME 1 - {STRUCT_FLD(field_name, "FOR_COL_NAME"), - STRUCT_FLD(field_length, NAME_LEN + 1), - STRUCT_FLD(field_type, MYSQL_TYPE_STRING), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_FOREIGN_COL_REF_NAME 2 - {STRUCT_FLD(field_name, "REF_COL_NAME"), - STRUCT_FLD(field_length, NAME_LEN + 1), - STRUCT_FLD(field_type, MYSQL_TYPE_STRING), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, 0), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - -#define SYS_FOREIGN_COL_POS 3 - {STRUCT_FLD(field_name, "POS"), - STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS), - STRUCT_FLD(field_type, MYSQL_TYPE_LONG), - STRUCT_FLD(value, 0), - STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), - STRUCT_FLD(old_name, ""), - STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, - - END_OF_ST_FIELD_INFO -}; - -/**********************************************************************//** -Function to fill information_schema.innodb_sys_foreign_cols with information -collected by scanning SYS_FOREIGN_COLS table. -@return 0 on success */ -static -int -i_s_dict_fill_sys_foreign_cols( -/*==========================*/ - THD* thd, /*!< in: thread */ - const char* name, /*!< in: foreign key constraint name */ - const char* for_col_name, /*!< in: referencing column name*/ - const char* ref_col_name, /*!< in: referenced column - name */ - ulint pos, /*!< in: column position */ - TABLE* table_to_fill) /*!< in/out: fill this table */ -{ - Field** fields; - - DBUG_ENTER("i_s_dict_fill_sys_foreign_cols"); - - fields = table_to_fill->field; - - OK(field_store_string(fields[SYS_FOREIGN_COL_ID], name)); - - OK(field_store_string(fields[SYS_FOREIGN_COL_FOR_NAME], for_col_name)); - - OK(field_store_string(fields[SYS_FOREIGN_COL_REF_NAME], ref_col_name)); - - OK(fields[SYS_FOREIGN_COL_POS]->store(pos)); - - OK(schema_table_store_record(thd, table_to_fill)); - - DBUG_RETURN(0); -} -/*******************************************************************//** -Function to populate INFORMATION_SCHEMA.innodb_sys_foreign_cols table. Loop -through each record in SYS_FOREIGN_COLS, and extract the foreign key column -information and fill the INFORMATION_SCHEMA.innodb_sys_foreign_cols table. -@return 0 on success */ -static -int -i_s_sys_foreign_cols_fill_table( -/*============================*/ - THD* thd, /*!< in: thread */ - TABLE_LIST* tables, /*!< in/out: tables to fill */ - COND* cond) /*!< in: condition (not used) */ -{ - btr_pcur_t pcur; - const rec_t* rec; - mem_heap_t* heap; - mtr_t mtr; - - DBUG_ENTER("i_s_sys_foreign_cols_fill_table"); - - /* deny access to non-superusers */ - if (check_global_access(thd, PROCESS_ACL)) { - DBUG_RETURN(0); - } - - heap = mem_heap_create(1000); - mutex_enter(&dict_sys->mutex); - mtr_start(&mtr); - - rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN_COLS); - - while (rec) { - const char* err_msg; - const char* name; - const char* for_col_name; - const char* ref_col_name; - ulint pos; - - /* Extract necessary information from a SYS_FOREIGN_COLS row */ - err_msg = dict_process_sys_foreign_col_rec( - heap, rec, &name, &for_col_name, &ref_col_name, &pos); - - mtr_commit(&mtr); - mutex_exit(&dict_sys->mutex); - - if (!err_msg) { - i_s_dict_fill_sys_foreign_cols( - thd, name, for_col_name, ref_col_name, pos, - tables->table); - } else { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_CANT_FIND_SYSTEM_REC, - err_msg); - } - - mem_heap_empty(heap); - - /* Get the next record */ - mutex_enter(&dict_sys->mutex); - mtr_start(&mtr); - rec = dict_getnext_system(&pcur, &mtr); - } - - mtr_commit(&mtr); - mutex_exit(&dict_sys->mutex); - mem_heap_free(heap); - - DBUG_RETURN(0); -} -/*******************************************************************//** -Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_foreign_cols -@return 0 on success */ -static -int -innodb_sys_foreign_cols_init( -/*========================*/ - void* p) /*!< in/out: table schema object */ -{ - ST_SCHEMA_TABLE* schema; - - DBUG_ENTER("innodb_sys_foreign_cols_init"); - - schema = (ST_SCHEMA_TABLE*) p; - - schema->fields_info = innodb_sys_foreign_cols_fields_info; - schema->fill_table = i_s_sys_foreign_cols_fill_table; - - DBUG_RETURN(0); -} - -UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_foreign_cols = -{ - /* the plugin type (a MYSQL_XXX_PLUGIN value) */ - /* int */ - STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), - - /* pointer to type-specific plugin descriptor */ - /* void* */ - STRUCT_FLD(info, &i_s_info), - - /* plugin name */ - /* const char* */ - STRUCT_FLD(name, "INNODB_SYS_FOREIGN_COLS"), - - /* plugin author (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(author, plugin_author), - - /* general descriptive text (for SHOW PLUGINS) */ - /* const char* */ - STRUCT_FLD(descr, "InnoDB SYS_FOREIGN_COLS"), - - /* the plugin license (PLUGIN_LICENSE_XXX) */ - /* int */ - STRUCT_FLD(license, PLUGIN_LICENSE_GPL), - - /* the function to invoke when plugin is loaded */ - /* int (*)(void*); */ - STRUCT_FLD(init, innodb_sys_foreign_cols_init), - - /* the function to invoke when plugin is unloaded */ - /* int (*)(void*); */ - STRUCT_FLD(deinit, i_s_common_deinit), - - /* plugin version (for SHOW PLUGINS) */ - /* unsigned int */ - STRUCT_FLD(version, INNODB_VERSION_SHORT), - - /* struct st_mysql_show_var* */ - STRUCT_FLD(status_vars, NULL), - - /* struct st_mysql_sys_var** */ - STRUCT_FLD(system_vars, NULL), - - /* reserved for dependency checking */ - /* void* */ - STRUCT_FLD(__reserved1, NULL) -}; - diff --git a/storage/innobase/handler/i_s.h b/storage/innobase/handler/i_s.h index 69f5ed9dad8..402c88bbedb 100644 --- a/storage/innobase/handler/i_s.h +++ b/storage/innobase/handler/i_s.h @@ -33,12 +33,5 @@ extern struct st_mysql_plugin i_s_innodb_cmp; extern struct st_mysql_plugin i_s_innodb_cmp_reset; extern struct st_mysql_plugin i_s_innodb_cmpmem; extern struct st_mysql_plugin i_s_innodb_cmpmem_reset; -extern struct st_mysql_plugin i_s_innodb_sys_tables; -extern struct st_mysql_plugin i_s_innodb_sys_tablestats; -extern struct st_mysql_plugin i_s_innodb_sys_indexes; -extern struct st_mysql_plugin i_s_innodb_sys_columns; -extern struct st_mysql_plugin i_s_innodb_sys_fields; -extern struct st_mysql_plugin i_s_innodb_sys_foreign; -extern struct st_mysql_plugin i_s_innodb_sys_foreign_cols; #endif /* i_s_h */ From bf89d475169870f24fc2e31b329b28e73981bd66 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Mon, 20 Sep 2010 10:12:39 +0200 Subject: [PATCH 084/159] Bug #56787 MTR completion report should be more informative Added counts of skipped test, inclusing how many by test itself Also fixed misspelling in the (hitherto unused) variable name --- mysql-test/lib/mtr_report.pm | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index 77f6920771d..af75178473d 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -229,7 +229,8 @@ sub mtr_report_stats ($$;$) { # Find out how we where doing # ---------------------------------------------------------------------- - my $tot_skiped= 0; + my $tot_skipped= 0; + my $tot_skipdetect= 0; my $tot_passed= 0; my $tot_failed= 0; my $tot_tests= 0; @@ -246,8 +247,9 @@ sub mtr_report_stats ($$;$) { } elsif ( $tinfo->{'result'} eq 'MTR_RES_SKIPPED' ) { - # Test was skipped - $tot_skiped++; + # Test was skipped (disabled not counted) + $tot_skipped++ unless $tinfo->{'disable'}; + $tot_skipdetect++ if $tinfo->{'skip_detected_by_test'}; } elsif ( $tinfo->{'result'} eq 'MTR_RES_PASSED' ) { @@ -376,6 +378,9 @@ sub mtr_report_stats ($$;$) { print "All $tot_tests tests were successful.\n\n"; } + print "$tot_skipped tests were skipped, ". + "$tot_skipdetect by the test itself.\n\n" if $tot_skipped; + if ( $tot_failed != 0 || $found_problems) { mtr_error("there were failing test cases") unless $dont_error; From 4237920a40659c4f26711ee09f098b254fc411ff Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Mon, 20 Sep 2010 10:21:55 +0200 Subject: [PATCH 085/159] small test fix after 56753 --- mysql-test/suite/sys_vars/t/div_precision_increment_func.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/sys_vars/t/div_precision_increment_func.test b/mysql-test/suite/sys_vars/t/div_precision_increment_func.test index 1c2cbfc24e9..472b6469f42 100644 --- a/mysql-test/suite/sys_vars/t/div_precision_increment_func.test +++ b/mysql-test/suite/sys_vars/t/div_precision_increment_func.test @@ -19,7 +19,7 @@ # # ################################################################################ -let $save_div_precision_increment = `SELECT @@global.div_precision_increment` +let $save_div_precision_increment = `SELECT @@global.div_precision_increment`; #SET @save_div_precision_increment = @@global.div_precision_increment; From c18a34bda6f16521f9c3f9c43579af70d1c7a22f Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Mon, 20 Sep 2010 11:21:27 +0200 Subject: [PATCH 086/159] Bug #55426 mysqltest crashes when trying to unlock not acquired mutex Follow-up: don't call pthread_join() on Windows This change only valid for 5.1 --- client/mysqltest.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index a84ad2ad9e8..08375e4a576 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -763,7 +763,10 @@ static void wait_query_thread_end(struct st_connection *con) } if (con->has_thread) { +#ifndef __WIN__ + /* May hang on Windows, but the problem it solves is not seen there */ pthread_join(con->tid, NULL); +#endif con->has_thread= FALSE; } } From fe55bb00541db71118eb90d5c643f92fb9544e7f Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 15:31:34 +0300 Subject: [PATCH 087/159] Increment InnoDB version from 1.1.2 to 1.1.3 InnoDB 1.1.2 was released with MySQL 5.5.6-rc --- storage/innobase/include/univ.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index 748070efa02..1e8e60fea52 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -46,7 +46,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_MAJOR 1 #define INNODB_VERSION_MINOR 1 -#define INNODB_VERSION_BUGFIX 2 +#define INNODB_VERSION_BUGFIX 3 /* The following is the InnoDB version as shown in SELECT plugin_version FROM information_schema.plugins; From f043b952627e4c8538be10cd27aa1ca39fe24844 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 15:50:34 +0300 Subject: [PATCH 088/159] Whitespace fixup on ha_innodb.cc:1274 --- storage/innobase/handler/ha_innodb.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 7a5608bd95c..bf9056e470f 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1271,7 +1271,7 @@ innobase_mysql_tmpfile(void) #ifdef _WIN32 /* Note that on Windows, the integer returned by mysql_tmpfile - has no relation to C runtime file descriptor. Here, we need + has no relation to C runtime file descriptor. Here, we need to call my_get_osfhandle to get the HANDLE and then convert it to C runtime filedescriptor. */ { From aad1419981afb8ce831162ec71839cdcea30a189 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 17:14:21 +0300 Subject: [PATCH 089/159] Whitespace fixup on ha_innodb.cc:2612 --- storage/innobase/handler/ha_innodb.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index bf9056e470f..a55bd4120c7 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2609,7 +2609,7 @@ static int innobase_commit( /*============*/ - handlerton *hton, /*!< in: Innodb handlerton */ + handlerton *hton, /*!< in: Innodb handlerton */ THD* thd, /*!< in: MySQL thread handle of the user for whom the transaction should be committed */ bool all) /*!< in: TRUE - commit transaction From c37573590dfdf6c944b097b802f68e151f9d7327 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 17:59:59 +0300 Subject: [PATCH 090/159] (btr0btr.c:606) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/btr/btr0btr.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c index f8638af2e71..5c0f9e4c610 100644 --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c @@ -603,7 +603,6 @@ btr_page_get_father_node_ptr_func( ulint line, /*!< in: line where called */ mtr_t* mtr) /*!< in: mtr */ { - page_t* page; dtuple_t* tuple; rec_t* user_rec; rec_t* node_ptr; @@ -621,7 +620,6 @@ btr_page_get_father_node_ptr_func( level = btr_page_get_level(btr_cur_get_page(cursor), mtr); - page = btr_cur_get_page(cursor); user_rec = btr_cur_get_rec(cursor); ut_a(page_rec_is_user_rec(user_rec)); tuple = dict_index_build_node_ptr(index, user_rec, 0, heap, level); From ab8cec7774ecb4afd76784db00029b06315a6fa7 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 18:16:19 +0300 Subject: [PATCH 091/159] (btr0btr.c:1900) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/btr/btr0btr.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c index 5c0f9e4c610..0ec82a3cc81 100644 --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c @@ -1897,7 +1897,6 @@ btr_page_split_and_insert( buf_block_t* left_block; buf_block_t* right_block; buf_block_t* insert_block; - page_t* insert_page; page_cur_t* page_cursor; rec_t* first_rec; byte* buf = 0; /* remove warning */ @@ -2155,8 +2154,6 @@ insert_empty: insert_block = right_block; } - insert_page = buf_block_get_frame(insert_block); - /* 7. Reposition the cursor for insert and try insertion */ page_cursor = btr_cur_get_page_cur(cursor); @@ -2168,8 +2165,12 @@ insert_empty: #ifdef UNIV_ZIP_DEBUG { + page_t* insert_page + = buf_block_get_frame(insert_block); + page_zip_des_t* insert_page_zip = buf_block_get_page_zip(insert_block); + ut_a(!insert_page_zip || page_zip_validate(insert_page_zip, insert_page)); } From 17d69471803087a9a8c5e05894ae186c1001044d Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 18:31:58 +0300 Subject: [PATCH 092/159] (btr0btr.c:2566) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/btr/btr0btr.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c index 0ec82a3cc81..06cfdf5a798 100644 --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c @@ -2563,7 +2563,6 @@ btr_compress( ulint n_recs; ulint max_ins_size; ulint max_ins_size_reorg; - ulint level; block = btr_cur_get_block(cursor); page = btr_cur_get_page(cursor); @@ -2573,7 +2572,6 @@ btr_compress( ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index), MTR_MEMO_X_LOCK)); ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); - level = btr_page_get_level(page, mtr); space = dict_index_get_space(index); zip_size = dict_table_zip_size(index->table); From 530a8c6f35585eb9b5366f2fc1d395b2917094b6 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 18:33:39 +0300 Subject: [PATCH 093/159] (btr0cur.c:1957) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/btr/btr0cur.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c index 2549589b0c7..fa71a0b12fa 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -1954,7 +1954,6 @@ btr_cur_optimistic_update( page_t* page; page_zip_des_t* page_zip; rec_t* rec; - rec_t* orig_rec; ulint max_size; ulint new_rec_size; ulint old_rec_size; @@ -1968,7 +1967,7 @@ btr_cur_optimistic_update( block = btr_cur_get_block(cursor); page = buf_block_get_frame(block); - orig_rec = rec = btr_cur_get_rec(cursor); + rec = btr_cur_get_rec(cursor); index = cursor->index; ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table)); ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); From dd7989d2b4375982bc1a5fa37eb6ae01fe848f8a Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 18:38:43 +0300 Subject: [PATCH 094/159] (btr0cur.c:4559) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/btr/btr0cur.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c index fa71a0b12fa..8955c483f6e 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -4556,17 +4556,20 @@ btr_free_externally_stored_field( } for (;;) { +#ifdef UNIV_SYNC_DEBUG buf_block_t* rec_block; +#endif /* UNIV_SYNC_DEBUG */ buf_block_t* ext_block; mtr_start(&mtr); - rec_block = buf_page_get(page_get_space_id( - page_align(field_ref)), - rec_zip_size, - page_get_page_no( - page_align(field_ref)), - RW_X_LATCH, &mtr); +#ifdef UNIV_SYNC_DEBUG + rec_block = +#endif /* UNIV_SYNC_DEBUG */ + buf_page_get(page_get_space_id(page_align(field_ref)), + rec_zip_size, + page_get_page_no(page_align(field_ref)), + RW_X_LATCH, &mtr); buf_block_dbg_add_level(rec_block, SYNC_NO_ORDER_CHECK); page_no = mach_read_from_4(field_ref + BTR_EXTERN_PAGE_NO); From 633971d4641d0b74aa01ed0aa26260a32b245589 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 18:42:13 +0300 Subject: [PATCH 095/159] (btr0pcur.c:455) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/btr/btr0pcur.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innobase/btr/btr0pcur.c b/storage/innobase/btr/btr0pcur.c index 658901208ef..056896c7927 100644 --- a/storage/innobase/btr/btr0pcur.c +++ b/storage/innobase/btr/btr0pcur.c @@ -452,7 +452,6 @@ btr_pcur_move_backward_from_page( mtr_t* mtr) /*!< in: mtr */ { ulint prev_page_no; - ulint space; page_t* page; buf_block_t* prev_block; ulint latch_mode; @@ -488,7 +487,6 @@ btr_pcur_move_backward_from_page( page = btr_pcur_get_page(cursor); prev_page_no = btr_page_get_prev(page, mtr); - space = buf_block_get_space(btr_pcur_get_block(cursor)); if (prev_page_no == FIL_NULL) { } else if (btr_pcur_is_before_first_on_page(cursor)) { From ef76f25d269fba2a4564fc3000624b288c955fc3 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 18:43:15 +0300 Subject: [PATCH 096/159] (btr0sea.c:1510) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/btr/btr0sea.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c index fb667bcae82..8f5f9b839b5 100644 --- a/storage/innobase/btr/btr0sea.c +++ b/storage/innobase/btr/btr0sea.c @@ -1507,7 +1507,6 @@ btr_search_update_hash_on_delete( rec_t* rec; ulint fold; index_id_t index_id; - ibool found; ulint offsets_[REC_OFFS_NORMAL_SIZE]; mem_heap_t* heap = NULL; rec_offs_init(offsets_); @@ -1540,7 +1539,7 @@ btr_search_update_hash_on_delete( } rw_lock_x_lock(&btr_search_latch); - found = ha_search_and_delete_if_found(table, fold, rec); + ha_search_and_delete_if_found(table, fold, rec); rw_lock_x_unlock(&btr_search_latch); } From 288a543332c038956b546f4878bb58bf126968a5 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 18:45:40 +0300 Subject: [PATCH 097/159] (buf0flu.c:136) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/buf/buf0flu.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c index 7b51fc60fcc..70ed3efaf4a 100644 --- a/storage/innobase/buf/buf0flu.c +++ b/storage/innobase/buf/buf0flu.c @@ -133,12 +133,18 @@ buf_flush_delete_from_flush_rbt( /*============================*/ buf_page_t* bpage) /*!< in: bpage to be removed. */ { +#ifdef UNIV_DEBUG ibool ret = FALSE; +#endif /* UNIV_DEBUG */ buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); ut_ad(buf_flush_list_mutex_own(buf_pool)); - ret = rbt_delete(buf_pool->flush_rbt, &bpage); +#ifdef UNIV_DEBUG + ret = +#endif /* UNIV_DEBUG */ + rbt_delete(buf_pool->flush_rbt, &bpage); + ut_ad(ret); } From 80226874dd1a72a205a62bdac6c757fc75f541cf Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 18:46:24 +0300 Subject: [PATCH 098/159] (dict0crea.c:630) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/dict/dict0crea.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c index 6824d0fa9f9..1a332ea9329 100644 --- a/storage/innobase/dict/dict0crea.c +++ b/storage/innobase/dict/dict0crea.c @@ -627,7 +627,6 @@ dict_create_index_tree_step( { dict_index_t* index; dict_table_t* sys_indexes; - dict_table_t* table; dtuple_t* search_tuple; ulint zip_size; btr_pcur_t pcur; @@ -636,7 +635,6 @@ dict_create_index_tree_step( ut_ad(mutex_own(&(dict_sys->mutex))); index = node->index; - table = node->table; sys_indexes = dict_sys->sys_indexes; From 666c01419dfe472a299c3f32c1635f8ee8621740 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 18:47:15 +0300 Subject: [PATCH 099/159] (dict0dict.c:4458) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/dict/dict0dict.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index 3dba63cc76a..2512f199875 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -4455,7 +4455,6 @@ dict_index_print_low( { ib_int64_t n_vals; ulint i; - const char* type_string; ut_ad(mutex_own(&(dict_sys->mutex))); @@ -4470,14 +4469,6 @@ dict_index_print_low( dict_index_stat_mutex_exit(index); - if (dict_index_is_clust(index)) { - type_string = "clustered index"; - } else if (dict_index_is_unique(index)) { - type_string = "unique index"; - } else { - type_string = "secondary index"; - } - fprintf(stderr, " INDEX: name %s, id %llu, fields %lu/%lu," " uniq %lu, type %lu\n" From 6101698651be40b01f8a09925c1ca2163d730b8f Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 18:47:51 +0300 Subject: [PATCH 100/159] (eval0eval.c:388) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/eval/eval0eval.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innobase/eval/eval0eval.c b/storage/innobase/eval/eval0eval.c index 589b0fa1576..2aad7951535 100644 --- a/storage/innobase/eval/eval0eval.c +++ b/storage/innobase/eval/eval0eval.c @@ -385,13 +385,11 @@ eval_notfound( func_node_t* func_node) /*!< in: function node */ { que_node_t* arg1; - que_node_t* arg2; sym_node_t* cursor; sel_node_t* sel_node; ibool ibool_val; arg1 = func_node->args; - arg2 = que_node_get_next(arg1); ut_ad(func_node->func == PARS_NOTFOUND_TOKEN); From 6dfcadafc9cdf32d4ece84732c90ec419214c821 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 18:48:38 +0300 Subject: [PATCH 101/159] Remove redundant variable --- storage/innobase/eval/eval0eval.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/storage/innobase/eval/eval0eval.c b/storage/innobase/eval/eval0eval.c index 2aad7951535..dcd416adeee 100644 --- a/storage/innobase/eval/eval0eval.c +++ b/storage/innobase/eval/eval0eval.c @@ -384,16 +384,13 @@ eval_notfound( /*==========*/ func_node_t* func_node) /*!< in: function node */ { - que_node_t* arg1; sym_node_t* cursor; sel_node_t* sel_node; ibool ibool_val; - arg1 = func_node->args; - ut_ad(func_node->func == PARS_NOTFOUND_TOKEN); - cursor = arg1; + cursor = func_node->args; ut_ad(que_node_get_type(cursor) == QUE_NODE_SYMBOL); From 2efc8b2221ff5cc2c35d3ca8c5abf190e2a68a27 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 18:51:11 +0300 Subject: [PATCH 102/159] (ibuf0ibuf.c:1300) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/ibuf/ibuf0ibuf.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c index b77390ab038..d560f936cb9 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.c +++ b/storage/innobase/ibuf/ibuf0ibuf.c @@ -1297,12 +1297,11 @@ ibuf_rec_get_op_type( const rec_t* rec) /*!< in: ibuf record */ { ulint len; - const byte* field; ut_ad(ibuf_inside()); ut_ad(rec_get_n_fields_old(rec) > 2); - field = rec_get_nth_field_old(rec, 1, &len); + (void) rec_get_nth_field_old(rec, 1, &len); if (len > 1) { /* This is a < 4.1.x format record */ From 0b59b891c2ce021de6d2ac802e78b45736f19b34 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 18:51:51 +0300 Subject: [PATCH 103/159] (log0recv.c:572) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/log/log0recv.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c index f983c4fb974..dce0f2f8eb6 100644 --- a/storage/innobase/log/log0recv.c +++ b/storage/innobase/log/log0recv.c @@ -569,10 +569,8 @@ recv_synchronize_groups( ib_uint64_t start_lsn; ib_uint64_t end_lsn; ib_uint64_t recovered_lsn; - ib_uint64_t limit_lsn; recovered_lsn = recv_sys->recovered_lsn; - limit_lsn = recv_sys->limit_lsn; /* Read the last recovered log block to the recovery system buffer: the block is always incomplete */ From 191b5943229334ce1daac6aa22f3d5c8791f8d24 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 18:53:07 +0300 Subject: [PATCH 104/159] (log0recv.c:1660) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/log/log0recv.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c index dce0f2f8eb6..f6d90e4e330 100644 --- a/storage/innobase/log/log0recv.c +++ b/storage/innobase/log/log0recv.c @@ -1657,12 +1657,8 @@ recv_recover_page_func( #ifndef UNIV_HOTBACKUP if (modification_to_page) { - buf_pool_t* buf_pool; - ut_a(block); - buf_pool = buf_pool_from_block(block); - log_flush_order_mutex_enter(); buf_flush_recv_note_modification(block, start_lsn, end_lsn); log_flush_order_mutex_exit(); From 70330ca9179a764dc700d4bb0bc91994b191ef36 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 18:55:54 +0300 Subject: [PATCH 105/159] (log0recv.c:2905) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/log/log0recv.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c index f6d90e4e330..5d5caf1b48a 100644 --- a/storage/innobase/log/log0recv.c +++ b/storage/innobase/log/log0recv.c @@ -2902,7 +2902,9 @@ recv_recovery_from_checkpoint_start_func( ib_uint64_t old_scanned_lsn; ib_uint64_t group_scanned_lsn; ib_uint64_t contiguous_lsn; +#ifdef UNIV_LOG_ARCHIVE ib_uint64_t archived_lsn; +#endif /* UNIV_LOG_ARCHIVE */ byte* buf; byte log_hdr_buf[LOG_FILE_HDR_SIZE]; ulint err; @@ -2957,7 +2959,9 @@ recv_recovery_from_checkpoint_start_func( checkpoint_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_LSN); checkpoint_no = mach_read_from_8(buf + LOG_CHECKPOINT_NO); +#ifdef UNIV_LOG_ARCHIVE archived_lsn = mach_read_from_8(buf + LOG_CHECKPOINT_ARCHIVED_LSN); +#endif /* UNIV_LOG_ARCHIVE */ /* Read the first log file header to print a note if this is a recovery from a restored InnoDB Hot Backup */ From b69c8895c9dbdeba91843b7dcbab71f5bba3d1a1 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 18:57:36 +0300 Subject: [PATCH 106/159] (os0file.c:1486) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/os/os0file.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index 65c5d65f860..a57e10182dd 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -1483,7 +1483,6 @@ try_again: ibool retry; const char* mode_str = NULL; const char* type_str = NULL; - const char* purpose_str = NULL; try_again: ut_a(name); @@ -1511,18 +1510,8 @@ try_again: ut_error; } - if (purpose == OS_FILE_AIO) { - purpose_str = "AIO"; - } else if (purpose == OS_FILE_NORMAL) { - purpose_str = "NORMAL"; - } else { - ut_error; - } + ut_a(purpose == OS_FILE_AIO || purpose == OS_FILE_NORMAL); -#if 0 - fprintf(stderr, "Opening file %s, mode %s, type %s, purpose %s\n", - name, mode_str, type_str, purpose_str); -#endif #ifdef O_SYNC /* We let O_SYNC only affect log files; note that we map O_DSYNC to O_SYNC because the datasync options seemed to corrupt files in 2001 From ac67443afe196426664264c4cbc28737d474dfdb Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 19:00:28 +0300 Subject: [PATCH 107/159] (os0file.c:1485) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/os/os0file.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index a57e10182dd..6c17ded0073 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -1482,7 +1482,6 @@ try_again: int create_flag; ibool retry; const char* mode_str = NULL; - const char* type_str = NULL; try_again: ut_a(name); @@ -1502,14 +1501,7 @@ try_again: ut_error; } - if (type == OS_LOG_FILE) { - type_str = "LOG"; - } else if (type == OS_DATA_FILE) { - type_str = "DATA"; - } else { - ut_error; - } - + ut_a(type == OS_LOG_FILE || type == OS_DATA_FILE); ut_a(purpose == OS_FILE_AIO || purpose == OS_FILE_NORMAL); #ifdef O_SYNC From 0f6113f6a3146c90ac3ee931858bb3c9cabd56b6 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 19:01:14 +0300 Subject: [PATCH 108/159] (que0que.c:1286) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/que/que0que.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/storage/innobase/que/que0que.c b/storage/innobase/que/que0que.c index 3dcb9e89565..384fb490b86 100644 --- a/storage/innobase/que/que0que.c +++ b/storage/innobase/que/que0que.c @@ -1283,18 +1283,13 @@ que_run_threads_low( que_thr_t* thr) /*!< in: query thread */ { que_thr_t* next_thr; - ulint cumul_resource; ulint loop_count; ut_ad(thr->state == QUE_THR_RUNNING); ut_a(thr_get_trx(thr)->error_state == DB_SUCCESS); ut_ad(!mutex_own(&kernel_mutex)); - /* cumul_resource counts how much resources the OS thread (NOT the - query thread) has spent in this function */ - loop_count = QUE_MAX_LOOPS_WITHOUT_CHECK; - cumul_resource = 0; loop: /* Check that there is enough space in the log to accommodate possible log entries by this query step; if the operation can touch From ce3e9093d6625c62fdaf795592ac23d30e451708 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 19:03:05 +0300 Subject: [PATCH 109/159] (ha_innodb.cc:7202) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/handler/ha_innodb.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index a55bd4120c7..8b185ecca28 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -7199,7 +7199,6 @@ innobase_drop_database( ulint len = 0; trx_t* trx; char* ptr; - int error; char* namebuf; THD* thd = current_thd; @@ -7242,7 +7241,7 @@ innobase_drop_database( #else trx = innobase_trx_allocate(thd); #endif - error = row_drop_database_for_mysql(namebuf, trx); + row_drop_database_for_mysql(namebuf, trx); my_free(namebuf); /* Flush the log to reduce probability that the .frm files and From 86d0e51a9ee7194aeafc90191ee2fbf5f06309fb Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 19:04:14 +0300 Subject: [PATCH 110/159] (ha_innodb.cc:9037) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/handler/ha_innodb.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 8b185ecca28..e3b20f79464 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -9034,12 +9034,9 @@ innodb_show_status( mutex_exit(&srv_monitor_file_mutex); - bool result = FALSE; + stat_print(thd, innobase_hton_name, (uint) strlen(innobase_hton_name), + STRING_WITH_LEN(""), str, flen); - if (stat_print(thd, innobase_hton_name, (uint) strlen(innobase_hton_name), - STRING_WITH_LEN(""), str, flen)) { - result= TRUE; - } my_free(str); DBUG_RETURN(FALSE); From 11a3945ef0f556c95d8fdb5d9e316213c603f6e3 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 19:07:54 +0300 Subject: [PATCH 111/159] (i_s.cc:1111) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/handler/i_s.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index e31d6b3c523..2ec37a5365f 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -1193,6 +1193,7 @@ trx_i_s_common_fill_table( see http://bugs.mysql.com/29900 ; when that bug is resolved we can enable the DBUG_RETURN(ret) above */ DBUG_RETURN(0); + ret++; // silence a gcc46 warning #endif } From 17cc7b76bea79c24bd6e4cb8fd6977276c0f94b5 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 19:09:30 +0300 Subject: [PATCH 112/159] (row0purge.c:789) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/row/row0purge.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/storage/innobase/row/row0purge.c b/storage/innobase/row/row0purge.c index fe7a3e0236e..031b5258e98 100644 --- a/storage/innobase/row/row0purge.c +++ b/storage/innobase/row/row0purge.c @@ -786,7 +786,9 @@ row_purge_step( que_thr_t* thr) /*!< in: query thread */ { purge_node_t* node; +#ifdef UNIV_DEBUG ulint err; +#endif /* UNIV_DEBUG */ ut_ad(thr); @@ -794,7 +796,10 @@ row_purge_step( ut_ad(que_node_get_type(node) == QUE_NODE_PURGE); - err = row_purge(node, thr); +#ifdef UNIV_DEBUG + err = +#endif /* UNIV_DEBUG */ + row_purge(node, thr); ut_ad(err == DB_SUCCESS); From d4a2abcd2fc8186d17c42b1c4286720484dea45c Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 19:10:33 +0300 Subject: [PATCH 113/159] (row0umod.c:117) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/row/row0umod.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/storage/innobase/row/row0umod.c b/storage/innobase/row/row0umod.c index aebff0764c8..aef653b3150 100644 --- a/storage/innobase/row/row0umod.c +++ b/storage/innobase/row/row0umod.c @@ -114,12 +114,17 @@ row_undo_mod_clust_low( btr_pcur_t* pcur; btr_cur_t* btr_cur; ulint err; +#ifdef UNIV_DEBUG ibool success; +#endif /* UNIV_DEBUG */ pcur = &(node->pcur); btr_cur = btr_pcur_get_btr_cur(pcur); - success = btr_pcur_restore_position(mode, pcur, mtr); +#ifdef UNIV_DEBUG + success = +#endif /* UNIV_DEBUG */ + btr_pcur_restore_position(mode, pcur, mtr); ut_ad(success); From 70a486c7e7857cce3e65d917706d4d59725cfbe8 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 19:17:20 +0300 Subject: [PATCH 114/159] (row0vers.c:74) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/row/row0vers.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/storage/innobase/row/row0vers.c b/storage/innobase/row/row0vers.c index 3e6fc3f18b6..2e12361312c 100644 --- a/storage/innobase/row/row0vers.c +++ b/storage/innobase/row/row0vers.c @@ -71,7 +71,9 @@ row_vers_impl_x_locked_off_kernel( warning */ trx_t* trx; ulint rec_del; +#ifdef UNIV_DEBUG ulint err; +#endif /* UNIV_DEBUG */ mtr_t mtr; ulint comp; @@ -169,9 +171,12 @@ row_vers_impl_x_locked_off_kernel( heap2 = heap; heap = mem_heap_create(1024); - err = trx_undo_prev_version_build(clust_rec, &mtr, version, - clust_index, clust_offsets, - heap, &prev_version); +#ifdef UNIV_DEBUG + err = +#endif /* UNIV_DEBUG */ + trx_undo_prev_version_build(clust_rec, &mtr, version, + clust_index, clust_offsets, + heap, &prev_version); mem_heap_free(heap2); /* free version and clust_offsets */ if (prev_version == NULL) { From d75e5995d14ba4eca221e4dc844d89a3e9999568 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 19:30:44 +0300 Subject: [PATCH 115/159] (trx0purge.c:318) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/trx/trx0purge.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c index e17ed547050..80fe6847261 100644 --- a/storage/innobase/trx/trx0purge.c +++ b/storage/innobase/trx/trx0purge.c @@ -315,7 +315,6 @@ trx_purge_add_update_undo_to_history( trx_rsegf_t* rseg_header; trx_usegf_t* seg_header; trx_ulogf_t* undo_header; - trx_upagef_t* page_header; ulint hist_size; undo = trx->update_undo; @@ -331,7 +330,6 @@ trx_purge_add_update_undo_to_history( undo_header = undo_page + undo->hdr_offset; seg_header = undo_page + TRX_UNDO_SEG_HDR; - page_header = undo_page + TRX_UNDO_PAGE_HDR; if (undo->state != TRX_UNDO_CACHED) { /* The undo log segment will not be reused */ From 81e539f3bc2768cdee2d1e83bfaf987800c964b9 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 19:32:35 +0300 Subject: [PATCH 116/159] (trx0purge.c:316) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/trx/trx0purge.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c index 80fe6847261..cad3fb093e3 100644 --- a/storage/innobase/trx/trx0purge.c +++ b/storage/innobase/trx/trx0purge.c @@ -313,7 +313,9 @@ trx_purge_add_update_undo_to_history( trx_undo_t* undo; trx_rseg_t* rseg; trx_rsegf_t* rseg_header; +#ifdef UNIV_DEBUG trx_usegf_t* seg_header; +#endif /* UNIV_DEBUG */ trx_ulogf_t* undo_header; ulint hist_size; @@ -329,7 +331,9 @@ trx_purge_add_update_undo_to_history( rseg->page_no, mtr); undo_header = undo_page + undo->hdr_offset; +#ifdef UNIV_DEBUG seg_header = undo_page + TRX_UNDO_SEG_HDR; +#endif /* UNIV_DEBUG */ if (undo->state != TRX_UNDO_CACHED) { /* The undo log segment will not be reused */ From 74162b20923590842687c9b6d42a480d4249e738 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 19:33:38 +0300 Subject: [PATCH 117/159] (trx0purge.c:674) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/trx/trx0purge.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c index cad3fb093e3..05c0ee58a5f 100644 --- a/storage/innobase/trx/trx0purge.c +++ b/storage/innobase/trx/trx0purge.c @@ -671,7 +671,6 @@ trx_purge_rseg_get_next_history_log( { page_t* undo_page; trx_ulogf_t* log_hdr; - trx_usegf_t* seg_hdr; fil_addr_t prev_log_addr; trx_id_t trx_no; ibool del_marks; @@ -692,7 +691,6 @@ trx_purge_rseg_get_next_history_log( undo_page = trx_undo_page_get_s_latched(rseg->space, rseg->zip_size, rseg->last_page_no, &mtr); log_hdr = undo_page + rseg->last_offset; - seg_hdr = undo_page + TRX_UNDO_SEG_HDR; /* Increase the purge page count by one for every handled log */ From 9cf5e1de92f89487d2e170d95e759a77dd089fbc Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 19:34:39 +0300 Subject: [PATCH 118/159] (trx0purge.c:1082) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/trx/trx0purge.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c index 05c0ee58a5f..4c787579a03 100644 --- a/storage/innobase/trx/trx0purge.c +++ b/storage/innobase/trx/trx0purge.c @@ -1079,12 +1079,8 @@ trx_purge_rec_release( /*==================*/ trx_undo_inf_t* cell) /*!< in: storage cell */ { - trx_undo_arr_t* arr; - mutex_enter(&(purge_sys->mutex)); - arr = purge_sys->arr; - trx_purge_arr_remove_info(cell); mutex_exit(&(purge_sys->mutex)); From f7af534a5698cccdf5cefca76efe48c1e416971c Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 19:35:13 +0300 Subject: [PATCH 119/159] (trx0roll.c:747) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/trx/trx0roll.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innobase/trx/trx0roll.c b/storage/innobase/trx/trx0roll.c index 42b8a8685ad..c9e3a3850d3 100644 --- a/storage/innobase/trx/trx0roll.c +++ b/storage/innobase/trx/trx0roll.c @@ -744,11 +744,9 @@ trx_undo_arr_remove_info( { trx_undo_inf_t* cell; ulint n_used; - ulint n; ulint i; n_used = arr->n_used; - n = 0; for (i = 0;; i++) { cell = trx_undo_arr_get_nth_info(arr, i); From 154ea4f4c5e9c043226f87a7bdb19e1c374b4422 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 19:36:08 +0300 Subject: [PATCH 120/159] (trx0roll.c:746) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/trx/trx0roll.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/storage/innobase/trx/trx0roll.c b/storage/innobase/trx/trx0roll.c index c9e3a3850d3..876a00fb935 100644 --- a/storage/innobase/trx/trx0roll.c +++ b/storage/innobase/trx/trx0roll.c @@ -743,11 +743,8 @@ trx_undo_arr_remove_info( undo_no_t undo_no)/*!< in: undo number */ { trx_undo_inf_t* cell; - ulint n_used; ulint i; - n_used = arr->n_used; - for (i = 0;; i++) { cell = trx_undo_arr_get_nth_info(arr, i); From cbf60280afd54c76bae18c4b23f6cc55d0725df4 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 19:37:53 +0300 Subject: [PATCH 121/159] (trx0sys.c:252) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/trx/trx0sys.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c index 640412c4572..26498a1b712 100644 --- a/storage/innobase/trx/trx0sys.c +++ b/storage/innobase/trx/trx0sys.c @@ -249,7 +249,9 @@ trx_sys_create_doublewrite_buf(void) { buf_block_t* block; buf_block_t* block2; +#ifdef UNIV_SYNC_DEBUG buf_block_t* new_block; +#endif /* UNIV_SYNC_DEBUG */ byte* doublewrite; byte* fseg_header; ulint page_no; @@ -352,8 +354,11 @@ start_again: the page position in the tablespace, then the page has not been written to in doublewrite. */ - new_block = buf_page_get(TRX_SYS_SPACE, 0, page_no, - RW_X_LATCH, &mtr); +#ifdef UNIV_SYNC_DEBUG + new_block = +#endif /* UNIV_SYNC_DEBUG */ + buf_page_get(TRX_SYS_SPACE, 0, page_no, + RW_X_LATCH, &mtr); buf_block_dbg_add_level(new_block, SYNC_NO_ORDER_CHECK); From 01e095df3775993f6c50c1d1723112c861897766 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 19:39:35 +0300 Subject: [PATCH 122/159] (trx0trx.c:1801) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/trx/trx0trx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c index 19e3eb26421..6ef47a8dc16 100644 --- a/storage/innobase/trx/trx0trx.c +++ b/storage/innobase/trx/trx0trx.c @@ -1798,7 +1798,6 @@ trx_prepare_off_kernel( /*===================*/ trx_t* trx) /*!< in: transaction */ { - page_t* update_hdr_page; trx_rseg_t* rseg; ib_uint64_t lsn = 0; mtr_t mtr; @@ -1831,7 +1830,7 @@ trx_prepare_off_kernel( } if (trx->update_undo) { - update_hdr_page = trx_undo_set_state_at_prepare( + trx_undo_set_state_at_prepare( trx, trx->update_undo, &mtr); } From 4d79dc6fab193e7836564f5cbb4ddf95434e15ab Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 19:40:13 +0300 Subject: [PATCH 123/159] (trx0undo.c:1075) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/trx/trx0undo.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c index 90fc98f419d..59f00d198d6 100644 --- a/storage/innobase/trx/trx0undo.c +++ b/storage/innobase/trx/trx0undo.c @@ -1072,14 +1072,11 @@ trx_undo_truncate_end( ulint last_page_no; trx_undo_rec_t* rec; trx_undo_rec_t* trunc_here; - trx_rseg_t* rseg; mtr_t mtr; ut_ad(mutex_own(&(trx->undo_mutex))); ut_ad(mutex_own(&(trx->rseg->mutex))); - rseg = trx->rseg; - for (;;) { mtr_start(&mtr); From a6cc6cd6177df1299240ca614ed891afb46e610a Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 19:40:44 +0300 Subject: [PATCH 124/159] (trx0undo.c:1873) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/trx/trx0undo.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/storage/innobase/trx/trx0undo.c b/storage/innobase/trx/trx0undo.c index 59f00d198d6..9162c82e423 100644 --- a/storage/innobase/trx/trx0undo.c +++ b/storage/innobase/trx/trx0undo.c @@ -1870,7 +1870,6 @@ trx_undo_set_state_at_prepare( mtr_t* mtr) /*!< in: mtr */ { trx_usegf_t* seg_hdr; - trx_upagef_t* page_hdr; trx_ulogf_t* undo_header; page_t* undo_page; ulint offset; @@ -1888,7 +1887,6 @@ trx_undo_set_state_at_prepare( undo->hdr_page_no, mtr); seg_hdr = undo_page + TRX_UNDO_SEG_HDR; - page_hdr = undo_page + TRX_UNDO_PAGE_HDR; /*------------------------------*/ undo->state = TRX_UNDO_PREPARED; From f482bce2c1ee64fd4d780f3dd4f609173b16129a Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 20 Sep 2010 19:41:58 +0300 Subject: [PATCH 125/159] (ut0rnd.ic:88) Bug#55227 Fix compiler warnings in innodb with gcc 4.6 --- storage/innobase/include/ut0rnd.ic | 3 --- 1 file changed, 3 deletions(-) diff --git a/storage/innobase/include/ut0rnd.ic b/storage/innobase/include/ut0rnd.ic index a6ba4ec2ba2..df99c384bbe 100644 --- a/storage/innobase/include/ut0rnd.ic +++ b/storage/innobase/include/ut0rnd.ic @@ -85,9 +85,6 @@ ut_rnd_gen_ulint(void) /*==================*/ { ulint rnd; - ulint n_bits; - - n_bits = 8 * sizeof(ulint); ut_rnd_ulint_counter = UT_RND1 * ut_rnd_ulint_counter + UT_RND2; From ee6f8ae1bd0f4821bf806b3721877400ede0e848 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 21 Sep 2010 11:16:20 +0200 Subject: [PATCH 126/159] test fixes after 56753 --- mysql-test/suite/sys_vars/t/secure_file_priv.test | 2 +- mysql-test/t/mysqltest.test | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/sys_vars/t/secure_file_priv.test b/mysql-test/suite/sys_vars/t/secure_file_priv.test index 7a534e7d6e4..3e2a4fa467a 100644 --- a/mysql-test/suite/sys_vars/t/secure_file_priv.test +++ b/mysql-test/suite/sys_vars/t/secure_file_priv.test @@ -9,7 +9,7 @@ SHOW VARIABLES LIKE 'secure_file_priv'; # Doing this in a portable manner is difficult but we should be able to # count on the depth of the directory hierarchy used. Three steps up from # the datadir is the 'mysql_test' directory. ---let $PROTECTED_FILE=`SELECT concat(@@datadir,'/../../../bug50373.txt')`; +--let $PROTECTED_FILE=`SELECT concat(@@datadir,'/../../../bug50373.txt')` --eval SELECT * FROM t1 INTO OUTFILE '$PROTECTED_FILE'; DELETE FROM t1; --eval LOAD DATA INFILE '$PROTECTED_FILE' INTO TABLE t1; diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 597adffd035..c054b163c0c 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -497,10 +497,19 @@ remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql; # # Extra text after `` # +# Cannot use exec echo here as ` may or may not need to be escaped +--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql +let $x= `select 1` BOO ; +EOF --error 1 --- exec echo "let \$x= \`select 1\` BOO ;" | $MYSQL_TEST 2>&1 +--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1 +remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql; +--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--let $x= `select 1`; +EOF --error 1 --- exec echo "--let \$x= \`select 1\`;" | $MYSQL_TEST 2>&1 +--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1 +remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql; --write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql # Missing ; in next line should be detected and cause failure let $x= `select 1` From 7b216d7625301901a8296868d9a4c34bfec8b08a Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 22 Sep 2010 10:57:10 +0200 Subject: [PATCH 127/159] Bug #56921 It should be possible to log connection statements in mysqltest Added --enable-connect-log, somewhet similar to --enable-query-log If query log is disabled, disable connect log too Also some related cleanup in mysqltest.test: removing duplicate test loop --- client/mysqltest.cc | 33 +++++++++++++++++++++++++++++++++ mysql-test/r/mysqltest.result | 8 ++++++-- mysql-test/t/mysqltest.test | 32 +++++++++++++++++--------------- 3 files changed, 56 insertions(+), 17 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 08375e4a576..742ddda6add 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -103,6 +103,7 @@ static my_bool parsing_disabled= 0; static my_bool display_result_vertically= FALSE, display_result_lower= FALSE, display_metadata= FALSE, display_result_sorted= FALSE; static my_bool disable_query_log= 0, disable_result_log= 0; +static my_bool disable_connect_log= 1; static my_bool disable_warnings= 0; static my_bool disable_info= 1; static my_bool abort_on_error= 1; @@ -275,6 +276,7 @@ enum enum_commands { Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT, Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG, Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG, + Q_ENABLE_CONNECT_LOG, Q_DISABLE_CONNECT_LOG, Q_WAIT_FOR_SLAVE_TO_STOP, Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS, Q_ENABLE_INFO, Q_DISABLE_INFO, @@ -342,6 +344,8 @@ const char *command_names[]= /* Enable/disable that the _result_ from a query is logged to result file */ "enable_result_log", "disable_result_log", + "enable_connect_log", + "disable_connect_log", "wait_for_slave_to_stop", "enable_warnings", "disable_warnings", @@ -4793,6 +4797,16 @@ void select_connection_name(const char *name) set_current_connection(con); + /* Connection logging if enabled */ + if (!disable_connect_log && !disable_query_log) + { + DYNAMIC_STRING *ds= &ds_res; + + dynstr_append_mem(ds, "connection ", 11); + replace_dynstr_append(ds, name); + dynstr_append_mem(ds, ";\n", 2); + } + DBUG_VOID_RETURN; } @@ -4880,6 +4894,16 @@ void do_close_connection(struct st_command *command) var_set_string("$CURRENT_CONNECTION", con->name); } + /* Connection logging if enabled */ + if (!disable_connect_log && !disable_query_log) + { + DYNAMIC_STRING *ds= &ds_res; + + dynstr_append_mem(ds, "disconnect ", 11); + replace_dynstr_append(ds, ds_connection.str); + dynstr_append_mem(ds, ";\n", 2); + } + DBUG_VOID_RETURN; } @@ -5014,6 +5038,13 @@ int connect_n_handle_errors(struct st_command *command, dynstr_append_mem(ds, delimiter, delimiter_length); dynstr_append_mem(ds, "\n", 1); } + /* Simlified logging if enabled */ + if (!disable_connect_log && !disable_query_log) + { + replace_dynstr_append(ds, command->query); + dynstr_append_mem(ds, ";\n", 2); + } + while (!mysql_real_connect(con, host, user, pass, db, port, sock ? sock: 0, CLIENT_MULTI_STATEMENTS)) { @@ -8071,6 +8102,8 @@ int main(int argc, char **argv) case Q_DISABLE_ABORT_ON_ERROR: abort_on_error=0; break; case Q_ENABLE_RESULT_LOG: disable_result_log=0; break; case Q_DISABLE_RESULT_LOG: disable_result_log=1; break; + case Q_ENABLE_CONNECT_LOG: disable_connect_log=0; break; + case Q_DISABLE_CONNECT_LOG: disable_connect_log=1; break; case Q_ENABLE_WARNINGS: disable_warnings=0; break; case Q_DISABLE_WARNINGS: disable_warnings=1; break; case Q_ENABLE_INFO: disable_info=0; break; diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 650cc069b7f..8afef65b66f 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -452,12 +452,16 @@ mysqltest: At line 1: Missing required argument 'host' to command 'connect' mysqltest: At line 1: query 'connect con2,localhost,root,,illegal_db' failed: 1049: Unknown database 'illegal_db' mysqltest: At line 1: Illegal argument for port: 'illegal_port' mysqltest: At line 1: Illegal option to connect: SMTP -OK -mysqltest: The test didn't produce any output +200 connects succeeded mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 3: connection 'test_con1' not found in connection pool mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 2: Connection test_con1 already exists show tables; ERROR 3D000: No database selected +connect con1,localhost,root,,; +connection default; +connection con1; +disconnect con1; +connection default; Output from mysqltest-x.inc Output from mysqltest-x.inc Output from mysqltest-x.inc diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index c054b163c0c..caadce44dcf 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1465,19 +1465,6 @@ eval select "$long_rep" as x; --error 1 --exec echo "connect (con1,localhost,root,,,,,SMTP POP);" | $MYSQL_TEST 2>&1 -# Repeat connect/disconnect ---write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql -let $i=100; -while ($i) -{ - connect (test_con1,localhost,root,,); - disconnect test_con1; - dec $i; -} -EOF ---exec echo "source $MYSQLTEST_VARDIR/tmp/mysqltest.sql; echo OK; exit;" | $MYSQL_TEST 2>&1 -remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql; - # Repeat connect/disconnect --write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql let $i=200; @@ -1487,9 +1474,8 @@ while ($i) disconnect test_con1; dec $i; } +echo 200 connects succeeded; EOF ---replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---error 1 --exec echo "source $MYSQLTEST_VARDIR/tmp/mysqltest.sql;" | $MYSQL_TEST 2>&1 remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql; @@ -1530,6 +1516,22 @@ show tables; disconnect con2; connection default; +# Test enable_connect_log +--enable_connect_log +connect (con1,localhost,root,,); +connection default; +connection con1; +--disable_query_log +# These should not be logged +connect (con2,localhost,root,,*NO-ONE*); +connection con2; +disconnect con2; +connection con1; +--enable_query_log +disconnect con1; +connection default; +--disable_connect_log + # ---------------------------------------------------------------------------- # Test mysqltest arguments # ---------------------------------------------------------------------------- From faf54ff95cfb4e32029cd1d30a1a643d79ce96ec Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Wed, 22 Sep 2010 23:33:18 +0400 Subject: [PATCH 128/159] Bug #56709: Memory leaks at running the 5.1 test suite Fixed a number of memory leaks discovered by valgrind. dbug/dbug.c: This is actually an addendum to the fix for bug #52629: - there is no point in limiting the fix to just global variables, session ones are also affected. - zero all fields when allocating a new 'state' structure so that FreeState() does not deal with unitialized data later. - add a check for a NULL pointer in DBUGCloseFile() mysql-test/r/partition_error.result: Added a test case for bug #56709. mysql-test/r/variables_debug.result: Added a test case for bug #56709. mysql-test/t/partition_error.test: Added a test case for bug #56709. mysql-test/t/variables_debug.test: Added a test case for bug #56709. sql/item_timefunc.cc: There is no point in declaring 'value' as a member of Item_extract and dynamically allocating memory for it in Item_extract::fix_length_and_dec(), since this string is only used as a temporary storage in Item_extract::val_int(). sql/item_timefunc.h: Removed 'value' from the Item_extract class definition. sql/sql_load.cc: - we may need to deallocate 'buffer' even when 'error' is non-zero in some cases, since 'error' is public, and there is external code modifying it. - assign NULL to buffer when deallocating it so that we don't do it twice in the destructor - there is no point in changing 'error' in the destructor. --- dbug/dbug.c | 13 ++++--------- mysql-test/r/partition_error.result | 10 ++++++++++ mysql-test/r/variables_debug.result | 13 +++++++++++++ mysql-test/t/partition_error.test | 14 ++++++++++++++ mysql-test/t/variables_debug.test | 13 +++++++++++++ sql/item_timefunc.cc | 4 ++-- sql/item_timefunc.h | 1 - sql/sql_load.cc | 12 +++++------- 8 files changed, 61 insertions(+), 19 deletions(-) diff --git a/dbug/dbug.c b/dbug/dbug.c index 8fa5ed9af6b..76723fa8767 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -455,13 +455,8 @@ static void DbugParse(CODE_STATE *cs, const char *control) rel= control[0] == '+' || control[0] == '-'; if ((!rel || (!stack->out_file && !stack->next))) { - /* - We need to free what's already in init_settings, because unlike - the thread related stack frames there's a chance that something - is in these variables already. - */ - if (stack == &init_settings) - FreeState(cs, stack, 0); + /* Free memory associated with the state before resetting its members */ + FreeState(cs, stack, 0); stack->flags= 0; stack->delay= 0; stack->maxdepth= 0; @@ -1447,8 +1442,8 @@ static void PushState(CODE_STATE *cs) struct settings *new_malloc; new_malloc= (struct settings *) DbugMalloc(sizeof(struct settings)); + bzero(new_malloc, sizeof(struct settings)); new_malloc->next= cs->stack; - new_malloc->out_file= NULL; cs->stack= new_malloc; } @@ -1957,7 +1952,7 @@ static FILE *OpenProfile(CODE_STATE *cs, const char *name) static void DBUGCloseFile(CODE_STATE *cs, FILE *fp) { - if (fp != stderr && fp != stdout && fclose(fp) == EOF) + if (fp != NULL && fp != stderr && fp != stdout && fclose(fp) == EOF) { pthread_mutex_lock(&THR_LOCK_dbug); (void) fprintf(cs->stack->out_file, ERR_CLOSE, cs->process); diff --git a/mysql-test/r/partition_error.result b/mysql-test/r/partition_error.result index 16428fba4d9..ea74f476ceb 100644 --- a/mysql-test/r/partition_error.result +++ b/mysql-test/r/partition_error.result @@ -1008,4 +1008,14 @@ PARTITION p VALUES LESS THAN (1219089600), PARTITION pmax VALUES LESS THAN MAXVALUE); ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed DROP TABLE old; +# +# Bug #56709: Memory leaks at running the 5.1 test suite +# +CREATE TABLE t1 (a TIMESTAMP NOT NULL PRIMARY KEY); +ALTER TABLE t1 +PARTITION BY RANGE (EXTRACT(DAY FROM a)) ( +PARTITION p VALUES LESS THAN (18), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/r/variables_debug.result b/mysql-test/r/variables_debug.result index d578fa957fc..41d77007b26 100644 --- a/mysql-test/r/variables_debug.result +++ b/mysql-test/r/variables_debug.result @@ -24,4 +24,17 @@ SELECT @@global.debug; @@global.debug SET GLOBAL debug=@old_debug; +# +# Bug #56709: Memory leaks at running the 5.1 test suite +# +SET @old_local_debug = @@debug; +SET @@debug='d,foo'; +SELECT @@debug; +@@debug +d,foo +SET @@debug=''; +SELECT @@debug; +@@debug + +SET @@debug = @old_local_debug; End of 5.1 tests diff --git a/mysql-test/t/partition_error.test b/mysql-test/t/partition_error.test index 434392c2e28..d3f10628254 100644 --- a/mysql-test/t/partition_error.test +++ b/mysql-test/t/partition_error.test @@ -1252,4 +1252,18 @@ PARTITION pmax VALUES LESS THAN MAXVALUE); DROP TABLE old; +--echo # +--echo # Bug #56709: Memory leaks at running the 5.1 test suite +--echo # + +CREATE TABLE t1 (a TIMESTAMP NOT NULL PRIMARY KEY); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE t1 +PARTITION BY RANGE (EXTRACT(DAY FROM a)) ( +PARTITION p VALUES LESS THAN (18), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/mysql-test/t/variables_debug.test b/mysql-test/t/variables_debug.test index 12f5d2e6ca5..e6f1bbddc2a 100644 --- a/mysql-test/t/variables_debug.test +++ b/mysql-test/t/variables_debug.test @@ -25,4 +25,17 @@ SELECT @@global.debug; SET GLOBAL debug=@old_debug; +--echo # +--echo # Bug #56709: Memory leaks at running the 5.1 test suite +--echo # + +SET @old_local_debug = @@debug; + +SET @@debug='d,foo'; +SELECT @@debug; +SET @@debug=''; +SELECT @@debug; + +SET @@debug = @old_local_debug; + --echo End of 5.1 tests diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index dff4d20f347..103bd96efd4 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2270,8 +2270,6 @@ void Item_extract::print(String *str, enum_query_type query_type) void Item_extract::fix_length_and_dec() { - value.alloc(32); // alloc buffer - maybe_null=1; // If wrong date switch (int_type) { case INTERVAL_YEAR: max_length=4; date_value=1; break; @@ -2314,6 +2312,8 @@ longlong Item_extract::val_int() } else { + char buf[40]; + String value(buf, sizeof(buf), &my_charset_bin);; String *res= args[0]->val_str(&value); if (!res || str_to_time_with_warn(res->ptr(), res->length(), <ime)) { diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 11eed70f399..ef86406e1be 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -702,7 +702,6 @@ public: class Item_extract :public Item_int_func { - String value; bool date_value; public: const interval_type int_type; // keep it public diff --git a/sql/sql_load.cc b/sql/sql_load.cc index f9386206dce..4b68f2a3821 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -1116,6 +1116,7 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs, MYF(MY_WME))) { my_free((uchar*) buffer,MYF(0)); /* purecov: inspected */ + buffer= NULL; error=1; } else @@ -1142,13 +1143,10 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs, READ_INFO::~READ_INFO() { - if (!error) - { - if (need_end_io_cache) - ::end_io_cache(&cache); - my_free((uchar*) buffer,MYF(0)); - error=1; - } + if (!error && need_end_io_cache) + ::end_io_cache(&cache); + + my_free(buffer, MYF(MY_ALLOW_ZERO_PTR)); } From 14c7c747a5efc2a28ff67d218cb077e84390011b Mon Sep 17 00:00:00 2001 From: Mark Leith Date: Thu, 23 Sep 2010 09:12:09 +0100 Subject: [PATCH 129/159] Bug#56922 SHOW ENGINE INNODB STATUS truncation limit is too strict and not instrumented rb://459 approved by Jimmuy / Inaam --- storage/innobase/handler/ha_innodb.cc | 5 ++++- storage/innobase/include/srv0srv.h | 5 ++++- storage/innobase/srv/srv0srv.c | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index e3b20f79464..6bcca31cfcc 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -674,6 +674,8 @@ static SHOW_VAR innodb_status_variables[]= { (char*) &export_vars.innodb_rows_read, SHOW_LONG}, {"rows_updated", (char*) &export_vars.innodb_rows_updated, SHOW_LONG}, + {"truncated_status_writes", + (char*) &export_vars.innodb_truncated_status_writes, SHOW_LONG}, {NullS, NullS, SHOW_LONG} }; @@ -8969,7 +8971,7 @@ innodb_show_status( { trx_t* trx; static const char truncated_msg[] = "... truncated...\n"; - const long MAX_STATUS_SIZE = 64000; + const long MAX_STATUS_SIZE = 1048576; ulint trx_list_start = ULINT_UNDEFINED; ulint trx_list_end = ULINT_UNDEFINED; @@ -8999,6 +9001,7 @@ innodb_show_status( if (flen > MAX_STATUS_SIZE) { usable_len = MAX_STATUS_SIZE; + srv_truncated_status_writes++; } else { usable_len = flen; } diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index d78c8113aee..5d2fb808dc9 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -225,6 +225,8 @@ extern ulong srv_thread_sleep_delay; extern ulong srv_spin_wait_delay; extern ibool srv_priority_boost; +extern ulint srv_truncated_status_writes; + extern ulint srv_mem_pool_size; extern ulint srv_lock_table_size; @@ -710,11 +712,12 @@ struct export_var_struct{ ulint innodb_rows_inserted; /*!< srv_n_rows_inserted */ ulint innodb_rows_updated; /*!< srv_n_rows_updated */ ulint innodb_rows_deleted; /*!< srv_n_rows_deleted */ + ulint innodb_truncated_status_writes; /*!< srv_truncated_status_writes */ }; /** Thread slot in the thread table */ typedef struct srv_slot_struct srv_slot_t; - + /** Thread table is an array of slots */ typedef srv_slot_t srv_table_t; diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 714b0355506..72b095c7ad4 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -424,6 +424,7 @@ UNIV_INTERN ulint srv_n_lock_wait_current_count = 0; UNIV_INTERN ib_int64_t srv_n_lock_wait_time = 0; UNIV_INTERN ulint srv_n_lock_max_wait_time = 0; +UNIV_INTERN ulint srv_truncated_status_writes = 0; /* Set the following to 0 if you want InnoDB to write messages on @@ -2032,6 +2033,7 @@ srv_export_innodb_status(void) export_vars.innodb_rows_inserted = srv_n_rows_inserted; export_vars.innodb_rows_updated = srv_n_rows_updated; export_vars.innodb_rows_deleted = srv_n_rows_deleted; + export_vars.innodb_truncated_status_writes = srv_truncated_status_writes; mutex_exit(&srv_innodb_monitor_mutex); } From 064fed3b253ad91b4d6a9ff77b5e9ffaafe97d5a Mon Sep 17 00:00:00 2001 From: Sunny Bains Date: Fri, 24 Sep 2010 08:37:09 +1000 Subject: [PATCH 130/159] This patch comes from Michael: See bug#56933. --- storage/innobase/srv/srv0srv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 72b095c7ad4..83355bd1322 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -2639,7 +2639,9 @@ loop: when there is database activity */ srv_last_log_flush_time = time(NULL); - next_itr_time = ut_time_ms(); + + /* Sleep for 1 second on entrying the for loop below the first time. */ + next_itr_time = ut_time_ms() + 1000; for (i = 0; i < 10; i++) { ulint cur_time = ut_time_ms(); From f7d82cd3a2b46042a938ce50c827022abaf9f99a Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Fri, 24 Sep 2010 11:39:47 +0200 Subject: [PATCH 131/159] Bug#56659: Mismatch of CAPITAL vs small letters in "unified filelist" partitioning output Update to previous patch according to reviewers comments. Removing parts.partition_alter4_innodb from default.experimental (Also closed bug#45299 as a duplicate of bug#56659 as a result of this.) Adding run of tests requiring --big-test flag to default.weekly to keep the coverage. mysql-test/collections/default.experimental: Removed partition_alter4_innodb since it now requires --big-test flag to run since it is very time consuming. mysql-test/collections/default.weekly: Added run of test that require --big-test flag, to be run on weekly basis. --- mysql-test/collections/default.experimental | 2 -- mysql-test/collections/default.weekly | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index a8047ae9ed9..ca634d58cea 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -24,8 +24,6 @@ main.sp @solaris # Bug#47791 2010-01-20 alik Several tes main.type_float @freebsd # Bug#38965 2010-05-04 alik test cases gis-rtree, type_float, type_newdecimal fail in embedded server main.wait_timeout @solaris # Bug#51244 2010-04-26 alik wait_timeout fails on OpenSolaris -parts.partition_alter4_innodb # Bug#45299 2010-06-28 alik Test "partition_alter4_innodb" is taking too long, timeout - rpl.rpl_heartbeat_basic # BUG#54820 2010-06-26 alik rpl.rpl_heartbeat_basic fails sporadically again rpl.rpl_heartbeat_2slaves # BUG#43828 2009-10-22 luis fails sporadically rpl.rpl_innodb_bug28430* # Bug#46029 diff --git a/mysql-test/collections/default.weekly b/mysql-test/collections/default.weekly index 452a79eacbd..d874c2f4519 100644 --- a/mysql-test/collections/default.weekly +++ b/mysql-test/collections/default.weekly @@ -1 +1,2 @@ -perl mysql-test-run.pl --timer --force --comment=1st --experimental=collections/default.experimental 1st +perl mysql-test-run.pl --timer --force --comment=1st --experimental=collections/default.experimental 1st +perl mysql-test-run.pl --timer --force --comment=big-tests --experimental=collections/default.experimental --vardir=var-big-tests --big-test --testcase-timeout=60 --suite-timeout=600 parts.part_supported_sql_func_innodb parts.partition_alter1_1_2_innodb parts.partition_alter1_1_2_ndb parts.partition_alter1_1_ndb parts.partition_alter1_2_innodb parts.partition_alter1_2_ndb parts.partition_alter2_1_1_innodb parts.partition_alter2_1_2_innodb parts.partition_alter2_2_2_innodb parts.partition_alter4_innodb main.variables-big rpl_ndb.rpl_truncate_7ndb_2 From 500cb492959eef3771f03fd516eb1a21fb2924da Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Mon, 27 Sep 2010 14:36:16 +0200 Subject: [PATCH 132/159] Bug #57036 Add checks in mysqltest that variables treated as ints are in fact ints Adds boolean flag is_int and a separete function to check for int value Added tests to mysqltest.test --- client/mysqltest.cc | 36 +++++++++++++++++++++++++---------- mysql-test/r/mysqltest.result | 17 +++++++++-------- mysql-test/t/mysqltest.test | 27 ++++++++++++++------------ 3 files changed, 50 insertions(+), 30 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index c945f20a240..d1b26363d4d 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -227,8 +227,9 @@ typedef struct int str_val_len; int int_val; int alloced_len; - int int_dirty; /* do not update string if int is updated until first read */ - int alloced; + bool int_dirty; /* do not update string if int is updated until first read */ + bool is_int; + bool alloced; } VAR; /*Perl/shell-like variable registers */ @@ -1954,6 +1955,21 @@ static void var_free(void *v) C_MODE_END +void var_set_int(VAR *v, const char *str) +{ + char *endptr; + /* Initially assume not a number */ + v->int_val= 0; + v->is_int= false; + v->int_dirty= false; + if (!str) return; + + v->int_val = (int) strtol(str, &endptr, 10); + /* It is an int if strtol consumed something up to end/space/tab */ + if (endptr > str && (!*endptr || *endptr == ' ' || *endptr == '\t')) + v->is_int= true; +} + VAR *var_init(VAR *v, const char *name, int name_len, const char *val, int val_len) @@ -1988,11 +2004,10 @@ VAR *var_init(VAR *v, const char *name, int name_len, const char *val, memcpy(tmp_var->str_val, val, val_len); tmp_var->str_val[val_len]= 0; } + var_set_int(tmp_var, val); tmp_var->name_len = name_len; tmp_var->str_val_len = val_len; tmp_var->alloced_len = val_alloc_len; - tmp_var->int_val = (val) ? atoi(val) : 0; - tmp_var->int_dirty = 0; return tmp_var; } @@ -2053,7 +2068,7 @@ VAR* var_get(const char *var_name, const char **var_name_end, my_bool raw, if (!raw && v->int_dirty) { sprintf(v->str_val, "%d", v->int_val); - v->int_dirty = 0; + v->int_dirty= false; v->str_val_len = strlen(v->str_val); } if (var_name_end) @@ -2115,7 +2130,7 @@ void var_set(const char *var_name, const char *var_name_end, if (v->int_dirty) { sprintf(v->str_val, "%d", v->int_val); - v->int_dirty= 0; + v->int_dirty=false; v->str_val_len= strlen(v->str_val); } /* setenv() expects \0-terminated strings */ @@ -2421,6 +2436,7 @@ void var_set_query_get_value(struct st_command *command, VAR *var) void var_copy(VAR *dest, VAR *src) { dest->int_val= src->int_val; + dest->is_int= src->is_int; dest->int_dirty= src->int_dirty; /* Alloc/realloc data for str_val in dest */ @@ -2504,9 +2520,7 @@ void eval_expr(VAR *v, const char *p, const char **p_end) v->str_val_len = new_val_len; memcpy(v->str_val, p, new_val_len); v->str_val[new_val_len] = 0; - v->int_val=atoi(p); - DBUG_PRINT("info", ("atoi on '%s', returns: %d", p, v->int_val)); - v->int_dirty=0; + var_set_int(v, p); } DBUG_VOID_RETURN; } @@ -2853,6 +2867,8 @@ int do_modify_var(struct st_command *command, die("The argument to %.*s must be a variable (start with $)", command->first_word_len, command->query); v= var_get(p, &p, 1, 0); + if (! v->is_int) + die("Cannot perform inc/dec on a non-numeric value"); switch (op) { case DO_DEC: v->int_val--; @@ -2864,7 +2880,7 @@ int do_modify_var(struct st_command *command, die("Invalid operator to do_modify_var"); break; } - v->int_dirty= 1; + v->int_dirty= true; command->last_argument= (char*)++p; return 0; } diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 650cc069b7f..d7597599f02 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -369,23 +369,24 @@ mysqltest: At line 1: Missing required argument 'sleep_delay' to command 'real_s mysqltest: At line 1: Invalid argument to sleep "abc" mysqltest: At line 1: Invalid argument to real_sleep "abc" 1 -2 101 -hej -1 +-99 mysqltest: At line 1: Missing argument to inc mysqltest: At line 1: The argument to inc must be a variable (start with $) +mysqltest: At line 1: Cannot perform inc/dec on a non-numeric value mysqltest: At line 1: End of line junk detected: "1000" -4 -4 +mysqltest: At line 1: Cannot perform inc/dec on a non-numeric value +mysqltest: At line 1: Cannot perform inc/dec on a non-numeric value +-96 +-96 -1 --2 99 -hej --1 mysqltest: At line 1: Missing argument to dec mysqltest: At line 1: The argument to dec must be a variable (start with $) +mysqltest: At line 1: Cannot perform inc/dec on a non-numeric value mysqltest: At line 1: End of line junk detected: "1000" +mysqltest: At line 1: Cannot perform inc/dec on a non-numeric value +mysqltest: At line 1: Cannot perform inc/dec on a non-numeric value mysqltest: At line 1: Missing arguments to system, nothing to do! mysqltest: At line 1: Missing arguments to system, nothing to do! system command 'NonExistsinfComamdn 2> /dev/null' failed diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index c054b163c0c..45dbb4a5c8d 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1006,16 +1006,13 @@ EOF # ---------------------------------------------------------------------------- # Test inc # ---------------------------------------------------------------------------- -inc $i; -echo $i; +let $i= 0; inc $i; echo $i; let $i=100; inc $i; echo $i; - -let $i=hej; -echo $i; +let $i= -100; inc $i; echo $i; @@ -1024,7 +1021,13 @@ echo $i; --error 1 --exec echo "inc i;" | $MYSQL_TEST 2>&1 --error 1 +--exec echo "inc \$i;" | $MYSQL_TEST 2>&1 +--error 1 --exec echo "let \$i=100; inc \$i 1000; echo \$i;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "let \$i=text; inc \$i; echo \$i;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "let \$i=10cc; inc \$i; echo \$i;" | $MYSQL_TEST 2>&1 inc $i; inc $i; inc $i; --echo $i echo $i; @@ -1034,25 +1037,25 @@ echo $i; # Test dec # ---------------------------------------------------------------------------- -dec $d; -echo $d; +let $d= 0; dec $d; echo $d; let $d=100; dec $d; echo $d; -let $d=hej; -echo $d; -dec $d; -echo $d; - --error 1 --exec echo "dec;" | $MYSQL_TEST 2>&1 --error 1 --exec echo "dec i;" | $MYSQL_TEST 2>&1 --error 1 +--exec echo "dec \$i;" | $MYSQL_TEST 2>&1 +--error 1 --exec echo "let \$i=100; dec \$i 1000; echo \$i;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "let \$i=text; dec \$i; echo \$i;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "let \$i=10cc; dec \$i; echo \$i;" | $MYSQL_TEST 2>&1 # ---------------------------------------------------------------------------- From b9f144fa4b278b8c8c2a54fd98e37c630b73224c Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 27 Sep 2010 20:08:12 +0300 Subject: [PATCH 133/159] Use C-style comment instead of C++ in a C header. Spotted by: Davi Arnaut --- storage/innobase/include/ut0rbt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/include/ut0rbt.h b/storage/innobase/include/ut0rbt.h index 7902dc91f09..e26b637ae13 100644 --- a/storage/innobase/include/ut0rbt.h +++ b/storage/innobase/include/ut0rbt.h @@ -53,7 +53,7 @@ Created 2007-03-20 Sunny Bains /* Red black tree typedefs */ typedef struct ib_rbt_struct ib_rbt_t; typedef struct ib_rbt_node_struct ib_rbt_node_t; -// FIXME: Iterator is a better name than _bound_ +/* FIXME: Iterator is a better name than _bound_ */ typedef struct ib_rbt_bound_struct ib_rbt_bound_t; typedef void (*ib_rbt_print_node)(const ib_rbt_node_t* node); typedef int (*ib_rbt_compare)(const void* p1, const void* p2); From 9f3660c6e5632ad017e90c1ef9dc0c40cfe1c9f9 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 28 Sep 2010 11:12:34 +0300 Subject: [PATCH 134/159] Silence a GCC warning about reaching the end of non-void func Spotted by: Marko --- storage/innodb_plugin/handler/i_s.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innodb_plugin/handler/i_s.cc b/storage/innodb_plugin/handler/i_s.cc index 1ac79860351..9ad2d656365 100644 --- a/storage/innodb_plugin/handler/i_s.cc +++ b/storage/innodb_plugin/handler/i_s.cc @@ -1012,8 +1012,8 @@ trx_i_s_common_fill_table( deadlock occurs between the mysqld server and mysql client, see http://bugs.mysql.com/29900 ; when that bug is resolved we can enable the DBUG_RETURN(ret) above */ - DBUG_RETURN(0); ret++; // silence a gcc46 warning + DBUG_RETURN(0); #endif } From fbeb571369c19d7534d5d1e9695c5bcc03123844 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 28 Sep 2010 11:14:42 +0300 Subject: [PATCH 135/159] Manually merge a GCC warning fix from 5.1 to 5.5: ------------------------------------------------------------ revno: 3615 revision-id: vasil.dimov@oracle.com-20100928081234-22qbm6cwht521484 parent: vasil.dimov@oracle.com-20100928063833-snn6cjwgksa6gk3b committer: Vasil Dimov branch nick: mysql-5.1-innodb timestamp: Tue 2010-09-28 11:12:34 +0300 message: Silence a GCC warning about reaching the end of non-void func Spotted by: Marko --- storage/innobase/handler/i_s.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 2ec37a5365f..9f0e465a4d9 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -1192,8 +1192,8 @@ trx_i_s_common_fill_table( deadlock occurs between the mysqld server and mysql client, see http://bugs.mysql.com/29900 ; when that bug is resolved we can enable the DBUG_RETURN(ret) above */ - DBUG_RETURN(0); ret++; // silence a gcc46 warning + DBUG_RETURN(0); #endif } From 3de0aa061b6bec17c78c37d04f6fa99b111f5115 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 28 Sep 2010 15:31:33 +0300 Subject: [PATCH 136/159] Increment InnoDB Plugin version to 1.0.13. InnoDB Plugin 1.0.12 has been released with MySQL 5.1.51. --- storage/innodb_plugin/include/univ.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i index 66b712a0355..ee77582d7f1 100644 --- a/storage/innodb_plugin/include/univ.i +++ b/storage/innodb_plugin/include/univ.i @@ -46,7 +46,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_MAJOR 1 #define INNODB_VERSION_MINOR 0 -#define INNODB_VERSION_BUGFIX 12 +#define INNODB_VERSION_BUGFIX 13 /* The following is the InnoDB version as shown in SELECT plugin_version FROM information_schema.plugins; From 9605bc63fc7fe2d2b188d992ae43d9e97360c782 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Tue, 28 Sep 2010 15:58:01 +0200 Subject: [PATCH 137/159] Bug #56125 MTR2 start-and-exit removes server tmpdir, server becomes not operational This happens when creating new tmpdir due to too long socket path Don't delete it if --start-and-exit, but warn user to do it. --- mysql-test/mysql-test-run.pl | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 82c62ebfcf1..f0c7a02348a 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -110,12 +110,24 @@ my $path_vardir_trace; # unix formatted opt_vardir for trace files my $opt_tmpdir; # Path to use for tmp/ dir my $opt_tmpdir_pid; +my $opt_start; +my $opt_start_dirty; +my $opt_start_exit; +my $start_only; + END { if ( defined $opt_tmpdir_pid and $opt_tmpdir_pid == $$ ) { - # Remove the tempdir this process has created - mtr_verbose("Removing tmpdir '$opt_tmpdir"); - rmtree($opt_tmpdir); + if (!$opt_start_exit) + { + # Remove the tempdir this process has created + mtr_verbose("Removing tmpdir $opt_tmpdir"); + rmtree($opt_tmpdir); + } + else + { + mtr_warning("tmpdir $opt_tmpdir should be removed after the server has finished"); + } } } @@ -215,10 +227,6 @@ my $opt_start_timeout = $ENV{MTR_START_TIMEOUT} || 180; # seconds sub suite_timeout { return $opt_suite_timeout * 60; }; sub check_timeout { return $opt_testcase_timeout * 6; }; -my $opt_start; -my $opt_start_dirty; -my $opt_start_exit; -my $start_only; my $opt_wait_all; my $opt_user_args; my $opt_repeat= 1; From 9ec472486608a0fb1a5ea6fa31ad8f1f2927f1c7 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 30 Sep 2010 10:28:22 +0200 Subject: [PATCH 138/159] Small test fix after 56753 --- mysql-test/suite/innodb/t/innodb_bug53756.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/innodb/t/innodb_bug53756.test b/mysql-test/suite/innodb/t/innodb_bug53756.test index 8324f2640a2..d3b0a77c680 100644 --- a/mysql-test/suite/innodb/t/innodb_bug53756.test +++ b/mysql-test/suite/innodb/t/innodb_bug53756.test @@ -34,8 +34,8 @@ INSERT INTO bug_53756 VALUES(1, 11), (2, 22), (3, 33), (4, 44); --echo --echo # Select a less restrictive isolation level. # Don't use user variables. They won't survive server crash. ---let $global_isolation= `SELECT @@global.tx_isolation`; ---let $session_isolation= `SELECT @@session.tx_isolation`; +--let $global_isolation= `SELECT @@global.tx_isolation` +--let $session_isolation= `SELECT @@session.tx_isolation` SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED; SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; COMMIT; From 51cdf59546be883119b5a00e10c8c1b0f5362761 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Thu, 30 Sep 2010 13:26:18 +0300 Subject: [PATCH 139/159] Fix a potential bug when using __sync_lock_test_and_set() TYPE __sync_lock_test_and_set (TYPE *ptr, TYPE value, ...) it is not documented what happens if the two arguments are of different type like it was before: the first one was lock_word_t (byte) and the second one was 1 or 0 (int). Approved by: Marko (via IRC) --- storage/innodb_plugin/include/os0sync.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innodb_plugin/include/os0sync.h b/storage/innodb_plugin/include/os0sync.h index 0c22162b900..f32e7ab710a 100644 --- a/storage/innodb_plugin/include/os0sync.h +++ b/storage/innodb_plugin/include/os0sync.h @@ -330,7 +330,7 @@ amount of increment. */ Returns the old value of *ptr, atomically sets *ptr to new_val */ # define os_atomic_test_and_set_byte(ptr, new_val) \ - __sync_lock_test_and_set(ptr, new_val) + __sync_lock_test_and_set(ptr, (byte) new_val) #elif defined(HAVE_IB_SOLARIS_ATOMICS) From be7b3c004066fba276471df861ffb6d90c88a883 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Thu, 30 Sep 2010 12:42:37 +0200 Subject: [PATCH 140/159] Bug #52828 Tests that use perl fail when perl is not in path Trying to run perl fails, just like it does when perl is started but fails Trap the case that perl was not found/could not be started, and skip test Also force a restart of servers since test may already have done something mtr now also appends path of current perl to PATH to aid mysqltest --- client/mysqltest.cc | 13 ++++++++++++- mysql-test/mysql-test-run.pl | 8 ++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 89ba739a9ef..7d335b7d47a 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -3853,7 +3853,18 @@ void do_perl(struct st_command *command) if (!error) my_delete(temp_file_path, MYF(0)); - handle_command_error(command, WEXITSTATUS(error)); + /* Check for error code that indicates perl could not be started */ + int exstat= WEXITSTATUS(error); +#ifdef __WIN__ + if (exstat == 1) + /* Text must begin 'perl not found' as mtr looks for it */ + abort_not_supported_test("perl not found in path or did not start"); +#else + if (exstat == 127) + abort_not_supported_test("perl not found in path"); +#endif + else + handle_command_error(command, exstat); } dynstr_free(&ds_delimiter); DBUG_VOID_RETURN; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index f0c7a02348a..b83c32d3815 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2107,6 +2107,11 @@ sub environment_setup { # to detect that valgrind is being used from test cases $ENV{'VALGRIND_TEST'}= $opt_valgrind; + # Add dir of this perl to aid mysqltest in finding perl + my $perldir= dirname($^X); + my $pathsep= ":"; + $pathsep= ";" if IS_WINDOWS && ! IS_CYGWIN; + $ENV{'PATH'}= "$ENV{'PATH'}".$pathsep.$perldir; } @@ -3583,6 +3588,9 @@ sub run_testcase ($) { # Try to get reason from test log file find_testcase_skipped_reason($tinfo); mtr_report_test_skipped($tinfo); + # Restart if skipped due to missing perl, it may have had side effects + stop_all_servers($opt_shutdown_timeout) + if ($tinfo->{'comment'} =~ /^perl not found/); } elsif ( $res == 65 ) { From eaaea8eb7d2619c5c53947356a7672f4b174b5bc Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Thu, 30 Sep 2010 15:48:44 +0300 Subject: [PATCH 141/159] Fix Bug#56340 innodb updates index stats too frequently after non-index updates This is a simple optimization issue. All stats are related to only indexed columns, index size or number of rows in the whole table. UPDATEs that touch only non-indexed columns cannot affect stats and we can avoid calling the function row_update_statistics_if_needed() which may result in unnecessary I/O. Approved by: Marko (rb://466) --- storage/innobase/row/row0mysql.c | 7 ++++++- storage/innodb_plugin/row/row0mysql.c | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 4a834c4efc2..2058363c786 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -1447,7 +1447,12 @@ run_again: srv_n_rows_updated++; } - row_update_statistics_if_needed(prebuilt->table); + /* We update table statistics only if it is a DELETE or UPDATE + that changes indexed columns, UPDATEs that change only non-indexed + columns would not affect statistics. */ + if (node->is_delete || !(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) { + row_update_statistics_if_needed(prebuilt->table); + } trx->op_info = ""; diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index feeb7fc80b7..813a99049fc 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -1422,7 +1422,12 @@ run_again: srv_n_rows_updated++; } - row_update_statistics_if_needed(prebuilt->table); + /* We update table statistics only if it is a DELETE or UPDATE + that changes indexed columns, UPDATEs that change only non-indexed + columns would not affect statistics. */ + if (node->is_delete || !(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) { + row_update_statistics_if_needed(prebuilt->table); + } trx->op_info = ""; From 003a2315650b9ab4777fce959ded2881ff741da3 Mon Sep 17 00:00:00 2001 From: "Bernt M. Johnsen" Date: Thu, 30 Sep 2010 15:52:39 +0200 Subject: [PATCH 142/159] Bug#56375 Ignore socket path since it may vary. Added some comments to inline perl in the test. --- mysql-test/include/mysqld--help.inc | 16 ++++++++++++++-- mysql-test/r/mysqld--help-notwin.result | 1 - 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/mysql-test/include/mysqld--help.inc b/mysql-test/include/mysqld--help.inc index 3c50e50ac0e..5d20cff2c13 100644 --- a/mysql-test/include/mysqld--help.inc +++ b/mysql-test/include/mysqld--help.inc @@ -7,15 +7,27 @@ # force lower-case-table-names=1 (linux/macosx have different defaults) # force symbolic-links=0 (valgrind build has a different default) # + exec $MYSQLD_BOOTSTRAP_CMD --symbolic-links=0 --lower-case-table-names=1 --help --verbose > $MYSQL_TMP_DIR/mysqld--help.txt 2>&1; +# The inline perl code below will copy $MYSQL_TMP_DIR/mysqld--help.txt +# to output, but filter away some variable stuff (e.g. paths). + perl; + # Variables which we don't want to display in the result file since + # their paths may vary: @skipvars=qw/basedir open-files-limit general-log-file log plugin-dir log-slow-queries pid-file slow-query-log-file - datadir slave-load-tmpdir tmpdir/; + datadir slave-load-tmpdir tmpdir socket/; + + # Plugins which may or may not be there: @plugins=qw/innodb ndb archive blackhole federated partition ndbcluster debug temp-pool ssl des-key-file thread-concurrency super-large-pages mutex-deadlock-detector null-audit/; - @env=qw/MYSQLTEST_VARDIR MYSQL_TEST_DIR MYSQL_LIBDIR MYSQL_CHARSETSDIR MYSQL_SHAREDIR /; + + # And substitute the content some environment variables with their + # names: + @env=qw/MYSQLTEST_VARDIR MYSQL_TEST_DIR MYSQL_LIBDIR MYSQL_CHARSETSDIR MYSQL_SHAREDIR/; + $re1=join('|', @skipvars, @plugins); $re2=join('|', @plugins); $skip=0; diff --git a/mysql-test/r/mysqld--help-notwin.result b/mysql-test/r/mysqld--help-notwin.result index 025f67082ec..63e17e1c188 100644 --- a/mysql-test/r/mysqld--help-notwin.result +++ b/mysql-test/r/mysqld--help-notwin.result @@ -913,7 +913,6 @@ slave-transaction-retries 10 slave-type-conversions slow-launch-time 2 slow-query-log FALSE -socket /tmp/mysql.sock sort-buffer-size 2097152 sporadic-binlog-dump-fail FALSE sql-mode From c485854945cf73ad96594eea838fdd4286c53b33 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Thu, 30 Sep 2010 15:57:33 +0200 Subject: [PATCH 143/159] Bug#55458: Partitioned MyISAM table gets crashed by multi-table update Bug#57113: ha_partition::extra(ha_extra_function): Assertion `m_extra_cache' failed Fix for bug#55458 included DBUG_ASSERTS causing debug builds of the server to crash on another multi-table update. Removed the asserts since they where wrong. (updated after testing the patch in 5.5). mysql-test/r/partition.result: updated result mysql-test/t/partition.test: Added test for bug#57113 sql/ha_partition.cc: Removed the assert for m_extra_cache when ::extra(HA_PREPARE_FOR_UPDATE) was called. --- mysql-test/r/partition.result | 15 +++++++++++++++ mysql-test/t/partition.test | 22 ++++++++++++++++++++++ sql/ha_partition.cc | 18 +++++++++++------- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index bb1635b8621..1267ec70b0a 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -1,5 +1,20 @@ drop table if exists t1, t2; # +# Bug#57113: ha_partition::extra(ha_extra_function): +# Assertion `m_extra_cache' failed +CREATE TABLE t1 +(id INT NOT NULL PRIMARY KEY, +name VARCHAR(16) NOT NULL, +year YEAR, +INDEX name (name(8)) +) +PARTITION BY HASH(id) PARTITIONS 2; +INSERT INTO t1 VALUES ( 1, 'FooBar', '1924' ); +CREATE TABLE t2 (id INT); +INSERT INTO t2 VALUES (1),(2); +UPDATE t1, t2 SET t1.year = '1955' WHERE t1.name = 'FooBar'; +DROP TABLE t1, t2; +# # Bug#55458: Partitioned MyISAM table gets crashed by multi-table update # CREATE TABLE t1 ( diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 95d702ee6b8..86e2603cd01 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -14,6 +14,28 @@ drop table if exists t1, t2; --enable_warnings +--echo # +--echo # Bug#57113: ha_partition::extra(ha_extra_function): +--echo # Assertion `m_extra_cache' failed +CREATE TABLE t1 +(id INT NOT NULL PRIMARY KEY, + name VARCHAR(16) NOT NULL, + year YEAR, + INDEX name (name(8)) +) +PARTITION BY HASH(id) PARTITIONS 2; + +INSERT INTO t1 VALUES ( 1, 'FooBar', '1924' ); + +CREATE TABLE t2 (id INT); + +INSERT INTO t2 VALUES (1),(2); + +UPDATE t1, t2 SET t1.year = '1955' WHERE t1.name = 'FooBar'; + +DROP TABLE t1, t2; + + --echo # --echo # Bug#55458: Partitioned MyISAM table gets crashed by multi-table update --echo # diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 4fff6cc703c..42920ef18f7 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -5550,7 +5550,6 @@ int ha_partition::extra(enum ha_extra_function operation) DBUG_RETURN(prepare_for_rename()); break; case HA_EXTRA_PREPARE_FOR_UPDATE: - DBUG_ASSERT(m_extra_cache); /* Needs to be run on the first partition in the range now, and later in late_extra_cache, when switching to a new partition to scan. @@ -5558,6 +5557,8 @@ int ha_partition::extra(enum ha_extra_function operation) m_extra_prepare_for_update= TRUE; if (m_part_spec.start_part != NO_CURRENT_PART_ID) { + if (!m_extra_cache) + m_extra_cache_part_id= m_part_spec.start_part; DBUG_ASSERT(m_extra_cache_part_id == m_part_spec.start_part); VOID(m_file[m_part_spec.start_part]->extra(HA_EXTRA_PREPARE_FOR_UPDATE)); } @@ -5820,19 +5821,22 @@ void ha_partition::late_extra_cache(uint partition_id) { handler *file; DBUG_ENTER("ha_partition::late_extra_cache"); - DBUG_PRINT("info", ("extra_cache %u partid %u size %u", m_extra_cache, + DBUG_PRINT("info", ("extra_cache %u prepare %u partid %u size %u", + m_extra_cache, m_extra_prepare_for_update, partition_id, m_extra_cache_size)); if (!m_extra_cache && !m_extra_prepare_for_update) DBUG_VOID_RETURN; file= m_file[partition_id]; - if (m_extra_cache_size == 0) - VOID(file->extra(HA_EXTRA_CACHE)); - else - VOID(file->extra_opt(HA_EXTRA_CACHE, m_extra_cache_size)); + if (m_extra_cache) + { + if (m_extra_cache_size == 0) + VOID(file->extra(HA_EXTRA_CACHE)); + else + VOID(file->extra_opt(HA_EXTRA_CACHE, m_extra_cache_size)); + } if (m_extra_prepare_for_update) { - DBUG_ASSERT(m_extra_cache); VOID(file->extra(HA_EXTRA_PREPARE_FOR_UPDATE)); } m_extra_cache_part_id= partition_id; From f7c83521936987965a7c1d92fbc7e8300964af79 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Fri, 1 Oct 2010 10:34:21 +0300 Subject: [PATCH 144/159] Fix Bug#56340 innodb updates index stats too frequently after non-index updates This is a manual merge from mysql-5.1-innodb of: revno: 3618 revision-id: vasil.dimov@oracle.com-20100930124844-yglojy7c3vaji6dx parent: vasil.dimov@oracle.com-20100930102618-s9f9ytbytr3eqw9h committer: Vasil Dimov branch nick: mysql-5.1-innodb timestamp: Thu 2010-09-30 15:48:44 +0300 message: Fix Bug#56340 innodb updates index stats too frequently after non-index updates This is a simple optimization issue. All stats are related to only indexed columns, index size or number of rows in the whole table. UPDATEs that touch only non-indexed columns cannot affect stats and we can avoid calling the function row_update_statistics_if_needed() which may result in unnecessary I/O. Approved by: Marko (rb://466) In addition to the above message: we know that row_update_cascade_for_mysql() (the other place where row_update_statistics_if_needed is called) always updates indexed columns (FK-related), so there is no need to add this cond there. --- storage/innobase/row/row0mysql.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 1262ac71e98..29c1f919ed2 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -1481,7 +1481,12 @@ run_again: srv_n_rows_updated++; } - row_update_statistics_if_needed(prebuilt->table); + /* We update table statistics only if it is a DELETE or UPDATE + that changes indexed columns, UPDATEs that change only non-indexed + columns would not affect statistics. */ + if (node->is_delete || !(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) { + row_update_statistics_if_needed(prebuilt->table); + } trx->op_info = ""; From abaa5c91b4307750aeac4582753f2f4131cf4f6f Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Fri, 1 Oct 2010 11:00:18 +0200 Subject: [PATCH 145/159] Bug #20304 mysqltest: reap with no preceding statement hangs forever Added sanity check, similar to the one preventing send without reap --- client/mysqltest.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 7d335b7d47a..53c1f1bdf85 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -7370,6 +7370,9 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) if (cn->pending && (flags & QUERY_SEND_FLAG)) die ("Cannot run query on connection between send and reap"); + if (!(flags & QUERY_SEND_FLAG) && !cn->pending) + die ("Cannot reap on a connection without pending send"); + init_dynamic_string(&ds_warnings, NULL, 0, 256); /* Evaluate query if this is an eval command From 1b5f84db5b2b38428ec662124c9241cf2bd51350 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Fri, 1 Oct 2010 13:22:11 +0200 Subject: [PATCH 146/159] Bug#56172: Server crashes in ha_partition::reset on REBUILD PARTITION under LOCK TABLE Collapsed patch including updates from the reviews. In case of failure in ALTER ... PARTITION under LOCK TABLE the server could crash, due to it had modified the locked table object, which was not reverted in case of failure, resulting in a bad table definition used after the failed command. Solved by instead of altering the locked table object and its partition_info struct, creating an internal temporary intermediate table object used for altering, just like the non partitioned mysql_alter_table. So if an error occur before the alter operation is complete, the original table is not modified at all. But if the alter operation have succeeded so far that it must be completed as whole, the table is properly closed and reopened. (The completion on failure is done by the ddl_log.) mysql-test/suite/parts/inc/partition_fail.inc: Added tests under LOCK TABLE mysql-test/suite/parts/r/partition_debug_innodb.result: Updated results mysql-test/suite/parts/r/partition_debug_myisam.result: Updated results mysql-test/suite/parts/r/partition_special_innodb.result: updated result mysql-test/suite/parts/t/partition_special_innodb.test: changing comment, since this patch also fixes this. sql/sql_partition.cc: Added TODO, to use DBUG_SUICIDE() instead of abort() to avoid core-files on expected crashes. Removed unused arguments to fast_end_partition. Opening a intermediate table in prep_alter_part_table, instead of altering (a possible locked) normally opened table. That way we do not have to do anything more than close the intermediate table on error, leaving the ordinary table opened and locked. Also making sure that the intermediate table are closed/destroyed on failure. If no error occur it is later destroyed in the end of fast_alter_partition_table. Added ha_external_lock to make sure MyISAM flushed the index file after copying the partitions. This also leads to removal of the special close and removal from the table cache for other instances of the table. sql/sql_partition.h: Changed the arguments for prep_alter_part_table and fast_alter_partition_table to use an intermediate table instead of altering a (possibly locked) normal table. sql/sql_table.cc: Using an intermediate table created in prep_alter_part_table to be used in fast_alter_partition_table, also closing/destroying it on failure. --- mysql-test/suite/parts/inc/partition_fail.inc | 20 + .../parts/r/partition_debug_innodb.result | 1886 ++++++++++++++- .../parts/r/partition_debug_myisam.result | 2016 ++++++++++++++++- .../parts/r/partition_special_innodb.result | 5 +- .../parts/t/partition_special_innodb.test | 2 +- sql/sql_partition.cc | 428 ++-- sql/sql_partition.h | 8 +- sql/sql_table.cc | 17 +- 8 files changed, 4164 insertions(+), 218 deletions(-) diff --git a/mysql-test/suite/parts/inc/partition_fail.inc b/mysql-test/suite/parts/inc/partition_fail.inc index 6942b40042a..995a1f895e4 100644 --- a/mysql-test/suite/parts/inc/partition_fail.inc +++ b/mysql-test/suite/parts/inc/partition_fail.inc @@ -16,3 +16,23 @@ SHOW CREATE TABLE t1; --sorted_result SELECT * FROM t1; DROP TABLE t1; + +--echo # Same test under LOCK TABLE +--eval $create_statement +--eval $insert_statement +--echo # State before failure +--list_files $DATADIR/test +SHOW CREATE TABLE t1; +--sorted_result +SELECT * FROM t1; +LOCK TABLE t1 WRITE; +--disable_abort_on_error +--eval $fail_statement +--enable_abort_on_error +--echo # State after failure +--list_files $DATADIR/test +SHOW CREATE TABLE t1; +--sorted_result +SELECT * FROM t1; +UNLOCK TABLES; +DROP TABLE t1; diff --git a/mysql-test/suite/parts/r/partition_debug_innodb.result b/mysql-test/suite/parts/r/partition_debug_innodb.result index eb2218e204e..49d863bca8e 100644 --- a/mysql-test/suite/parts/r/partition_debug_innodb.result +++ b/mysql-test/suite/parts/r/partition_debug_innodb.result @@ -747,6 +747,67 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_1"; SET SESSION debug="+d,fail_add_partition_2"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -807,6 +868,67 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_2"; SET SESSION debug="+d,fail_add_partition_3"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -867,6 +989,67 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_3"; SET SESSION debug="+d,fail_add_partition_4"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -927,6 +1110,67 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_4"; SET SESSION debug="+d,fail_add_partition_5"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -987,6 +1231,67 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_5"; SET SESSION debug="+d,fail_add_partition_6"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -1047,6 +1352,67 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_6"; SET SESSION debug="+d,fail_add_partition_7"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -1107,6 +1473,67 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_7"; SET SESSION debug="+d,fail_add_partition_8"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -1169,6 +1596,69 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1#P#p20.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_8"; SET SESSION debug="+d,fail_add_partition_9"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -1231,6 +1721,69 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1#P#p20.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_9"; SET SESSION debug="+d,fail_add_partition_10"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -1293,6 +1846,69 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1#P#p20.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_10"; # Test DROP PARTITION SET SESSION debug="+d,crash_drop_partition_1"; @@ -1902,6 +2518,66 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 DROP PARTITION p10; +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_drop_partition_1"; SET SESSION debug="+d,fail_drop_partition_2"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -1961,6 +2637,66 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 DROP PARTITION p10; +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_drop_partition_2"; SET SESSION debug="+d,fail_drop_partition_3"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -2020,6 +2756,66 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 DROP PARTITION p10; +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_drop_partition_3"; SET SESSION debug="+d,fail_drop_partition_4"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -2073,6 +2869,60 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 DROP PARTITION p10; +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_drop_partition_4"; SET SESSION debug="+d,fail_drop_partition_5"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -2126,6 +2976,60 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 DROP PARTITION p10; +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_drop_partition_5"; SET SESSION debug="+d,fail_drop_partition_6"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -2179,6 +3083,60 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 DROP PARTITION p10; +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_drop_partition_6"; SET SESSION debug="+d,fail_drop_partition_7"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -2232,6 +3190,60 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 DROP PARTITION p10; +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_drop_partition_7"; SET SESSION debug="+d,fail_drop_partition_8"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -2285,6 +3297,60 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 DROP PARTITION p10; +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_drop_partition_8"; SET SESSION debug="+d,fail_drop_partition_9"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -2338,6 +3404,60 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 DROP PARTITION p10; +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_drop_partition_9"; # Test change partition (REORGANIZE/REBUILD/COALESCE # or ADD HASH PARTITION). @@ -2730,6 +3850,7 @@ t1.par # State after crash recovery t1#P#p0.ibd t1#P#p10.ibd +t1#P#p20.ibd t1.frm t1.par SHOW CREATE TABLE t1; @@ -2740,7 +3861,8 @@ t1 CREATE TABLE `t1` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (a) (PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, - PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ + PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19) ENGINE = InnoDB, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = InnoDB) */ SELECT * FROM t1; a b 1 Original from partition p0 @@ -2861,8 +3983,6 @@ ALTER TABLE t1 REORGANIZE PARTITION p10 INTO PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); ERROR HY000: Lost connection to MySQL server during query # State after crash (before recovery) -#sql-t1.frm -#sql-t1.par t1#P#p0.ibd t1#P#p10#TMP#.ibd t1#P#p10.ibd @@ -3237,6 +4357,68 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_1"; SET SESSION debug="+d,fail_change_partition_2"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -3298,6 +4480,68 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_2"; SET SESSION debug="+d,fail_change_partition_3"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -3359,6 +4603,68 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_3"; SET SESSION debug="+d,fail_change_partition_4"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -3420,6 +4726,68 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_4"; SET SESSION debug="+d,fail_change_partition_5"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -3481,6 +4849,68 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_5"; SET SESSION debug="+d,fail_change_partition_6"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -3520,6 +4950,40 @@ ERROR HY000: Unknown error # State after failure t1#P#p0.ibd t1#P#p10.ibd +t1#P#p20.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19) ENGINE = InnoDB, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd t1.frm t1.par SHOW CREATE TABLE t1; @@ -3541,6 +5005,38 @@ a b 2 Original from partition p0 3 Original from partition p0 4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1#P#p20.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19) ENGINE = InnoDB, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_6"; SET SESSION debug="+d,fail_change_partition_7"; @@ -3605,6 +5101,70 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1#P#p20.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19) ENGINE = InnoDB, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_7"; SET SESSION debug="+d,fail_change_partition_8"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -3668,6 +5228,70 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1#P#p20.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19) ENGINE = InnoDB, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_8"; SET SESSION debug="+d,fail_change_partition_9"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -3731,6 +5355,70 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1#P#p20.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19) ENGINE = InnoDB, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_9"; SET SESSION debug="+d,fail_change_partition_10"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -3794,6 +5482,70 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1#P#p20.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19) ENGINE = InnoDB, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_10"; SET SESSION debug="+d,fail_change_partition_11"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -3857,6 +5609,70 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1#P#p20.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19) ENGINE = InnoDB, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_11"; SET SESSION debug="+d,fail_change_partition_12"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -3920,4 +5736,68 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'InnoDB' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.ibd +t1#P#p10.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.ibd +t1#P#p10.ibd +t1#P#p20.ibd +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = InnoDB, + PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19) ENGINE = InnoDB, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = InnoDB) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_12"; diff --git a/mysql-test/suite/parts/r/partition_debug_myisam.result b/mysql-test/suite/parts/r/partition_debug_myisam.result index d3f40aedee5..ca3dd708972 100644 --- a/mysql-test/suite/parts/r/partition_debug_myisam.result +++ b/mysql-test/suite/parts/r/partition_debug_myisam.result @@ -817,6 +817,71 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_1"; SET SESSION debug="+d,fail_add_partition_2"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -881,6 +946,71 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_2"; SET SESSION debug="+d,fail_add_partition_3"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -945,6 +1075,71 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_3"; SET SESSION debug="+d,fail_add_partition_4"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -1009,6 +1204,71 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_4"; SET SESSION debug="+d,fail_add_partition_5"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -1073,6 +1333,71 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_5"; SET SESSION debug="+d,fail_add_partition_6"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -1137,6 +1462,71 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_6"; SET SESSION debug="+d,fail_add_partition_7"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -1201,6 +1591,71 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_7"; SET SESSION debug="+d,fail_add_partition_8"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -1268,6 +1723,74 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1#P#p20.MYD +t1#P#p20.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_8"; SET SESSION debug="+d,fail_add_partition_9"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -1335,6 +1858,74 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1#P#p20.MYD +t1#P#p20.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_9"; SET SESSION debug="+d,fail_add_partition_10"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -1402,6 +1993,74 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 ADD PARTITION +(PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1#P#p20.MYD +t1#P#p20.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_add_partition_10"; # Test DROP PARTITION SET SESSION debug="+d,crash_drop_partition_1"; @@ -2061,6 +2720,70 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 DROP PARTITION p10; +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_drop_partition_1"; SET SESSION debug="+d,fail_drop_partition_2"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -2124,6 +2847,70 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 DROP PARTITION p10; +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_drop_partition_2"; SET SESSION debug="+d,fail_drop_partition_3"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -2187,6 +2974,70 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 DROP PARTITION p10; +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_drop_partition_3"; SET SESSION debug="+d,fail_drop_partition_4"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -2243,6 +3094,63 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 DROP PARTITION p10; +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_drop_partition_4"; SET SESSION debug="+d,fail_drop_partition_5"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -2299,6 +3207,63 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 DROP PARTITION p10; +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_drop_partition_5"; SET SESSION debug="+d,fail_drop_partition_6"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -2355,6 +3320,63 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 DROP PARTITION p10; +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_drop_partition_6"; SET SESSION debug="+d,fail_drop_partition_7"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -2411,6 +3433,63 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 DROP PARTITION p10; +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_drop_partition_7"; SET SESSION debug="+d,fail_drop_partition_8"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -2467,6 +3546,63 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 DROP PARTITION p10; +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_drop_partition_8"; SET SESSION debug="+d,fail_drop_partition_9"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -2523,6 +3659,63 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 DROP PARTITION p10; +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_drop_partition_9"; # Test change partition (REORGANIZE/REBUILD/COALESCE # or ADD HASH PARTITION). @@ -2957,6 +4150,8 @@ t1#P#p0.MYD t1#P#p0.MYI t1#P#p10.MYD t1#P#p10.MYI +t1#P#p20.MYD +t1#P#p20.MYI t1.frm t1.par SHOW CREATE TABLE t1; @@ -2967,7 +4162,8 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 /*!50100 PARTITION BY LIST (a) (PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, - PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ + PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19) ENGINE = MyISAM, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = MyISAM) */ SELECT * FROM t1; a b 1 Original from partition p0 @@ -3099,8 +4295,6 @@ ALTER TABLE t1 REORGANIZE PARTITION p10 INTO PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); ERROR HY000: Lost connection to MySQL server during query # State after crash (before recovery) -#sql-t1.frm -#sql-t1.par t1#P#p0.MYD t1#P#p0.MYI t1#P#p10#TMP#.MYD @@ -3520,6 +4714,72 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_1"; SET SESSION debug="+d,fail_change_partition_2"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -3585,6 +4845,72 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_2"; SET SESSION debug="+d,fail_change_partition_3"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -3650,6 +4976,72 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_3"; SET SESSION debug="+d,fail_change_partition_4"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -3715,6 +5107,72 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_4"; SET SESSION debug="+d,fail_change_partition_5"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -3780,6 +5238,72 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_5"; SET SESSION debug="+d,fail_change_partition_6"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -3823,6 +5347,43 @@ t1#P#p0.MYD t1#P#p0.MYI t1#P#p10.MYD t1#P#p10.MYI +t1#P#p20.MYD +t1#P#p20.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19) ENGINE = MyISAM, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI t1.frm t1.par SHOW CREATE TABLE t1; @@ -3844,6 +5405,41 @@ a b 2 Original from partition p0 3 Original from partition p0 4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1#P#p20.MYD +t1#P#p20.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19) ENGINE = MyISAM, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_6"; SET SESSION debug="+d,fail_change_partition_7"; @@ -3913,6 +5509,75 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1#P#p20.MYD +t1#P#p20.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19) ENGINE = MyISAM, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_7"; SET SESSION debug="+d,fail_change_partition_8"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -3981,6 +5646,75 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1#P#p20.MYD +t1#P#p20.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19) ENGINE = MyISAM, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_8"; SET SESSION debug="+d,fail_change_partition_9"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -4049,6 +5783,75 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1#P#p20.MYD +t1#P#p20.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19) ENGINE = MyISAM, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_9"; SET SESSION debug="+d,fail_change_partition_10"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -4117,6 +5920,75 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1#P#p20.MYD +t1#P#p20.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19) ENGINE = MyISAM, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_10"; SET SESSION debug="+d,fail_change_partition_11"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -4185,6 +6057,75 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1#P#p20.MYD +t1#P#p20.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19) ENGINE = MyISAM, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_11"; SET SESSION debug="+d,fail_change_partition_12"; CREATE TABLE t1 (a INT, b VARCHAR(64)) @@ -4253,4 +6194,73 @@ a b 3 Original from partition p0 4 Original from partition p0 DROP TABLE t1; +# Same test under LOCK TABLE +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = 'MyISAM' +PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9), +PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19)); +INSERT INTO t1 VALUES (1, "Original from partition p0"), (2, "Original from partition p0"), (3, "Original from partition p0"), (4, "Original from partition p0"), (11, "Original from partition p1"), (12, "Original from partition p1"), (13, "Original from partition p1"), (14, "Original from partition p1"); +# State before failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (11,12,13,14,15,16,17,18,19) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +LOCK TABLE t1 WRITE; +ALTER TABLE t1 REORGANIZE PARTITION p10 INTO +(PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19), +PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29)); +ERROR HY000: Unknown error +# State after failure +t1#P#p0.MYD +t1#P#p0.MYI +t1#P#p10.MYD +t1#P#p10.MYI +t1#P#p20.MYD +t1#P#p20.MYI +t1.frm +t1.par +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` varchar(64) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY LIST (a) +(PARTITION p0 VALUES IN (0,1,2,3,4,5,6,7,8,9) ENGINE = MyISAM, + PARTITION p10 VALUES IN (10,11,12,13,14,15,16,17,18,19) ENGINE = MyISAM, + PARTITION p20 VALUES IN (20,21,22,23,24,25,26,27,28,29) ENGINE = MyISAM) */ +SELECT * FROM t1; +a b +1 Original from partition p0 +11 Original from partition p1 +12 Original from partition p1 +13 Original from partition p1 +14 Original from partition p1 +2 Original from partition p0 +3 Original from partition p0 +4 Original from partition p0 +UNLOCK TABLES; +DROP TABLE t1; SET SESSION debug="-d,fail_change_partition_12"; diff --git a/mysql-test/suite/parts/r/partition_special_innodb.result b/mysql-test/suite/parts/r/partition_special_innodb.result index b8dffd61fbe..c1213e86afc 100644 --- a/mysql-test/suite/parts/r/partition_special_innodb.result +++ b/mysql-test/suite/parts/r/partition_special_innodb.result @@ -238,11 +238,10 @@ LOCK TABLE t1 READ; # Third attempt: says that the table does not exist ALTER TABLE t1 ADD PARTITION PARTITIONS 2; ERROR HY000: Lock wait timeout exceeded; try restarting transaction -# Check table returns the same +# Check table returns the same (not after fixing bug#56172!) CHECK TABLE t1; Table Op Msg_type Msg_text -test.t1 check Error Lock wait timeout exceeded; try restarting transaction -test.t1 check error Corrupt +test.t1 check status OK UNLOCK TABLES; DROP TABLE t1; CREATE TABLE t2 ( i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f INT ) diff --git a/mysql-test/suite/parts/t/partition_special_innodb.test b/mysql-test/suite/parts/t/partition_special_innodb.test index 9c26ab6fdb4..1c36299f4bd 100644 --- a/mysql-test/suite/parts/t/partition_special_innodb.test +++ b/mysql-test/suite/parts/t/partition_special_innodb.test @@ -111,7 +111,7 @@ LOCK TABLE t1 READ; --echo # Third attempt: says that the table does not exist --error ER_LOCK_WAIT_TIMEOUT ALTER TABLE t1 ADD PARTITION PARTITIONS 2; ---echo # Check table returns the same +--echo # Check table returns the same (not after fixing bug#56172!) CHECK TABLE t1; --connection con1 diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index b72816f8ce3..f7aba395ed8 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -70,6 +70,7 @@ #ifdef WITH_PARTITION_STORAGE_ENGINE #include "ha_partition.h" +/* TODO: Change abort() to DBUG_SUICIDE() when bug#52002 is pushed */ #define ERROR_INJECT_CRASH(code) \ DBUG_EVALUATE_IF(code, (abort(), 0), 0) #define ERROR_INJECT_ERROR(code) \ @@ -4353,43 +4354,31 @@ set_engine_all_partitions(partition_info *part_info, } } while (++i < part_info->num_parts); } -/* - SYNOPSIS - fast_end_partition() - thd Thread object - out:copied Number of records copied - out:deleted Number of records deleted - table_list Table list with the one table in it - empty Has nothing been done - lpt Struct to be used by error handler - RETURN VALUES - FALSE Success - TRUE Failure - DESCRIPTION - Support routine to handle the successful cases for partition - management. +/** + Support routine to handle the successful cases for partition management. + + @param thd Thread object + @param copied Number of records copied + @param deleted Number of records deleted + @param table_list Table list with the one table in it + + @return Operation status + @retval FALSE Success + @retval TRUE Failure */ static int fast_end_partition(THD *thd, ulonglong copied, ulonglong deleted, - TABLE_LIST *table_list, bool is_empty, - ALTER_PARTITION_PARAM_TYPE *lpt, - bool written_bin_log) + TABLE_LIST *table_list) { char tmp_name[80]; DBUG_ENTER("fast_end_partition"); thd->proc_info="end"; - if (!is_empty) - query_cache_invalidate3(thd, table_list, 0); - - if ((!is_empty) && (!written_bin_log) && - (!thd->lex->no_write_to_binlog) && - write_bin_log(thd, FALSE, thd->query(), thd->query_length())) - DBUG_RETURN(TRUE); + query_cache_invalidate3(thd, table_list, 0); my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO), (ulong) (copied + deleted), @@ -4511,29 +4500,25 @@ uint set_part_state(Alter_info *alter_info, partition_info *tab_part_info, } -/* +/** Prepare for ALTER TABLE of partition structure - SYNOPSIS - prep_alter_part_table() - thd Thread object - table Table object - inout:alter_info Alter information - inout:create_info Create info for CREATE TABLE - old_db_type Old engine type - out:partition_changed Boolean indicating whether partition changed - out:fast_alter_partition Boolean indicating whether fast partition - change is requested + @param[in] thd Thread object + @param[in] table Table object + @param[in,out] alter_info Alter information + @param[in,out] create_info Create info for CREATE TABLE + @param[in] old_db_type Old engine type + @param[out] partition_changed Boolean indicating whether partition changed + @param[out] fast_alter_table Internal temporary table allowing fast + partition change or NULL if not possible - RETURN VALUES - TRUE Error - FALSE Success - partition_changed - fast_alter_partition + @return Operation status + @retval TRUE Error + @retval FALSE Success - DESCRIPTION + @note This method handles all preparations for ALTER TABLE for partitioned - tables + tables. We need to handle both partition management command such as Add Partition and others here as well as an ALTER TABLE that completely changes the partitioning and yet others that don't change anything at all. We start @@ -4545,8 +4530,12 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, HA_CREATE_INFO *create_info, handlerton *old_db_type, bool *partition_changed, - uint *fast_alter_partition) + char *db, + const char *table_name, + const char *path, + TABLE **fast_alter_table) { + TABLE *new_table= NULL; DBUG_ENTER("prep_alter_part_table"); /* Foreign keys on partitioned tables are not supported, waits for WL#148 */ @@ -4555,15 +4544,9 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, my_error(ER_FOREIGN_KEY_ON_PARTITIONED, MYF(0)); DBUG_RETURN(TRUE); } - /* - We are going to manipulate the partition info on the table object - so we need to ensure that the table instance is removed from the - table cache. - */ - if (table->part_info) - table->m_needs_reopen= TRUE; thd->work_part_info= thd->lex->part_info; + if (thd->work_part_info && !(thd->work_part_info= thd->lex->part_info->get_clone())) DBUG_RETURN(TRUE); @@ -4576,7 +4559,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, ALTER_COALESCE_PARTITION | ALTER_REORGANIZE_PARTITION | ALTER_TABLE_REORG | ALTER_REBUILD_PARTITION)) { - partition_info *tab_part_info= table->part_info; + partition_info *tab_part_info; partition_info *alt_part_info= thd->work_part_info; uint flags= 0; bool is_last_partition_reorged= FALSE; @@ -4584,11 +4567,32 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, part_elem_value *alt_max_elem_val= NULL; longlong tab_max_range= 0, alt_max_range= 0; - if (!tab_part_info) + if (!table->part_info) { my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0)); DBUG_RETURN(TRUE); } + + /* + Open our intermediate table, we will operate on a temporary instance + of the original table, to be able to skip copying all partitions. + Open it as a copy of the original table, and modify its partition_info + object to allow fast_alter_partition_table to perform the changes. + */ + DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, table_name, + MDL_INTENTION_EXCLUSIVE)); + new_table= open_temporary_table(thd, path, db, table_name, 0); + if (!new_table) + DBUG_RETURN(TRUE); + + /* + This table may be used for copy rows between partitions + and also read/write columns when fixing the partition_info struct. + */ + new_table->use_all_columns(); + + tab_part_info= new_table->part_info; + if (alter_info->flags & ALTER_TABLE_REORG) { uint new_part_no, curr_part_no; @@ -4596,9 +4600,9 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, tab_part_info->use_default_num_partitions) { my_error(ER_REORG_NO_PARAM_ERROR, MYF(0)); - DBUG_RETURN(TRUE); + goto err; } - new_part_no= table->file->get_default_no_partitions(create_info); + new_part_no= new_table->file->get_default_no_partitions(create_info); curr_part_no= tab_part_info->num_parts; if (new_part_no == curr_part_no) { @@ -4607,7 +4611,8 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, after the change as before. Thus we can reply ok immediately without any changes at all. */ - *fast_alter_partition= TRUE; + *fast_alter_table= new_table; + thd->work_part_info= tab_part_info; DBUG_RETURN(FALSE); } else if (new_part_no > curr_part_no) @@ -4629,15 +4634,15 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, alter_info->num_parts= curr_part_no - new_part_no; } } - if (!(flags= table->file->alter_table_flags(alter_info->flags))) + if (!(flags= new_table->file->alter_table_flags(alter_info->flags))) { my_error(ER_PARTITION_FUNCTION_FAILURE, MYF(0)); - DBUG_RETURN(1); + goto err; } - *fast_alter_partition= - ((flags & (HA_FAST_CHANGE_PARTITION | HA_PARTITION_ONE_PHASE)) != 0); - DBUG_PRINT("info", ("*fast_alter_partition: %d flags: 0x%x", - *fast_alter_partition, flags)); + if ((flags & (HA_FAST_CHANGE_PARTITION | HA_PARTITION_ONE_PHASE)) != 0) + *fast_alter_table= new_table; + DBUG_PRINT("info", ("*fast_alter_table: %p flags: 0x%x", + *fast_alter_table, flags)); if ((alter_info->flags & ALTER_ADD_PARTITION) || (alter_info->flags & ALTER_REORGANIZE_PARTITION)) { @@ -4648,12 +4653,12 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, if (tab_part_info->part_type == RANGE_PARTITION) { my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0), "RANGE"); - DBUG_RETURN(TRUE); + goto err; } else if (tab_part_info->part_type == LIST_PARTITION) { my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0), "LIST"); - DBUG_RETURN(TRUE); + goto err; } /* Hash partitions can be altered without parser finds out about @@ -4684,7 +4689,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), "LIST", "IN"); } - DBUG_RETURN(TRUE); + goto err; } } if ((tab_part_info->column_list && @@ -4698,12 +4703,12 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, alt_part_info->num_columns != 0)) { my_error(ER_PARTITION_COLUMN_LIST_ERROR, MYF(0)); - DBUG_RETURN(TRUE); + goto err; } alt_part_info->column_list= tab_part_info->column_list; if (alt_part_info->fix_parser_data(thd)) { - DBUG_RETURN(TRUE); + goto err; } } if (alter_info->flags & ALTER_ADD_PARTITION) @@ -4726,17 +4731,17 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, tab_part_info->part_type != HASH_PARTITION) { my_error(ER_NO_BINLOG_ERROR, MYF(0)); - DBUG_RETURN(TRUE); + goto err; } if (tab_part_info->defined_max_value) { my_error(ER_PARTITION_MAXVALUE_ERROR, MYF(0)); - DBUG_RETURN(TRUE); + goto err; } if (num_new_partitions == 0) { my_error(ER_ADD_PARTITION_NO_NEW_PARTITION, MYF(0)); - DBUG_RETURN(TRUE); + goto err; } if (tab_part_info->is_sub_partitioned()) { @@ -4745,7 +4750,7 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, else if (alt_part_info->num_subparts != tab_part_info->num_subparts) { my_error(ER_ADD_PARTITION_SUBPART_ERROR, MYF(0)); - DBUG_RETURN(TRUE); + goto err; } check_total_partitions= new_total_partitions* alt_part_info->num_subparts; @@ -4753,15 +4758,15 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, if (check_total_partitions > MAX_PARTITIONS) { my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0)); - DBUG_RETURN(TRUE); + goto err; } alt_part_info->part_type= tab_part_info->part_type; alt_part_info->subpart_type= tab_part_info->subpart_type; - if (alt_part_info->set_up_defaults_for_partitioning(table->file, + if (alt_part_info->set_up_defaults_for_partitioning(new_table->file, ULL(0), tab_part_info->num_parts)) { - DBUG_RETURN(TRUE); + goto err; } /* Handling of on-line cases: @@ -4825,7 +4830,7 @@ adding and copying partitions, the second after completing the adding and copying and finally the third line after also dropping the partitions that are reorganised. */ - if (*fast_alter_partition && + if (*fast_alter_table && tab_part_info->part_type == HASH_PARTITION) { uint part_no= 0, start_part= 1, start_sec_part= 1; @@ -4930,12 +4935,12 @@ that are reorganised. do { partition_element *part_elem= alt_it++; - if (*fast_alter_partition) + if (*fast_alter_table) part_elem->part_state= PART_TO_BE_ADDED; if (tab_part_info->partitions.push_back(part_elem)) { mem_alloc_error(1); - DBUG_RETURN(TRUE); + goto err; } } while (++part_count < num_new_partitions); tab_part_info->num_parts+= num_new_partitions; @@ -4976,12 +4981,12 @@ that are reorganised. tab_part_info->part_type == LIST_PARTITION)) { my_error(ER_ONLY_ON_RANGE_LIST_PARTITION, MYF(0), "DROP"); - DBUG_RETURN(TRUE); + goto err; } if (num_parts_dropped >= tab_part_info->num_parts) { my_error(ER_DROP_LAST_PARTITION, MYF(0)); - DBUG_RETURN(TRUE); + goto err; } do { @@ -4999,12 +5004,12 @@ that are reorganised. if (num_parts_found != num_parts_dropped) { my_error(ER_DROP_PARTITION_NON_EXISTENT, MYF(0), "DROP"); - DBUG_RETURN(TRUE); + goto err; } - if (table->file->is_fk_defined_on_table_or_index(MAX_KEY)) + if (new_table->file->is_fk_defined_on_table_or_index(MAX_KEY)) { my_error(ER_ROW_IS_REFERENCED, MYF(0)); - DBUG_RETURN(TRUE); + goto err; } tab_part_info->num_parts-= num_parts_dropped; } @@ -5017,12 +5022,12 @@ that are reorganised. (!(alter_info->flags & ALTER_ALL_PARTITION))) { my_error(ER_DROP_PARTITION_NON_EXISTENT, MYF(0), "REBUILD"); - DBUG_RETURN(TRUE); + goto err; } - if (!(*fast_alter_partition)) + if (!(*fast_alter_table)) { - table->file->print_error(HA_ERR_WRONG_COMMAND, MYF(0)); - DBUG_RETURN(TRUE); + new_table->file->print_error(HA_ERR_WRONG_COMMAND, MYF(0)); + goto err; } } else if (alter_info->flags & ALTER_COALESCE_PARTITION) @@ -5033,17 +5038,17 @@ that are reorganised. if (tab_part_info->part_type != HASH_PARTITION) { my_error(ER_COALESCE_ONLY_ON_HASH_PARTITION, MYF(0)); - DBUG_RETURN(TRUE); + goto err; } if (num_parts_coalesced == 0) { my_error(ER_COALESCE_PARTITION_NO_PARTITION, MYF(0)); - DBUG_RETURN(TRUE); + goto err; } if (num_parts_coalesced >= tab_part_info->num_parts) { my_error(ER_DROP_LAST_PARTITION, MYF(0)); - DBUG_RETURN(TRUE); + goto err; } /* Online handling: @@ -5082,7 +5087,7 @@ state of p1. uint part_count= 0, start_part= 1, start_sec_part= 1; uint end_part= 0, end_sec_part= 0; bool all_parts= TRUE; - if (*fast_alter_partition && + if (*fast_alter_table && tab_part_info->linear_hash_ind) { uint upper_2n= tab_part_info->linear_hash_mask + 1; @@ -5108,14 +5113,14 @@ state of p1. do { partition_element *p_elem= part_it++; - if (*fast_alter_partition && + if (*fast_alter_table && (all_parts || (part_count >= start_part && part_count <= end_part) || (part_count >= start_sec_part && part_count <= end_sec_part))) p_elem->part_state= PART_CHANGED; if (++part_count > num_parts_remain) { - if (*fast_alter_partition) + if (*fast_alter_table) p_elem->part_state= PART_REORGED_DROPPED; else part_it.remove(); @@ -5150,38 +5155,38 @@ state of p1. if (num_parts_reorged > tab_part_info->num_parts) { my_error(ER_REORG_PARTITION_NOT_EXIST, MYF(0)); - DBUG_RETURN(TRUE); + goto err; } if (!(tab_part_info->part_type == RANGE_PARTITION || tab_part_info->part_type == LIST_PARTITION) && (num_parts_new != num_parts_reorged)) { my_error(ER_REORG_HASH_ONLY_ON_SAME_NO, MYF(0)); - DBUG_RETURN(TRUE); + goto err; } if (tab_part_info->is_sub_partitioned() && alt_part_info->num_subparts && alt_part_info->num_subparts != tab_part_info->num_subparts) { my_error(ER_PARTITION_WRONG_NO_SUBPART_ERROR, MYF(0)); - DBUG_RETURN(TRUE); + goto err; } check_total_partitions= tab_part_info->num_parts + num_parts_new; check_total_partitions-= num_parts_reorged; if (check_total_partitions > MAX_PARTITIONS) { my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0)); - DBUG_RETURN(TRUE); + goto err; } alt_part_info->part_type= tab_part_info->part_type; alt_part_info->subpart_type= tab_part_info->subpart_type; alt_part_info->num_subparts= tab_part_info->num_subparts; DBUG_ASSERT(!alt_part_info->use_default_partitions); - if (alt_part_info->set_up_defaults_for_partitioning(table->file, + if (alt_part_info->set_up_defaults_for_partitioning(new_table->file, ULL(0), 0)) { - DBUG_RETURN(TRUE); + goto err; } /* Online handling: @@ -5240,13 +5245,13 @@ the generated partition syntax in a correct manner. } else tab_max_range= part_elem->range_value; - if (*fast_alter_partition && + if (*fast_alter_table && tab_part_info->temp_partitions.push_back(part_elem)) { mem_alloc_error(1); - DBUG_RETURN(TRUE); + goto err; } - if (*fast_alter_partition) + if (*fast_alter_table) part_elem->part_state= PART_TO_BE_REORGED; if (!found_first) { @@ -5266,7 +5271,7 @@ the generated partition syntax in a correct manner. else alt_max_range= alt_part_elem->range_value; - if (*fast_alter_partition) + if (*fast_alter_table) alt_part_elem->part_state= PART_TO_BE_ADDED; if (alt_part_count == 0) tab_it.replace(alt_part_elem); @@ -5277,7 +5282,7 @@ the generated partition syntax in a correct manner. else if (found_last) { my_error(ER_CONSECUTIVE_REORG_PARTITIONS, MYF(0)); - DBUG_RETURN(TRUE); + goto err; } else tab_it.remove(); @@ -5291,7 +5296,7 @@ the generated partition syntax in a correct manner. if (drop_count != num_parts_reorged) { my_error(ER_DROP_PARTITION_NON_EXISTENT, MYF(0), "REORGANIZE"); - DBUG_RETURN(TRUE); + goto err; } tab_part_info->num_parts= check_total_partitions; } @@ -5312,9 +5317,9 @@ the generated partition syntax in a correct manner. tab_part_info->use_default_num_subpartitions= FALSE; } if (tab_part_info->check_partition_info(thd, (handlerton**)NULL, - table->file, ULL(0), TRUE)) + new_table->file, ULL(0), TRUE)) { - DBUG_RETURN(TRUE); + goto err; } /* The check below needs to be performed after check_partition_info @@ -5346,7 +5351,7 @@ the generated partition syntax in a correct manner. to create "holes". */ my_error(ER_REORG_OUTSIDE_RANGE, MYF(0)); - DBUG_RETURN(TRUE); + goto err; } } } @@ -5463,7 +5468,7 @@ the generated partition syntax in a correct manner. *partition_changed= TRUE; if (thd->work_part_info->fix_parser_data(thd)) { - DBUG_RETURN(TRUE); + goto err; } } /* @@ -5484,7 +5489,7 @@ the generated partition syntax in a correct manner. if (check_native_partitioned(create_info, &is_native_partitioned, part_info, thd)) { - DBUG_RETURN(TRUE); + goto err; } if (!is_native_partitioned) { @@ -5494,6 +5499,17 @@ the generated partition syntax in a correct manner. } } DBUG_RETURN(FALSE); +err: + if (new_table) + { + /* + Only remove the intermediate table object and its share object, + do not remove the .frm file, since it is the original one. + */ + close_temporary(new_table, 1, 0); + } + *fast_alter_table= NULL; + DBUG_RETURN(TRUE); } @@ -5536,6 +5552,11 @@ static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) if(mysql_trans_prepare_alter_copy_data(thd)) DBUG_RETURN(TRUE); + if (file->ha_external_lock(thd, F_WRLCK)) + DBUG_RETURN(TRUE); + + /* TODO: test if bulk_insert would increase the performance */ + if ((error= file->ha_change_partitions(lpt->create_info, path, &lpt->copied, &lpt->deleted, lpt->pack_frm_data, lpt->pack_frm_len))) @@ -5544,7 +5565,10 @@ static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) } if (mysql_trans_commit_alter_copy_data(thd)) - DBUG_RETURN(TRUE); /* The error has been reported */ + error= 1; /* The error has been reported */ + + if (file->ha_external_lock(thd, F_UNLCK)) + error= 1; DBUG_RETURN(test(error)); } @@ -6294,8 +6318,18 @@ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt) { THD *thd= lpt->thd; - close_all_tables_for_name(thd, lpt->table->s, FALSE); + if (lpt->old_table) + close_all_tables_for_name(thd, lpt->old_table->s, FALSE); + if (lpt->table) + { + /* + Only remove the intermediate table object and its share object, + do not remove the .frm file, since it is the original one. + */ + close_temporary(lpt->table, 1, 0); + } lpt->table= 0; + lpt->old_table= 0; lpt->table_list->table= 0; if (thd->locked_tables_list.reopen_tables(thd)) sql_print_warning("We failed to reacquire LOCKs in ALTER TABLE"); @@ -6307,62 +6341,40 @@ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt) SYNOPSIS alter_close_tables() lpt Struct carrying parameters + close_old Close original table too RETURN VALUES 0 */ -static int alter_close_tables(ALTER_PARTITION_PARAM_TYPE *lpt) +static int alter_close_tables(ALTER_PARTITION_PARAM_TYPE *lpt, bool close_old) { - TABLE_SHARE *share= lpt->table->s; - THD *thd= lpt->thd; - TABLE *table; DBUG_ENTER("alter_close_tables"); - /* - We must keep LOCK_open while manipulating with thd->open_tables. - Another thread may be working on it. - */ - mysql_mutex_lock(&LOCK_open); - /* - We can safely remove locks for all tables with the same name: - later they will all be closed anyway in - alter_partition_lock_handling(). - */ - for (table= thd->open_tables; table ; table= table->next) + if (lpt->table->db_stat) { - if (!strcmp(table->s->table_name.str, share->table_name.str) && - !strcmp(table->s->db.str, share->db.str)) - { - mysql_lock_remove(thd, thd->lock, table); - table->file->close(); - table->db_stat= 0; // Mark file closed - /* - Ensure that we won't end up with a crippled table instance - in the table cache if an error occurs before we reach - alter_partition_lock_handling() and the table is closed - by close_thread_tables() instead. - */ - tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED, - table->s->db.str, - table->s->table_name.str, TRUE); - } + lpt->table->file->close(); + lpt->table->db_stat= 0; // Mark file closed + } + if (close_old && lpt->old_table) + { + close_all_tables_for_name(lpt->thd, lpt->old_table->s, FALSE); + lpt->old_table= 0; } - mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(0); } -/* - Handle errors for ALTER TABLE for partitioning - SYNOPSIS - handle_alter_part_error() - lpt Struct carrying parameters - not_completed Was request in complete phase when error occurred - RETURN VALUES - NONE +/** + Handle errors for ALTER TABLE for partitioning. + + @param lpt Struct carrying parameters + @param action_completed The action must be completed, NOT reverted + @param drop_partition Partitions has not been dropped yet + @param frm_install The shadow frm-file has not yet been installed + @param close_table Table is still open, close it before reverting */ void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt, - bool not_completed, + bool action_completed, bool drop_partition, bool frm_install, bool close_table) @@ -6379,7 +6391,7 @@ void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt, so we clone it first to have a copy. */ part_info= lpt->part_info->get_clone(); - alter_close_tables(lpt); + alter_close_tables(lpt, action_completed); } if (part_info->first_log_entry && @@ -6392,7 +6404,7 @@ void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt, */ write_log_completed(lpt, FALSE); release_log_entries(part_info); - if (not_completed) + if (!action_completed) { if (drop_partition) { @@ -6457,7 +6469,7 @@ void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt, else { release_log_entries(part_info); - if (not_completed) + if (!action_completed) { /* We hit an error before things were completed but managed @@ -6500,25 +6512,24 @@ static void downgrade_mdl_if_lock_tables_mode(THD *thd, MDL_ticket *ticket, } -/* +/** Actually perform the change requested by ALTER TABLE of partitions previously prepared. - SYNOPSIS - fast_alter_partition_table() - thd Thread object - table Table object - alter_info ALTER TABLE info - create_info Create info for CREATE TABLE - table_list List of the table involved - db Database name of new table - table_name Table name of new table + @param thd Thread object + @param table Original table object + @param alter_info ALTER TABLE info + @param create_info Create info for CREATE TABLE + @param table_list List of the table involved + @param db Database name of new table + @param table_name Table name of new table + @param fast_alter_table Prepared table object - RETURN VALUES - TRUE Error - FALSE Success + @return Operation status + @retval TRUE Error + @retval FALSE Success - DESCRIPTION + @note Perform all ALTER TABLE operations for partitioned tables that can be performed fast without a full copy of the original table. */ @@ -6529,19 +6540,20 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, TABLE_LIST *table_list, char *db, const char *table_name, - uint fast_alter_partition) + TABLE *fast_alter_table) { /* Set-up struct used to write frm files */ - partition_info *part_info= table->part_info; + partition_info *part_info; ALTER_PARTITION_PARAM_TYPE lpt_obj; ALTER_PARTITION_PARAM_TYPE *lpt= &lpt_obj; - bool written_bin_log= TRUE; - bool not_completed= TRUE; + bool action_completed= FALSE; bool close_table_on_failure= FALSE; bool frm_install= FALSE; MDL_ticket *mdl_ticket= table->mdl_ticket; + DBUG_ASSERT(fast_alter_table); DBUG_ENTER("fast_alter_partition_table"); + part_info= fast_alter_table->part_info; lpt->thd= thd; lpt->table_list= table_list; lpt->part_info= part_info; @@ -6550,7 +6562,8 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, lpt->db_options= create_info->table_options; if (create_info->row_type == ROW_TYPE_DYNAMIC) lpt->db_options|= HA_OPTION_PACK_RECORD; - lpt->table= table; + lpt->table= fast_alter_table; + lpt->old_table= table; lpt->key_info_buffer= 0; lpt->key_count= 0; lpt->db= db; @@ -6559,12 +6572,12 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, lpt->deleted= 0; lpt->pack_frm_data= NULL; lpt->pack_frm_len= 0; - thd->work_part_info= part_info; /* Never update timestamp columns when alter */ - table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; + lpt->table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; - if (fast_alter_partition & HA_PARTITION_ONE_PHASE) + if (table->file->alter_table_flags(alter_info->flags) & + HA_PARTITION_ONE_PHASE) { /* In the case where the engine supports one phase online partition @@ -6681,11 +6694,11 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, ERROR_INJECT_ERROR("fail_drop_partition_3") || (close_table_on_failure= TRUE, FALSE) || write_log_drop_partition(lpt) || + (action_completed= TRUE, FALSE) || ERROR_INJECT_CRASH("crash_drop_partition_4") || ERROR_INJECT_ERROR("fail_drop_partition_4") || + alter_close_tables(lpt, action_completed) || (close_table_on_failure= FALSE, FALSE) || - (not_completed= FALSE, FALSE) || - alter_close_tables(lpt) || ERROR_INJECT_CRASH("crash_drop_partition_5") || ERROR_INJECT_ERROR("fail_drop_partition_5") || ((!thd->lex->no_write_to_binlog) && @@ -6706,7 +6719,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, ERROR_INJECT_ERROR("fail_drop_partition_9") || (alter_partition_lock_handling(lpt), FALSE)) { - handle_alter_part_error(lpt, not_completed, TRUE, frm_install, + handle_alter_part_error(lpt, action_completed, TRUE, frm_install, close_table_on_failure); goto err; } @@ -6761,7 +6774,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, ERROR_INJECT_CRASH("crash_add_partition_5") || ERROR_INJECT_ERROR("fail_add_partition_5") || (close_table_on_failure= FALSE, FALSE) || - alter_close_tables(lpt) || + alter_close_tables(lpt, action_completed) || ERROR_INJECT_CRASH("crash_add_partition_6") || ERROR_INJECT_ERROR("fail_add_partition_6") || ((!thd->lex->no_write_to_binlog) && @@ -6770,11 +6783,12 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, ERROR_INJECT_CRASH("crash_add_partition_7") || ERROR_INJECT_ERROR("fail_add_partition_7") || write_log_rename_frm(lpt) || - (frm_install= TRUE, FALSE) || - (not_completed= FALSE, FALSE) || + (action_completed= TRUE, FALSE) || ERROR_INJECT_CRASH("crash_add_partition_8") || ERROR_INJECT_ERROR("fail_add_partition_8") || + (frm_install= TRUE, FALSE) || mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) || + (frm_install= FALSE, FALSE) || ERROR_INJECT_CRASH("crash_add_partition_9") || ERROR_INJECT_ERROR("fail_add_partition_9") || (write_log_completed(lpt, FALSE), FALSE) || @@ -6782,7 +6796,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, ERROR_INJECT_ERROR("fail_add_partition_10") || (alter_partition_lock_handling(lpt), FALSE)) { - handle_alter_part_error(lpt, not_completed, FALSE, frm_install, + handle_alter_part_error(lpt, action_completed, FALSE, frm_install, close_table_on_failure); goto err; } @@ -6831,10 +6845,10 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, can release all other locks on the table and since no one can open the table, there can be no new threads accessing the table. They will be hanging on this exclusive lock. - 5) Close all instances of the table and remove them from the table cache. - 6) Log that operation is completed and log all complete actions + 5) Log that operation is completed and log all complete actions needed to complete operation from here - 7) Write bin log + 6) Write bin log + 7) Close all instances of the table and remove them from the table cache. 8) Prepare handlers for rename and delete of partitions 9) Rename and drop the reorged partitions such that they are no longer used and rename those added to their real new names. @@ -6858,27 +6872,28 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN) || ERROR_INJECT_CRASH("crash_change_partition_5") || ERROR_INJECT_ERROR("fail_change_partition_5") || - alter_close_tables(lpt) || - (close_table_on_failure= FALSE) || + write_log_final_change_partition(lpt) || + (action_completed= TRUE, FALSE) || ERROR_INJECT_CRASH("crash_change_partition_6") || ERROR_INJECT_ERROR("fail_change_partition_6") || - write_log_final_change_partition(lpt) || - (not_completed= FALSE) || - ERROR_INJECT_CRASH("crash_change_partition_7") || - ERROR_INJECT_ERROR("fail_change_partition_7") || ((!thd->lex->no_write_to_binlog) && (write_bin_log(thd, FALSE, thd->query(), thd->query_length()), FALSE)) || + ERROR_INJECT_CRASH("crash_change_partition_7") || + ERROR_INJECT_ERROR("fail_change_partition_7") || + ((frm_install= TRUE), FALSE) || + mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) || + (frm_install= FALSE, FALSE) || ERROR_INJECT_CRASH("crash_change_partition_8") || ERROR_INJECT_ERROR("fail_change_partition_8") || - mysql_write_frm(lpt, WFRM_INSTALL_SHADOW) || + alter_close_tables(lpt, action_completed) || + (close_table_on_failure= FALSE, FALSE) || ERROR_INJECT_CRASH("crash_change_partition_9") || ERROR_INJECT_ERROR("fail_change_partition_9") || mysql_drop_partitions(lpt) || ERROR_INJECT_CRASH("crash_change_partition_10") || ERROR_INJECT_ERROR("fail_change_partition_10") || mysql_rename_partitions(lpt) || - ((frm_install= TRUE), FALSE) || ERROR_INJECT_CRASH("crash_change_partition_11") || ERROR_INJECT_ERROR("fail_change_partition_11") || (write_log_completed(lpt, FALSE), FALSE) || @@ -6886,7 +6901,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, ERROR_INJECT_ERROR("fail_change_partition_12") || (alter_partition_lock_handling(lpt), FALSE)) { - handle_alter_part_error(lpt, not_completed, FALSE, frm_install, + handle_alter_part_error(lpt, action_completed, FALSE, frm_install, close_table_on_failure); goto err; } @@ -6896,12 +6911,25 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, A final step is to write the query to the binlog and send ok to the user */ - DBUG_RETURN(fast_end_partition(thd, lpt->copied, lpt->deleted, - table_list, FALSE, NULL, - written_bin_log)); + DBUG_RETURN(fast_end_partition(thd, lpt->copied, lpt->deleted, table_list)); err: + if (action_completed) + { + /* + Although error occurred, the action was forced to retry for completion. + Therefore we must close+reopen all instances of the table. + */ + (void) alter_partition_lock_handling(lpt); + } + else + { + /* + The failed action was reverted, leave the original table as is and + close/destroy the intermediate table object and its share. + */ + close_temporary(lpt->table, 1, 0); + } downgrade_mdl_if_lock_tables_mode(thd, mdl_ticket, MDL_SHARED_NO_READ_WRITE); - table->m_needs_reopen= TRUE; DBUG_RETURN(TRUE); } #endif diff --git a/sql/sql_partition.h b/sql/sql_partition.h index c644e63794c..9a9a0bd56fa 100644 --- a/sql/sql_partition.h +++ b/sql/sql_partition.h @@ -54,6 +54,7 @@ typedef struct st_lock_param_type HA_CREATE_INFO *create_info; Alter_info *alter_info; TABLE *table; + TABLE *old_table; KEY *key_info_buffer; const char *db; const char *table_name; @@ -252,14 +253,17 @@ uint fast_alter_partition_table(THD *thd, TABLE *table, TABLE_LIST *table_list, char *db, const char *table_name, - uint fast_alter_partition); + TABLE *fast_alter_table); uint set_part_state(Alter_info *alter_info, partition_info *tab_part_info, enum partition_state part_state); uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info, HA_CREATE_INFO *create_info, handlerton *old_db_type, bool *partition_changed, - uint *fast_alter_partition); + char *db, + const char *table_name, + const char *path, + TABLE **fast_alter_table); char *generate_partition_syntax(partition_info *part_info, uint *buf_length, bool use_sql_alloc, bool show_partition_options, diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 3f0a0326c84..0b66352c056 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1725,8 +1725,6 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) CHF_DELETE_FLAG, NULL) || deactivate_ddl_log_entry(part_info->frm_log_entry->entry_pos) || (sync_ddl_log(), FALSE) || -#endif -#ifdef WITH_PARTITION_STORAGE_ENGINE mysql_file_rename(key_file_frm, shadow_frm_name, frm_name, MYF(MY_WME)) || lpt->table->file->ha_create_handler_files(path, shadow_path, @@ -5599,7 +5597,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, handlerton *old_db_type, *new_db_type, *save_old_db_type; enum_alter_table_change_level need_copy_table= ALTER_TABLE_METADATA_ONLY; #ifdef WITH_PARTITION_STORAGE_ENGINE - uint fast_alter_partition= 0; + TABLE *table_for_fast_alter_partition= NULL; bool partition_changed= FALSE; #endif bool need_lock_for_indexes= TRUE; @@ -5968,7 +5966,9 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, #ifdef WITH_PARTITION_STORAGE_ENGINE if (prep_alter_part_table(thd, table, alter_info, create_info, old_db_type, - &partition_changed, &fast_alter_partition)) + &partition_changed, + db, table_name, path, + &table_for_fast_alter_partition)) goto err; #endif /* @@ -6201,12 +6201,12 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, create_info->frm_only= 1; #ifdef WITH_PARTITION_STORAGE_ENGINE - if (fast_alter_partition) + if (table_for_fast_alter_partition) { DBUG_RETURN(fast_alter_partition_table(thd, table, alter_info, create_info, table_list, db, table_name, - fast_alter_partition)); + table_for_fast_alter_partition)); } #endif @@ -6686,6 +6686,11 @@ err_new_table_cleanup: create_info->frm_only ? FN_IS_TMP | FRM_ONLY : FN_IS_TMP); err: +#ifdef WITH_PARTITION_STORAGE_ENGINE + /* If prep_alter_part_table created an intermediate table, destroy it. */ + if (table_for_fast_alter_partition) + close_temporary(table_for_fast_alter_partition, 1, 0); +#endif /* WITH_PARTITION_STORAGE_ENGINE */ /* No default value was provided for a DATE/DATETIME field, the current sql_mode doesn't allow the '0000-00-00' value and From 814fbc5b6f2bf40c91bfb01dfa1bcf711af01d76 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Fri, 1 Oct 2010 13:39:04 +0200 Subject: [PATCH 147/159] Bug#51851: Server with SBR locks mutex twice on LOAD DATA into partitioned MyISAM table Problem was that both partitioning and myisam used the same table_share->mutex for different protections (auto inc and repair). Solved by adding a specific mutex for the partitioning auto_increment. Also adding destroying the ha_data structure in free_table_share (which is to be propagated into 5.5). This is a 5.1 ONLY patch, already fixed in 5.5+. --- mysql-test/r/partition_binlog_stmt.result | 13 ++++++++++++ mysql-test/t/partition_binlog_stmt.test | 26 +++++++++++++++++++++++ sql/ha_partition.cc | 17 +++++++++++++++ sql/ha_partition.h | 7 ++++-- sql/table.cc | 10 +++++++++ sql/table.h | 1 + 6 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 mysql-test/r/partition_binlog_stmt.result create mode 100644 mysql-test/t/partition_binlog_stmt.test diff --git a/mysql-test/r/partition_binlog_stmt.result b/mysql-test/r/partition_binlog_stmt.result new file mode 100644 index 00000000000..9be23636ca6 --- /dev/null +++ b/mysql-test/r/partition_binlog_stmt.result @@ -0,0 +1,13 @@ +DROP TABLE IF EXISTS t1; +# +# Bug#51851: Server with SBR locks mutex twice on LOAD DATA into +# partitioned MyISAM table +CREATE TABLE t1 +(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, +name TINYBLOB NOT NULL, +modified TIMESTAMP DEFAULT '0000-00-00 00:00:00', +INDEX namelocs (name(255))) ENGINE = MyISAM +PARTITION BY HASH(id) PARTITIONS 2; +LOAD DATA LOCAL INFILE 'init_file.txt' +INTO TABLE t1 (name); +DROP TABLE t1; diff --git a/mysql-test/t/partition_binlog_stmt.test b/mysql-test/t/partition_binlog_stmt.test new file mode 100644 index 00000000000..c426de9f303 --- /dev/null +++ b/mysql-test/t/partition_binlog_stmt.test @@ -0,0 +1,26 @@ +--source include/have_partition.inc +--source include/have_binlog_format_statement.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +--echo # +--echo # Bug#51851: Server with SBR locks mutex twice on LOAD DATA into +--echo # partitioned MyISAM table +--write_file init_file.txt +abcd +EOF + +CREATE TABLE t1 +(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, + name TINYBLOB NOT NULL, + modified TIMESTAMP DEFAULT '0000-00-00 00:00:00', + INDEX namelocs (name(255))) ENGINE = MyISAM +PARTITION BY HASH(id) PARTITIONS 2; + +LOAD DATA LOCAL INFILE 'init_file.txt' +INTO TABLE t1 (name); + +--remove_file init_file.txt +DROP TABLE t1; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 624ef1aff5b..6806e9c5ac0 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -2449,6 +2449,21 @@ err1: /**************************************************************************** MODULE open/close object ****************************************************************************/ + + +/** + A destructor for partition-specific TABLE_SHARE data. +*/ + +void ha_data_partition_destroy(void *ha_data) +{ + if (ha_data) + { + HA_DATA_PARTITION *ha_part_data= (HA_DATA_PARTITION*) ha_data; + pthread_mutex_destroy(&ha_part_data->LOCK_auto_inc); + } +} + /* Open handler object @@ -2605,6 +2620,8 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) } DBUG_PRINT("info", ("table_share->ha_data 0x%p", ha_data)); bzero(ha_data, sizeof(HA_DATA_PARTITION)); + table_share->ha_data_destroy= ha_data_partition_destroy; + VOID(pthread_mutex_init(&ha_data->LOCK_auto_inc, MY_MUTEX_INIT_FAST)); } if (is_not_tmp_table) pthread_mutex_unlock(&table_share->mutex); diff --git a/sql/ha_partition.h b/sql/ha_partition.h index e3dc7d17c6d..cb5440a0b69 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -44,6 +44,7 @@ typedef struct st_partition_share typedef struct st_ha_data_partition { ulonglong next_auto_inc_val; /**< first non reserved value */ + pthread_mutex_t LOCK_auto_inc; bool auto_inc_initialized; } HA_DATA_PARTITION; @@ -944,8 +945,9 @@ private: DBUG_ASSERT(table_share->ha_data && !auto_increment_lock); if(table_share->tmp_table == NO_TMP_TABLE) { + HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data; auto_increment_lock= TRUE; - pthread_mutex_lock(&table_share->mutex); + pthread_mutex_lock(&ha_data->LOCK_auto_inc); } } virtual void unlock_auto_increment() @@ -958,7 +960,8 @@ private: */ if(auto_increment_lock && !auto_increment_safe_stmt_log_lock) { - pthread_mutex_unlock(&table_share->mutex); + HA_DATA_PARTITION *ha_data= (HA_DATA_PARTITION*) table_share->ha_data; + pthread_mutex_unlock(&ha_data->LOCK_auto_inc); auto_increment_lock= FALSE; } } diff --git a/sql/table.cc b/sql/table.cc index e989ab039a0..18523f08551 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -425,6 +425,11 @@ void free_table_share(TABLE_SHARE *share) key_info->flags= 0; } } + if (share->ha_data_destroy) + { + share->ha_data_destroy(share->ha_data); + share->ha_data_destroy= NULL; + } /* We must copy mem_root from share because share is allocated through it */ memcpy((char*) &mem_root, (char*) &share->mem_root, sizeof(mem_root)); free_root(&mem_root, MYF(0)); // Free's share @@ -1616,6 +1621,11 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, delete crypted; delete handler_file; hash_free(&share->name_hash); + if (share->ha_data_destroy) + { + share->ha_data_destroy(share->ha_data); + share->ha_data_destroy= NULL; + } open_table_error(share, error, share->open_errno, errarg); DBUG_RETURN(error); diff --git a/sql/table.h b/sql/table.h index bbb39aae6f7..132279169cb 100644 --- a/sql/table.h +++ b/sql/table.h @@ -463,6 +463,7 @@ typedef struct st_table_share /** place to store storage engine specific data */ void *ha_data; + void (*ha_data_destroy)(void *); /* An optional destructor for ha_data. */ /* From 75fc5b6a332a2c8e2d2640ca5e553e785711172b Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Fri, 1 Oct 2010 14:51:00 +0300 Subject: [PATCH 148/159] Fix a potential bug when using __sync_lock_test_and_set() This is a manual merge from mysql-5.1-innodb of: revision-id: vasil.dimov@oracle.com-20100930102618-s9f9ytbytr3eqw9h committer: Vasil Dimov timestamp: Thu 2010-09-30 13:26:18 +0300 message: Fix a potential bug when using __sync_lock_test_and_set() TYPE __sync_lock_test_and_set (TYPE *ptr, TYPE value, ...) it is not documented what happens if the two arguments are of different type like it was before: the first one was lock_word_t (byte) and the second one was 1 or 0 (int). Approved by: Marko (via IRC) --- storage/innobase/include/os0sync.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/include/os0sync.h b/storage/innobase/include/os0sync.h index 0b600c80ce3..ec5ccee3e27 100644 --- a/storage/innobase/include/os0sync.h +++ b/storage/innobase/include/os0sync.h @@ -289,7 +289,7 @@ amount of increment. */ Returns the old value of *ptr, atomically sets *ptr to new_val */ # define os_atomic_test_and_set_byte(ptr, new_val) \ - __sync_lock_test_and_set(ptr, new_val) + __sync_lock_test_and_set(ptr, (byte) new_val) #elif defined(HAVE_IB_SOLARIS_ATOMICS) From 53fe2b31f2aaf8aae7b0a12881ff8dbc7d59770f Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Fri, 1 Oct 2010 15:30:16 +0200 Subject: [PATCH 149/159] removed a comment according to the review --- sql/partition_info.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 879e7b10023..b54339db354 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -1997,7 +1997,6 @@ int partition_info::fix_partition_values(THD *thd, } else if (item_expr->result_type() != INT_RESULT) { - /* VALUES clause only allowed on partitions, not subpartitions */ my_error(ER_VALUES_IS_NOT_INT_TYPE_ERROR, MYF(0), part_elem->partition_name); DBUG_RETURN(TRUE); From 29acd776433ac91183255ed7117954931f76827f Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Fri, 1 Oct 2010 18:10:45 +0200 Subject: [PATCH 150/159] minor test result update after merge --- mysql-test/r/partition_error.result | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/partition_error.result b/mysql-test/r/partition_error.result index 830ca4bee10..a1e95727235 100644 --- a/mysql-test/r/partition_error.result +++ b/mysql-test/r/partition_error.result @@ -72,6 +72,8 @@ a 2000-01-02 03:04:05 2001-02-03 04:05:06 ALTER TABLE t1 ADD PARTITION PARTITIONS 2; +Warnings: +Warning 1486 Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed ALTER TABLE t1 PARTITION BY RANGE (TO_DAYS(a)) (PARTITION p0 VALUES LESS THAN (10000), @@ -84,8 +86,6 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (TO_DAYS(a)) PARTITIONS 3 */ -Warnings: -Warning 1486 Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table From e33e27a6643e426a6143cf725a480ecd5a22899e Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Fri, 1 Oct 2010 21:32:40 +0200 Subject: [PATCH 151/159] Minor update of test to pass both with and without --ps-protocol --- mysql-test/r/partition_error.result | 5 +++-- mysql-test/t/partition_error.test | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/partition_error.result b/mysql-test/r/partition_error.result index a1e95727235..27f34730463 100644 --- a/mysql-test/r/partition_error.result +++ b/mysql-test/r/partition_error.result @@ -55,11 +55,12 @@ SELECT * FROM t1; a 2000-01-02 03:04:05 FLUSH TABLES; +# replacing t1.frm with TO_DAYS(a) which was allowed earlier. +# Disable warnings, since the result would differ when running with +# --ps-protocol (only for the 'SELECT * FROM t1' statement). SELECT * FROM t1; a 2000-01-02 03:04:05 -Warning 1486 Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed -Warnings: SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( diff --git a/mysql-test/t/partition_error.test b/mysql-test/t/partition_error.test index 1afb65d496c..73afa9b5216 100644 --- a/mysql-test/t/partition_error.test +++ b/mysql-test/t/partition_error.test @@ -74,10 +74,15 @@ INSERT INTO t1 VALUES ('2000-01-02 03:04:05'); --sorted_result SELECT * FROM t1; FLUSH TABLES; +--echo # replacing t1.frm with TO_DAYS(a) which was allowed earlier. --remove_file $MYSQLD_DATADIR/test/t1.frm --copy_file std_data/parts/t1TIMESTAMP.frm $MYSQLD_DATADIR/test/t1.frm +--echo # Disable warnings, since the result would differ when running with +--echo # --ps-protocol (only for the 'SELECT * FROM t1' statement). +--disable_warnings --sorted_result SELECT * FROM t1; +--enable_warnings SHOW CREATE TABLE t1; INSERT INTO t1 VALUES ('2001-02-03 04:05:06'); --sorted_result From c443ee433393ab991c8c4be11f772906eb26fd7a Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Sun, 3 Oct 2010 19:39:28 +0200 Subject: [PATCH 152/159] Small test fix after 56753 --- mysql-test/suite/innodb_plugin/t/innodb_bug53756.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug53756.test b/mysql-test/suite/innodb_plugin/t/innodb_bug53756.test index 0623be1d0ae..8c48550a64d 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb_bug53756.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug53756.test @@ -34,8 +34,8 @@ INSERT INTO bug_53756 VALUES(1, 11), (2, 22), (3, 33), (4, 44); --echo --echo # Select a less restrictive isolation level. # Don't use user variables. They won't survive server crash. ---let $global_isolation= `SELECT @@global.tx_isolation`; ---let $session_isolation= `SELECT @@session.tx_isolation`; +--let $global_isolation= `SELECT @@global.tx_isolation` +--let $session_isolation= `SELECT @@session.tx_isolation` SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED; SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; COMMIT; From 0548d66df4c99de30fb12e5d56525460a69db9b2 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Mon, 4 Oct 2010 12:01:16 +0200 Subject: [PATCH 153/159] Follow-up to 54861, cannot assume pthread_t is integral type --- client/mysqltest.cc | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 5f28c000ac3..2ec4edc1b61 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -259,6 +259,7 @@ struct st_connection pthread_mutex_t result_mutex; pthread_cond_t result_cond; int query_done; + my_bool has_thread; #endif /*EMBEDDED_LIBRARY*/ }; @@ -770,7 +771,7 @@ end_thread: static void wait_query_thread_done(struct st_connection *con) { - DBUG_ASSERT(con->tid); + DBUG_ASSERT(con->has_thread); if (!con->query_done) { pthread_mutex_lock(&con->result_mutex); @@ -783,7 +784,7 @@ static void wait_query_thread_done(struct st_connection *con) static void signal_connection_thd(struct st_connection *cn, int command) { - DBUG_ASSERT(cn->tid); + DBUG_ASSERT(cn->has_thread); cn->query_done= 0; cn->command= command; pthread_mutex_lock(&cn->query_mutex); @@ -795,13 +796,13 @@ static void signal_connection_thd(struct st_connection *cn, int command) /* Sometimes we try to execute queries when the connection is closed. It's done to make sure it was closed completely. - So that if our connection is closed (cn->tid == 0), we just return + So that if our connection is closed (cn->has_thread == 0), we just return the mysql_send_query() result which is an error in this case. */ static int do_send_query(struct st_connection *cn, const char *q, int q_len) { - if (!cn->tid) + if (!cn->has_thread) return mysql_send_query(&cn->mysql, q, q_len); cn->cur_query= q; cn->cur_query_len= q_len; @@ -811,7 +812,7 @@ static int do_send_query(struct st_connection *cn, const char *q, int q_len) static int do_read_query_result(struct st_connection *cn) { - DBUG_ASSERT(cn->tid); + DBUG_ASSERT(cn->has_thread); wait_query_thread_done(cn); signal_connection_thd(cn, EMB_READ_QUERY_RESULT); wait_query_thread_done(cn); @@ -822,12 +823,12 @@ static int do_read_query_result(struct st_connection *cn) static void emb_close_connection(struct st_connection *cn) { - if (!cn->tid) + if (!cn->has_thread) return; wait_query_thread_done(cn); signal_connection_thd(cn, EMB_END_CONNECTION); pthread_join(cn->tid, NULL); - cn->tid= 0; + cn->has_thread= FALSE; pthread_mutex_destroy(&cn->query_mutex); pthread_cond_destroy(&cn->query_cond); pthread_mutex_destroy(&cn->result_mutex); @@ -845,6 +846,7 @@ static void init_connection_thd(struct st_connection *cn) pthread_cond_init(&cn->result_cond, NULL) || pthread_create(&cn->tid, &cn_thd_attrib, connection_thread, (void*)cn)) die("Error in the thread library"); + cn->has_thread=TRUE; } #else /*EMBEDDED_LIBRARY*/ From 678bc90ed8b416dbf68f590caae3a3d36c544b12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 4 Oct 2010 13:05:21 +0300 Subject: [PATCH 154/159] Bug#56716 InnoDB locks a record gap without locking the table row_search_for_mysql(): Acquire an intention lock on the table before locking the first record gap. --- .../suite/innodb/r/innodb_bug56716.result | 4 ++ .../suite/innodb/t/innodb_bug56716.test | 10 +++ storage/innobase/row/row0sel.c | 72 +++++++++---------- 3 files changed, 50 insertions(+), 36 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug56716.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug56716.test diff --git a/mysql-test/suite/innodb/r/innodb_bug56716.result b/mysql-test/suite/innodb/r/innodb_bug56716.result new file mode 100644 index 00000000000..50d83e8d87a --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug56716.result @@ -0,0 +1,4 @@ +CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB; +SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE; +a b c +DROP TABLE bug56716; diff --git a/mysql-test/suite/innodb/t/innodb_bug56716.test b/mysql-test/suite/innodb/t/innodb_bug56716.test new file mode 100644 index 00000000000..3345038d9c1 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug56716.test @@ -0,0 +1,10 @@ +# +# Bug #56716 InnoDB locks a record gap without locking the table +# +-- source include/have_innodb.inc + +CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB; + +SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE; + +DROP TABLE bug56716; diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index 06a19ba7979..a64dd3151ee 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -3599,6 +3599,42 @@ shortcut_fails_too_big_rec: clust_index = dict_table_get_first_index(index->table); + /* Do some start-of-statement preparations */ + + if (!prebuilt->sql_stat_start) { + /* No need to set an intention lock or assign a read view */ + + if (trx->read_view == NULL + && prebuilt->select_lock_type == LOCK_NONE) { + + fputs("InnoDB: Error: MySQL is trying to" + " perform a consistent read\n" + "InnoDB: but the read view is not assigned!\n", + stderr); + trx_print(stderr, trx, 600); + fputc('\n', stderr); + ut_error; + } + } else if (prebuilt->select_lock_type == LOCK_NONE) { + /* This is a consistent read */ + /* Assign a read view for the query */ + + trx_assign_read_view(trx); + prebuilt->sql_stat_start = FALSE; + } else { + err = lock_table(0, index->table, + prebuilt->select_lock_type == LOCK_S + ? LOCK_IS : LOCK_IX, thr); + + if (err != DB_SUCCESS) { + + goto lock_wait_or_error; + } + prebuilt->sql_stat_start = FALSE; + } + + /* Open or restore index cursor position */ + if (UNIV_LIKELY(direction != 0)) { ibool need_to_process = sel_restore_position_for_mysql( &same_user_rec, BTR_SEARCH_LEAF, @@ -3674,42 +3710,6 @@ shortcut_fails_too_big_rec: } } - if (!prebuilt->sql_stat_start) { - /* No need to set an intention lock or assign a read view */ - - if (trx->read_view == NULL - && prebuilt->select_lock_type == LOCK_NONE) { - - fputs("InnoDB: Error: MySQL is trying to" - " perform a consistent read\n" - "InnoDB: but the read view is not assigned!\n", - stderr); - trx_print(stderr, trx, 600); - fputc('\n', stderr); - ut_a(0); - } - } else if (prebuilt->select_lock_type == LOCK_NONE) { - /* This is a consistent read */ - /* Assign a read view for the query */ - - trx_assign_read_view(trx); - prebuilt->sql_stat_start = FALSE; - } else { - ulint lock_mode; - if (prebuilt->select_lock_type == LOCK_S) { - lock_mode = LOCK_IS; - } else { - lock_mode = LOCK_IX; - } - err = lock_table(0, index->table, lock_mode, thr); - - if (err != DB_SUCCESS) { - - goto lock_wait_or_error; - } - prebuilt->sql_stat_start = FALSE; - } - rec_loop: /*-------------------------------------------------------------*/ /* PHASE 4: Look for matching records in a loop */ From 190ebda206be4a8375976090c79e9cf89af4799e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 4 Oct 2010 13:06:41 +0300 Subject: [PATCH 155/159] Bug#56716 InnoDB locks a record gap without locking the table row_search_for_mysql(): Acquire an intention lock on the table before locking the first record gap. --- .../innodb_plugin/r/innodb_bug56716.result | 4 ++ .../innodb_plugin/t/innodb_bug56716.test | 10 +++ storage/innodb_plugin/ChangeLog | 5 ++ storage/innodb_plugin/row/row0sel.c | 72 +++++++++---------- 4 files changed, 55 insertions(+), 36 deletions(-) create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug56716.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug56716.test diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug56716.result b/mysql-test/suite/innodb_plugin/r/innodb_bug56716.result new file mode 100644 index 00000000000..50d83e8d87a --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug56716.result @@ -0,0 +1,4 @@ +CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB; +SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE; +a b c +DROP TABLE bug56716; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug56716.test b/mysql-test/suite/innodb_plugin/t/innodb_bug56716.test new file mode 100644 index 00000000000..24e90f5acc5 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug56716.test @@ -0,0 +1,10 @@ +# +# Bug #56716 InnoDB locks a record gap without locking the table +# +-- source include/have_innodb_plugin.inc + +CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB; + +SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE; + +DROP TABLE bug56716; diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 19ff64562fc..986750c28bf 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,8 @@ +2010-09-27 The InnoDB Team + + * row/row0sel.c, innodb_bug56716.result, innodb_bug56716.test: + Fix Bug #56716 InnoDB locks a record gap without locking the table + 2010-09-06 The InnoDB Team * dict/dict0load.c, innodb_bug53756.test innodb_bug53756.result Fix Bug #53756 ALTER TABLE ADD PRIMARY KEY affects crash recovery diff --git a/storage/innodb_plugin/row/row0sel.c b/storage/innodb_plugin/row/row0sel.c index aff36b65124..8b17bdc6ad3 100644 --- a/storage/innodb_plugin/row/row0sel.c +++ b/storage/innodb_plugin/row/row0sel.c @@ -3719,6 +3719,42 @@ release_search_latch_if_needed: clust_index = dict_table_get_first_index(index->table); + /* Do some start-of-statement preparations */ + + if (!prebuilt->sql_stat_start) { + /* No need to set an intention lock or assign a read view */ + + if (trx->read_view == NULL + && prebuilt->select_lock_type == LOCK_NONE) { + + fputs("InnoDB: Error: MySQL is trying to" + " perform a consistent read\n" + "InnoDB: but the read view is not assigned!\n", + stderr); + trx_print(stderr, trx, 600); + fputc('\n', stderr); + ut_error; + } + } else if (prebuilt->select_lock_type == LOCK_NONE) { + /* This is a consistent read */ + /* Assign a read view for the query */ + + trx_assign_read_view(trx); + prebuilt->sql_stat_start = FALSE; + } else { + err = lock_table(0, index->table, + prebuilt->select_lock_type == LOCK_S + ? LOCK_IS : LOCK_IX, thr); + + if (err != DB_SUCCESS) { + + goto lock_wait_or_error; + } + prebuilt->sql_stat_start = FALSE; + } + + /* Open or restore index cursor position */ + if (UNIV_LIKELY(direction != 0)) { ibool need_to_process = sel_restore_position_for_mysql( &same_user_rec, BTR_SEARCH_LEAF, @@ -3794,42 +3830,6 @@ release_search_latch_if_needed: } } - if (!prebuilt->sql_stat_start) { - /* No need to set an intention lock or assign a read view */ - - if (trx->read_view == NULL - && prebuilt->select_lock_type == LOCK_NONE) { - - fputs("InnoDB: Error: MySQL is trying to" - " perform a consistent read\n" - "InnoDB: but the read view is not assigned!\n", - stderr); - trx_print(stderr, trx, 600); - fputc('\n', stderr); - ut_a(0); - } - } else if (prebuilt->select_lock_type == LOCK_NONE) { - /* This is a consistent read */ - /* Assign a read view for the query */ - - trx_assign_read_view(trx); - prebuilt->sql_stat_start = FALSE; - } else { - ulint lock_mode; - if (prebuilt->select_lock_type == LOCK_S) { - lock_mode = LOCK_IS; - } else { - lock_mode = LOCK_IX; - } - err = lock_table(0, index->table, lock_mode, thr); - - if (err != DB_SUCCESS) { - - goto lock_wait_or_error; - } - prebuilt->sql_stat_start = FALSE; - } - rec_loop: /*-------------------------------------------------------------*/ /* PHASE 4: Look for matching records in a loop */ From 80961a0a25b127111c5704e846d890405b5bc5a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 4 Oct 2010 13:38:05 +0300 Subject: [PATCH 156/159] Merge Bug#56716 from 5.1 --- .../suite/innodb/r/innodb_bug56716.result | 4 ++ .../suite/innodb/t/innodb_bug56716.test | 10 +++ storage/innobase/row/row0sel.c | 72 +++++++++---------- 3 files changed, 50 insertions(+), 36 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug56716.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug56716.test diff --git a/mysql-test/suite/innodb/r/innodb_bug56716.result b/mysql-test/suite/innodb/r/innodb_bug56716.result new file mode 100644 index 00000000000..50d83e8d87a --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug56716.result @@ -0,0 +1,4 @@ +CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB; +SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE; +a b c +DROP TABLE bug56716; diff --git a/mysql-test/suite/innodb/t/innodb_bug56716.test b/mysql-test/suite/innodb/t/innodb_bug56716.test new file mode 100644 index 00000000000..3345038d9c1 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug56716.test @@ -0,0 +1,10 @@ +# +# Bug #56716 InnoDB locks a record gap without locking the table +# +-- source include/have_innodb.inc + +CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB; + +SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE; + +DROP TABLE bug56716; diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index 945eab74924..61ef4edb7a6 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -3711,6 +3711,42 @@ release_search_latch_if_needed: clust_index = dict_table_get_first_index(index->table); + /* Do some start-of-statement preparations */ + + if (!prebuilt->sql_stat_start) { + /* No need to set an intention lock or assign a read view */ + + if (trx->read_view == NULL + && prebuilt->select_lock_type == LOCK_NONE) { + + fputs("InnoDB: Error: MySQL is trying to" + " perform a consistent read\n" + "InnoDB: but the read view is not assigned!\n", + stderr); + trx_print(stderr, trx, 600); + fputc('\n', stderr); + ut_error; + } + } else if (prebuilt->select_lock_type == LOCK_NONE) { + /* This is a consistent read */ + /* Assign a read view for the query */ + + trx_assign_read_view(trx); + prebuilt->sql_stat_start = FALSE; + } else { + err = lock_table(0, index->table, + prebuilt->select_lock_type == LOCK_S + ? LOCK_IS : LOCK_IX, thr); + + if (err != DB_SUCCESS) { + + goto lock_wait_or_error; + } + prebuilt->sql_stat_start = FALSE; + } + + /* Open or restore index cursor position */ + if (UNIV_LIKELY(direction != 0)) { ibool need_to_process = sel_restore_position_for_mysql( &same_user_rec, BTR_SEARCH_LEAF, @@ -3786,42 +3822,6 @@ release_search_latch_if_needed: } } - if (!prebuilt->sql_stat_start) { - /* No need to set an intention lock or assign a read view */ - - if (trx->read_view == NULL - && prebuilt->select_lock_type == LOCK_NONE) { - - fputs("InnoDB: Error: MySQL is trying to" - " perform a consistent read\n" - "InnoDB: but the read view is not assigned!\n", - stderr); - trx_print(stderr, trx, 600); - fputc('\n', stderr); - ut_a(0); - } - } else if (prebuilt->select_lock_type == LOCK_NONE) { - /* This is a consistent read */ - /* Assign a read view for the query */ - - trx_assign_read_view(trx); - prebuilt->sql_stat_start = FALSE; - } else { - ulint lock_mode; - if (prebuilt->select_lock_type == LOCK_S) { - lock_mode = LOCK_IS; - } else { - lock_mode = LOCK_IX; - } - err = lock_table(0, index->table, lock_mode, thr); - - if (err != DB_SUCCESS) { - - goto lock_wait_or_error; - } - prebuilt->sql_stat_start = FALSE; - } - rec_loop: /*-------------------------------------------------------------*/ /* PHASE 4: Look for matching records in a loop */ From 367bfa41066bfe88b720f530e938e2c4cbf79205 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 4 Oct 2010 13:03:11 +0200 Subject: [PATCH 157/159] A follow-up to the patch for bug #56405 "Deadlock in the MDL deadlock detector". This patch addresses performance regression in OLTP_RO/MyISAM test on Windows introduced by the fix for bug #56405. Thus it makes original patch acceptable as a solution for bug #56585 "Slowdown of readonly sysbench benchmarks (e.g point_select) on Windows 5.5". With this patch, MySQL will use native Windows condition variables and reader-writer locks if they are supported by the OS. This speeds up MyISAM and the effect comes mostly from using native rwlocks. Native conditions improve scalability with higher number of concurrent users in other situations, e.g for prlocks. Benchmark numbers for this patch as measured on Win2008R2 quad core machine are attached to the bug report. ( direct link http://bugs.mysql.com/file.php?id=15883 ) Note that currently we require at least Windows7/WS2008R2 for reader-writer locks, even though native rwlock is available also on Vista. Reason is that "trylock" APIs are missing on Vista, and trylock is used in the server (in a single place in query cache). While this patch could have been written differently, to enable the native rwlock optimization also on Vista/WS2008 (e.g using native locks everywhere but portable implementation in query cache), this would come at the expense of the code clarity, as it would introduce a new "try-able" rwlock type, to handle Vista case. Another way to improve performance for the special case (OLTP_RO/MYISAM/Vista) would be to eliminate "trylock" usage from server, but this is outside of the scope here. Native conditions variables are used beginning with Vista though the effect of using condition variables alone is not measurable in this benchmark. But when used together with native rwlocks on Win7, native conditions improve performance in high-concurrency OLTP_RO/MyISAM (128 and more sysbench users). --- include/my_pthread.h | 78 ++++++++++++--- mysys/my_wincond.c | 232 +++++++++++++++++++++++++++++++++++-------- mysys/my_winthread.c | 15 ++- mysys/thr_rwlock.c | 160 +++++++++++++++++++++++++++++ 4 files changed, 429 insertions(+), 56 deletions(-) diff --git a/include/my_pthread.h b/include/my_pthread.h index 27ab5ba23fe..d3053b4861a 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -48,19 +48,30 @@ typedef struct st_pthread_link { struct st_pthread_link *next; } pthread_link; -typedef struct { - uint32 waiting; - CRITICAL_SECTION lock_waiting; - - enum { - SIGNAL= 0, - BROADCAST= 1, - MAX_EVENTS= 2 - } EVENTS; - - HANDLE events[MAX_EVENTS]; - HANDLE broadcast_block_event; +/** + Implementation of Windows condition variables. + We use native conditions on Vista and later, and fallback to own + implementation on earlier OS version. +*/ +typedef union +{ + /* Native condition (used on Vista and later) */ + CONDITION_VARIABLE native_cond; + /* Own implementation (used on XP) */ + struct + { + uint32 waiting; + CRITICAL_SECTION lock_waiting; + enum + { + SIGNAL= 0, + BROADCAST= 1, + MAX_EVENTS= 2 + } EVENTS; + HANDLE events[MAX_EVENTS]; + HANDLE broadcast_block_event; + }; } pthread_cond_t; @@ -679,6 +690,47 @@ extern int rw_pr_destroy(rw_pr_lock_t *); #ifdef NEED_MY_RW_LOCK + +#ifdef _WIN32 + +/** + Implementation of Windows rwlock. + + We use native (slim) rwlocks on Win7 and later, and fallback to portable + implementation on earlier Windows. + + slim rwlock are also available on Vista/WS2008, but we do not use it + ("trylock" APIs are missing on Vista) +*/ +typedef union +{ + /* Native rwlock (is_srwlock == TRUE) */ + struct + { + SRWLOCK srwlock; /* native reader writer lock */ + BOOL have_exclusive_srwlock; /* used for unlock */ + }; + + /* + Portable implementation (is_srwlock == FALSE) + Fields are identical with Unix my_rw_lock_t fields. + */ + struct + { + pthread_mutex_t lock; /* lock for structure */ + pthread_cond_t readers; /* waiting readers */ + pthread_cond_t writers; /* waiting writers */ + int state; /* -1:writer,0:free,>0:readers */ + int waiters; /* number of waiting writers */ +#ifdef SAFE_MUTEX + pthread_t write_thread; +#endif + }; +} my_rw_lock_t; + + +#else /* _WIN32 */ + /* On systems which don't support native read/write locks we have to use own implementation. @@ -694,6 +746,8 @@ typedef struct st_my_rw_lock_t { #endif } my_rw_lock_t; +#endif /*! _WIN32 */ + extern int my_rw_init(my_rw_lock_t *); extern int my_rw_destroy(my_rw_lock_t *); extern int my_rw_rdlock(my_rw_lock_t *); diff --git a/mysys/my_wincond.c b/mysys/my_wincond.c index ad1636011db..58c09e332d6 100644 --- a/mysys/my_wincond.c +++ b/mysys/my_wincond.c @@ -24,7 +24,108 @@ #include #include -int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) + +/* + Windows native condition variables. We use runtime loading / function + pointers, because they are not available on XP +*/ + +/* Prototypes and function pointers for condition variable functions */ +typedef VOID (WINAPI * InitializeConditionVariableProc) + (PCONDITION_VARIABLE ConditionVariable); + +typedef BOOL (WINAPI * SleepConditionVariableCSProc) + (PCONDITION_VARIABLE ConditionVariable, + PCRITICAL_SECTION CriticalSection, + DWORD dwMilliseconds); + +typedef VOID (WINAPI * WakeAllConditionVariableProc) + (PCONDITION_VARIABLE ConditionVariable); + +typedef VOID (WINAPI * WakeConditionVariableProc) + (PCONDITION_VARIABLE ConditionVariable); + +static InitializeConditionVariableProc my_InitializeConditionVariable; +static SleepConditionVariableCSProc my_SleepConditionVariableCS; +static WakeAllConditionVariableProc my_WakeAllConditionVariable; +static WakeConditionVariableProc my_WakeConditionVariable; + + +/** + Indicates if we have native condition variables, + initialized first time pthread_cond_init is called. +*/ + +static BOOL have_native_conditions= FALSE; + + +/** + Check if native conditions can be used, load function pointers +*/ + +static void check_native_cond_availability(void) +{ + HMODULE module= GetModuleHandle("kernel32"); + + my_InitializeConditionVariable= (InitializeConditionVariableProc) + GetProcAddress(module, "InitializeConditionVariable"); + my_SleepConditionVariableCS= (SleepConditionVariableCSProc) + GetProcAddress(module, "SleepConditionVariableCS"); + my_WakeAllConditionVariable= (WakeAllConditionVariableProc) + GetProcAddress(module, "WakeAllConditionVariable"); + my_WakeConditionVariable= (WakeConditionVariableProc) + GetProcAddress(module, "WakeConditionVariable"); + + if (my_InitializeConditionVariable) + have_native_conditions= TRUE; +} + + + +/** + Convert abstime to milliseconds +*/ + +static DWORD get_milliseconds(const struct timespec *abstime) +{ + long long millis; + union ft64 now; + + if (abstime == NULL) + return INFINITE; + + GetSystemTimeAsFileTime(&now.ft); + + /* + Calculate time left to abstime + - subtract start time from current time(values are in 100ns units) + - convert to millisec by dividing with 10000 + */ + millis= (abstime->tv.i64 - now.i64) / 10000; + + /* Don't allow the timeout to be negative */ + if (millis < 0) + return 0; + + /* + Make sure the calculated timeout does not exceed original timeout + value which could cause "wait for ever" if system time changes + */ + if (millis > abstime->max_timeout_msec) + millis= abstime->max_timeout_msec; + + if (millis > UINT_MAX) + millis= UINT_MAX; + + return (DWORD)millis; +} + + +/* + Old (pre-vista) implementation using events +*/ + +static int legacy_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) { cond->waiting= 0; InitializeCriticalSection(&cond->lock_waiting); @@ -53,7 +154,8 @@ int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) return 0; } -int pthread_cond_destroy(pthread_cond_t *cond) + +static int legacy_cond_destroy(pthread_cond_t *cond) { DeleteCriticalSection(&cond->lock_waiting); @@ -65,48 +167,13 @@ int pthread_cond_destroy(pthread_cond_t *cond) } -int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) -{ - return pthread_cond_timedwait(cond,mutex,NULL); -} - - -int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, +static int legacy_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *abstime) { int result; - long timeout; - union ft64 now; - - if( abstime != NULL ) - { - GetSystemTimeAsFileTime(&now.ft); - - /* - Calculate time left to abstime - - subtract start time from current time(values are in 100ns units) - - convert to millisec by dividing with 10000 - */ - timeout= (long)((abstime->tv.i64 - now.i64) / 10000); - - /* Don't allow the timeout to be negative */ - if (timeout < 0) - timeout= 0L; - - /* - Make sure the calucated timeout does not exceed original timeout - value which could cause "wait for ever" if system time changes - */ - if (timeout > abstime->max_timeout_msec) - timeout= abstime->max_timeout_msec; - - } - else - { - /* No time specified; don't expire */ - timeout= INFINITE; - } + DWORD timeout; + timeout= get_milliseconds(abstime); /* Block access if previous broadcast hasn't finished. This is just for safety and should normally not @@ -142,7 +209,7 @@ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, return result == WAIT_TIMEOUT ? ETIMEDOUT : 0; } -int pthread_cond_signal(pthread_cond_t *cond) +static int legacy_cond_signal(pthread_cond_t *cond) { EnterCriticalSection(&cond->lock_waiting); @@ -155,7 +222,7 @@ int pthread_cond_signal(pthread_cond_t *cond) } -int pthread_cond_broadcast(pthread_cond_t *cond) +static int legacy_cond_broadcast(pthread_cond_t *cond) { EnterCriticalSection(&cond->lock_waiting); /* @@ -177,6 +244,87 @@ int pthread_cond_broadcast(pthread_cond_t *cond) } +/* + Posix API functions. Just choose between native and legacy implementation. +*/ + +int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) +{ + /* + Once initialization is used here rather than in my_init(), to + 1) avoid my_init() pitfalls- undefined order in which initialization should + run + 2) be potentially useful C++ (in static constructors that run before main()) + 3) just to simplify the API. + Also, the overhead of my_pthread_once is very small. + */ + static my_pthread_once_t once_control= MY_PTHREAD_ONCE_INIT; + my_pthread_once(&once_control, check_native_cond_availability); + + if (have_native_conditions) + { + my_InitializeConditionVariable(&cond->native_cond); + return 0; + } + else + return legacy_cond_init(cond, attr); +} + + +int pthread_cond_destroy(pthread_cond_t *cond) +{ + if (have_native_conditions) + return 0; /* no destroy function */ + else + return legacy_cond_destroy(cond); +} + + +int pthread_cond_broadcast(pthread_cond_t *cond) +{ + if (have_native_conditions) + { + my_WakeAllConditionVariable(&cond->native_cond); + return 0; + } + else + return legacy_cond_broadcast(cond); +} + + +int pthread_cond_signal(pthread_cond_t *cond) +{ + if (have_native_conditions) + { + my_WakeConditionVariable(&cond->native_cond); + return 0; + } + else + return legacy_cond_signal(cond); +} + + +int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, + struct timespec *abstime) +{ + if (have_native_conditions) + { + DWORD timeout= get_milliseconds(abstime); + if (!my_SleepConditionVariableCS(&cond->native_cond, mutex, timeout)) + return ETIMEDOUT; + return 0; + } + else + return legacy_cond_timedwait(cond, mutex, abstime); +} + + +int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) +{ + return pthread_cond_timedwait(cond, mutex, NULL); +} + + int pthread_attr_init(pthread_attr_t *connect_att) { connect_att->dwStackSize = 0; diff --git a/mysys/my_winthread.c b/mysys/my_winthread.c index aecb2f7cc78..49534370a2f 100644 --- a/mysys/my_winthread.c +++ b/mysys/my_winthread.c @@ -155,8 +155,19 @@ int pthread_cancel(pthread_t thread) int my_pthread_once(my_pthread_once_t *once_control, void (*init_routine)(void)) { - LONG state= InterlockedCompareExchange(once_control, MY_PTHREAD_ONCE_INPROGRESS, - MY_PTHREAD_ONCE_INIT); + LONG state; + + /* + Do "dirty" read to find out if initialization is already done, to + save an interlocked operation in common case. Memory barriers are ensured by + Visual C++ volatile implementation. + */ + if (*once_control == MY_PTHREAD_ONCE_DONE) + return 0; + + state= InterlockedCompareExchange(once_control, MY_PTHREAD_ONCE_INPROGRESS, + MY_PTHREAD_ONCE_INIT); + switch(state) { case MY_PTHREAD_ONCE_INIT: diff --git a/mysys/thr_rwlock.c b/mysys/thr_rwlock.c index 218cfb251c8..13651221d37 100644 --- a/mysys/thr_rwlock.c +++ b/mysys/thr_rwlock.c @@ -20,6 +20,119 @@ #if defined(NEED_MY_RW_LOCK) #include +#ifdef _WIN32 + +static BOOL have_srwlock= FALSE; +/* Prototypes and function pointers for windows functions */ +typedef VOID (WINAPI* srw_func) (PSRWLOCK SRWLock); +typedef BOOL (WINAPI* srw_bool_func) (PSRWLOCK SRWLock); + +static srw_func my_InitializeSRWLock; +static srw_func my_AcquireSRWLockExclusive; +static srw_func my_ReleaseSRWLockExclusive; +static srw_func my_AcquireSRWLockShared; +static srw_func my_ReleaseSRWLockShared; + +static srw_bool_func my_TryAcquireSRWLockExclusive; +static srw_bool_func my_TryAcquireSRWLockShared; + +/** + Check for presence of Windows slim reader writer lock function. + Load function pointers. +*/ + +static void check_srwlock_availability(void) +{ + HMODULE module= GetModuleHandle("kernel32"); + + my_InitializeSRWLock= (srw_func) GetProcAddress(module, + "InitializeSRWLock"); + my_AcquireSRWLockExclusive= (srw_func) GetProcAddress(module, + "AcquireSRWLockExclusive"); + my_AcquireSRWLockShared= (srw_func) GetProcAddress(module, + "AcquireSRWLockShared"); + my_ReleaseSRWLockExclusive= (srw_func) GetProcAddress(module, + "ReleaseSRWLockExclusive"); + my_ReleaseSRWLockShared= (srw_func) GetProcAddress(module, + "ReleaseSRWLockShared"); + my_TryAcquireSRWLockExclusive= (srw_bool_func) GetProcAddress(module, + "TryAcquireSRWLockExclusive"); + my_TryAcquireSRWLockShared= (srw_bool_func) GetProcAddress(module, + "TryAcquireSRWLockShared"); + + /* + We currently require TryAcquireSRWLockExclusive. This API is missing on + Vista, this means SRWLock are only used starting with Win7. + + If "trylock" usage for rwlocks is eliminated from server codebase (it is used + in a single place currently, in query cache), then SRWLock can be enabled on + Vista too. In this case condition below needs to be changed to e.g check + for my_InitializeSRWLock. + */ + + if (my_TryAcquireSRWLockExclusive) + have_srwlock= TRUE; + +} + + +static int srw_init(my_rw_lock_t *rwp) +{ + my_InitializeSRWLock(&rwp->srwlock); + rwp->have_exclusive_srwlock = FALSE; + return 0; +} + + +static int srw_rdlock(my_rw_lock_t *rwp) +{ + my_AcquireSRWLockShared(&rwp->srwlock); + return 0; +} + + +static int srw_tryrdlock(my_rw_lock_t *rwp) +{ + + if (!my_TryAcquireSRWLockShared(&rwp->srwlock)) + return EBUSY; + return 0; +} + + +static int srw_wrlock(my_rw_lock_t *rwp) +{ + my_AcquireSRWLockExclusive(&rwp->srwlock); + rwp->have_exclusive_srwlock= TRUE; + return 0; +} + + +static int srw_trywrlock(my_rw_lock_t *rwp) +{ + if (!my_TryAcquireSRWLockExclusive(&rwp->srwlock)) + return EBUSY; + rwp->have_exclusive_srwlock= TRUE; + return 0; +} + + +static int srw_unlock(my_rw_lock_t *rwp) +{ + if (rwp->have_exclusive_srwlock) + { + rwp->have_exclusive_srwlock= FALSE; + my_ReleaseSRWLockExclusive(&rwp->srwlock); + } + else + { + my_ReleaseSRWLockShared(&rwp->srwlock); + } + return 0; +} + +#endif /*_WIN32 */ + /* Source base from Sun Microsystems SPILT, simplified for MySQL use -- Joshua Chamas @@ -63,6 +176,22 @@ int my_rw_init(my_rw_lock_t *rwp) { pthread_condattr_t cond_attr; +#ifdef _WIN32 + /* + Once initialization is used here rather than in my_init(), in order to + - avoid my_init() pitfalls- (undefined order in which initialization should + run) + - be potentially useful C++ (static constructors) + - just to simplify the API. + Also, the overhead is of my_pthread_once is very small. + */ + static my_pthread_once_t once_control= MY_PTHREAD_ONCE_INIT; + my_pthread_once(&once_control, check_srwlock_availability); + + if (have_srwlock) + return srw_init(rwp); +#endif + pthread_mutex_init( &rwp->lock, MY_MUTEX_INIT_FAST); pthread_condattr_init( &cond_attr ); pthread_cond_init( &rwp->readers, &cond_attr ); @@ -81,6 +210,10 @@ int my_rw_init(my_rw_lock_t *rwp) int my_rw_destroy(my_rw_lock_t *rwp) { +#ifdef _WIN32 + if (have_srwlock) + return 0; /* no destroy function */ +#endif DBUG_ASSERT(rwp->state == 0); pthread_mutex_destroy( &rwp->lock ); pthread_cond_destroy( &rwp->readers ); @@ -91,6 +224,11 @@ int my_rw_destroy(my_rw_lock_t *rwp) int my_rw_rdlock(my_rw_lock_t *rwp) { +#ifdef _WIN32 + if (have_srwlock) + return srw_rdlock(rwp); +#endif + pthread_mutex_lock(&rwp->lock); /* active or queued writers */ @@ -105,6 +243,12 @@ int my_rw_rdlock(my_rw_lock_t *rwp) int my_rw_tryrdlock(my_rw_lock_t *rwp) { int res; + +#ifdef _WIN32 + if (have_srwlock) + return srw_tryrdlock(rwp); +#endif + pthread_mutex_lock(&rwp->lock); if ((rwp->state < 0 ) || rwp->waiters) res= EBUSY; /* Can't get lock */ @@ -120,6 +264,11 @@ int my_rw_tryrdlock(my_rw_lock_t *rwp) int my_rw_wrlock(my_rw_lock_t *rwp) { +#ifdef _WIN32 + if (have_srwlock) + return srw_wrlock(rwp); +#endif + pthread_mutex_lock(&rwp->lock); rwp->waiters++; /* another writer queued */ @@ -140,6 +289,12 @@ int my_rw_wrlock(my_rw_lock_t *rwp) int my_rw_trywrlock(my_rw_lock_t *rwp) { int res; + +#ifdef _WIN32 + if (have_srwlock) + return srw_trywrlock(rwp); +#endif + pthread_mutex_lock(&rwp->lock); if (rwp->state) res= EBUSY; /* Can't get lock */ @@ -158,6 +313,11 @@ int my_rw_trywrlock(my_rw_lock_t *rwp) int my_rw_unlock(my_rw_lock_t *rwp) { +#ifdef _WIN32 + if (have_srwlock) + return srw_unlock(rwp); +#endif + DBUG_PRINT("rw_unlock", ("state: %d waiters: %d", rwp->state, rwp->waiters)); pthread_mutex_lock(&rwp->lock); From 24b1a8971248fc23419064947d21ac8cd444c4d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 4 Oct 2010 13:38:05 +0300 Subject: [PATCH 158/159] Merge Bug#56716 from 5.1 --- .../suite/innodb/r/innodb_bug56716.result | 4 ++ .../suite/innodb/t/innodb_bug56716.test | 10 +++ storage/innobase/row/row0sel.c | 72 +++++++++---------- 3 files changed, 50 insertions(+), 36 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug56716.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug56716.test diff --git a/mysql-test/suite/innodb/r/innodb_bug56716.result b/mysql-test/suite/innodb/r/innodb_bug56716.result new file mode 100644 index 00000000000..50d83e8d87a --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug56716.result @@ -0,0 +1,4 @@ +CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB; +SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE; +a b c +DROP TABLE bug56716; diff --git a/mysql-test/suite/innodb/t/innodb_bug56716.test b/mysql-test/suite/innodb/t/innodb_bug56716.test new file mode 100644 index 00000000000..3345038d9c1 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug56716.test @@ -0,0 +1,10 @@ +# +# Bug #56716 InnoDB locks a record gap without locking the table +# +-- source include/have_innodb.inc + +CREATE TABLE bug56716 (a INT PRIMARY KEY,b INT,c INT,INDEX(b)) ENGINE=InnoDB; + +SELECT * FROM bug56716 WHERE b<=42 ORDER BY b DESC FOR UPDATE; + +DROP TABLE bug56716; diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c index 945eab74924..61ef4edb7a6 100644 --- a/storage/innobase/row/row0sel.c +++ b/storage/innobase/row/row0sel.c @@ -3711,6 +3711,42 @@ release_search_latch_if_needed: clust_index = dict_table_get_first_index(index->table); + /* Do some start-of-statement preparations */ + + if (!prebuilt->sql_stat_start) { + /* No need to set an intention lock or assign a read view */ + + if (trx->read_view == NULL + && prebuilt->select_lock_type == LOCK_NONE) { + + fputs("InnoDB: Error: MySQL is trying to" + " perform a consistent read\n" + "InnoDB: but the read view is not assigned!\n", + stderr); + trx_print(stderr, trx, 600); + fputc('\n', stderr); + ut_error; + } + } else if (prebuilt->select_lock_type == LOCK_NONE) { + /* This is a consistent read */ + /* Assign a read view for the query */ + + trx_assign_read_view(trx); + prebuilt->sql_stat_start = FALSE; + } else { + err = lock_table(0, index->table, + prebuilt->select_lock_type == LOCK_S + ? LOCK_IS : LOCK_IX, thr); + + if (err != DB_SUCCESS) { + + goto lock_wait_or_error; + } + prebuilt->sql_stat_start = FALSE; + } + + /* Open or restore index cursor position */ + if (UNIV_LIKELY(direction != 0)) { ibool need_to_process = sel_restore_position_for_mysql( &same_user_rec, BTR_SEARCH_LEAF, @@ -3786,42 +3822,6 @@ release_search_latch_if_needed: } } - if (!prebuilt->sql_stat_start) { - /* No need to set an intention lock or assign a read view */ - - if (trx->read_view == NULL - && prebuilt->select_lock_type == LOCK_NONE) { - - fputs("InnoDB: Error: MySQL is trying to" - " perform a consistent read\n" - "InnoDB: but the read view is not assigned!\n", - stderr); - trx_print(stderr, trx, 600); - fputc('\n', stderr); - ut_a(0); - } - } else if (prebuilt->select_lock_type == LOCK_NONE) { - /* This is a consistent read */ - /* Assign a read view for the query */ - - trx_assign_read_view(trx); - prebuilt->sql_stat_start = FALSE; - } else { - ulint lock_mode; - if (prebuilt->select_lock_type == LOCK_S) { - lock_mode = LOCK_IS; - } else { - lock_mode = LOCK_IX; - } - err = lock_table(0, index->table, lock_mode, thr); - - if (err != DB_SUCCESS) { - - goto lock_wait_or_error; - } - prebuilt->sql_stat_start = FALSE; - } - rec_loop: /*-------------------------------------------------------------*/ /* PHASE 4: Look for matching records in a loop */ From 40ee088f68a452ac2ed19622481c73d6d38c7ec3 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Mon, 4 Oct 2010 08:52:59 -0300 Subject: [PATCH 159/159] Bug#57210: remove pstack Quoting from the bug report: The pstack library has been included in MySQL since version 4.0.0. It's useless and should be removed. Details: According to its own documentation, pstack only works on Linux on x86 in 32 bit mode and requires LinuxThreads and a statically linked binary. It doesn't really support any Linux from 2003 or later and doesn't work on any other OS. --- Makefile.am | 4 +- README | 94 - configure.in | 43 - include/my_global.h | 1 - include/mysql_embed.h | 1 - pstack/Makefile.am | 29 - pstack/aout/Makefile.am | 1 - pstack/aout/aout64.h | 475 --- pstack/aout/stab.def | 264 -- pstack/aout/stab_gnu.h | 37 - pstack/bucomm.c | 238 -- pstack/bucomm.h | 91 - pstack/budbg.h | 64 - pstack/debug.c | 3509 ------------------ pstack/debug.h | 798 ---- pstack/demangle.h | 90 - pstack/filemode.c | 266 -- pstack/ieee.c | 7602 --------------------------------------- pstack/ieee.h | 138 - pstack/libiberty.h | 180 - pstack/linuxthreads.c | 90 - pstack/linuxthreads.h | 28 - pstack/pstack.c | 2746 -------------- pstack/pstack.h | 22 - pstack/pstacktrace.h | 24 - pstack/rddbg.c | 462 --- pstack/stabs.c | 5082 -------------------------- sql/Makefile.am | 1 - sql/mysqld.cc | 23 - 29 files changed, 2 insertions(+), 22401 deletions(-) delete mode 100644 pstack/Makefile.am delete mode 100644 pstack/aout/Makefile.am delete mode 100644 pstack/aout/aout64.h delete mode 100644 pstack/aout/stab.def delete mode 100644 pstack/aout/stab_gnu.h delete mode 100644 pstack/bucomm.c delete mode 100644 pstack/bucomm.h delete mode 100644 pstack/budbg.h delete mode 100644 pstack/debug.c delete mode 100644 pstack/debug.h delete mode 100644 pstack/demangle.h delete mode 100644 pstack/filemode.c delete mode 100644 pstack/ieee.c delete mode 100644 pstack/ieee.h delete mode 100644 pstack/libiberty.h delete mode 100644 pstack/linuxthreads.c delete mode 100644 pstack/linuxthreads.h delete mode 100644 pstack/pstack.c delete mode 100644 pstack/pstack.h delete mode 100644 pstack/pstacktrace.h delete mode 100644 pstack/rddbg.c delete mode 100644 pstack/stabs.c diff --git a/Makefile.am b/Makefile.am index dcb55bdfa86..ca84e52a5a3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,7 +24,7 @@ EXTRA_DIST = INSTALL-SOURCE INSTALL-WIN-SOURCE \ SUBDIRS = . include @docs_dirs@ @zlib_dir@ \ @readline_topdir@ sql-common scripts \ - @pstack_dir@ libservices \ + libservices \ @sql_union_dirs@ unittest \ @sql_server@ @man_dirs@ tests \ @libmysqld_dirs@ \ @@ -34,7 +34,7 @@ SUBDIRS = . include @docs_dirs@ @zlib_dir@ \ cmake DIST_SUBDIRS = . include Docs zlib \ cmd-line-utils sql-common scripts \ - pstack libservices \ + libservices \ strings mysys dbug extra regex libmysql libmysql_r client unittest storage plugin \ vio sql man tests \ libmysqld \ diff --git a/README b/README index 7fb52404b17..42d80612174 100644 --- a/README +++ b/README @@ -2208,97 +2208,3 @@ library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. *************************************************************************** - -%%The following software may be included in this product: -pstack (part of GNU Binutils) - -Use of any of this software is governed by the terms of the license below: - -pstack is comprised of various .c and .h files; all begin like this: - -/* bucomm.h -- binutils common include file. - Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. - -This file is part of GNU Binutils. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -*************************************************************************** - -%%The following software may be included in this product: -libiberty.h (part of pstack GNU Binutils) - -Use of any of this software is governed by the terms of the license below: - -See -http://www.koders.com/c/fid99F596804BBE22C076522B848D5575F142079064.aspx - -/* Function declarations for libiberty. - Written by Cygnus Support, 1994. - - The libiberty library provides a number of functions which are - missing on some operating systems. We do not declare those here, - to avoid conflicts with the system header files on operating - systems that do support those functions. In this file we only - declare those functions which are specific to libiberty. */ - -*************************************************************************** - -%%The following software may be included in this product: -ieee.h (part of pstack GNU Binutils) - -Use of any of this software is governed by the terms of the license below: - -See -http://src.opensolaris.org/source/xref//sfw/usr/src/cmd/gdb/gdb-6.3/include/ieee.h - - -/* IEEE Standard 695-1980 "Universal Format for Object Modules" -header file - Contributed by Cygnus Support. */ - -*************************************************************************** - -%%The following software may be included in this product: -pstack.c (part of pstack GNU Binutils) - -Use of any of this software is governed by the terms of the license below: - -/* - pstack.c -- asynchronous stack trace of a running process - Copyright (c) 1999 Ross Thompson - Author: Ross Thompson - Critical bug fix: Tim Waugh -*/ - -/* - This file is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. -*/ - -*************************************************************************** diff --git a/configure.in b/configure.in index 4cde9ce1597..341c145e22f 100644 --- a/configure.in +++ b/configure.in @@ -1069,46 +1069,6 @@ struct request_info *req; ]) AC_SUBST(WRAPLIBS) -if test "$TARGET_LINUX" = "true"; then - AC_ARG_WITH(pstack, - [ --with-pstack Use the pstack backtrace library], - [ USE_PSTACK=$withval ], - [ USE_PSTACK=no ]) - pstack_libs= - pstack_dir= - if test "$USE_PSTACK" = yes -a "$TARGET_LINUX" = "true" -a "$BASE_MACHINE_TYPE" = "i386" - then - have_libiberty= have_libbfd= - my_save_LIBS="$LIBS" -dnl I have no idea if this is a good test - can not find docs for libiberty - AC_CHECK_LIB([iberty], [fdmatch], - [have_libiberty=yes - AC_CHECK_LIB([bfd], [bfd_openr], [have_libbfd=yes], , [-liberty])]) - LIBS="$my_save_LIBS" - - if test x"$have_libiberty" = xyes -a x"$have_libbfd" = xyes - then - pstack_dir="pstack" - pstack_libs="../pstack/libpstack.a -lbfd -liberty" - # We must link staticly when using pstack - with_mysqld_ldflags="-all-static" - AC_SUBST([pstack_dir]) - AC_SUBST([pstack_libs]) - AC_DEFINE([USE_PSTACK], [1], [the pstack backtrace library]) -dnl This check isn't needed, but might be nice to give some feedback.... -dnl AC_CHECK_HEADER(libiberty.h, -dnl have_libiberty_h=yes, -dnl have_libiberty_h=no) - else - USE_PSTACK="no" - fi - else - USE_PSTACK="no" - fi -fi -AC_MSG_CHECKING([if we should use pstack]) -AC_MSG_RESULT([$USE_PSTACK]) - # Check for gtty if termio.h doesn't exists if test "$ac_cv_header_termio_h" = "no" -a "$ac_cv_header_termios_h" = "no" then @@ -3004,9 +2964,6 @@ AC_SUBST([RDTSC_SPARC_ASSEMBLY]) # Output results #-------------------------------------------------------------------- -if test -d "$srcdir/pstack" ; then - AC_CONFIG_FILES(pstack/Makefile pstack/aout/Makefile) -fi if test -d "$srcdir/cmd-line-utils/readline" ; then AC_CONFIG_FILES(cmd-line-utils/readline/Makefile) fi diff --git a/include/my_global.h b/include/my_global.h index 1c615cc5ca2..4902f06c7c0 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -1474,7 +1474,6 @@ static inline double rint(double x) /* Things we don't need in the embedded version of MySQL */ /* TODO HF add #undef HAVE_VIO if we don't want client in embedded library */ -#undef HAVE_PSTACK /* No stacktrace */ #undef HAVE_OPENSSL #undef HAVE_SMEM /* No shared memory */ #undef HAVE_NDBCLUSTER_DB /* No NDB cluster */ diff --git a/include/mysql_embed.h b/include/mysql_embed.h index ae70b9723f8..e860a4486eb 100644 --- a/include/mysql_embed.h +++ b/include/mysql_embed.h @@ -23,7 +23,6 @@ /* Things we don't need in the embedded version of MySQL */ /* TODO HF add #undef HAVE_VIO if we don't want client in embedded library */ -#undef HAVE_PSTACK /* No stacktrace */ #undef HAVE_DLOPEN /* No udf functions */ #undef HAVE_SMEM /* No shared memory */ #undef HAVE_NDBCLUSTER_DB /* No NDB cluster */ diff --git a/pstack/Makefile.am b/pstack/Makefile.am deleted file mode 100644 index 25feadf9d06..00000000000 --- a/pstack/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (C) 2000-2003, 2005 MySQL AB -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -# -# As pstack doesn't work on all configurations, we have to use -# the USE_PSTACK hack to get all files into distribution -# - -SUBDIRS = aout - -INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include - -pkglib_LIBRARIES = libpstack.a -libpstack_a_SOURCES = bucomm.c filemode.c linuxthreads.c rddbg.c \ - debug.c ieee.c pstack.c stabs.c -noinst_HEADERS = bucomm.h debug.h ieee.h budbg.h demangle.h \ - linuxthreads.h pstack.h pstacktrace.h diff --git a/pstack/aout/Makefile.am b/pstack/aout/Makefile.am deleted file mode 100644 index 0b02cb7b643..00000000000 --- a/pstack/aout/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -noinst_HEADERS = aout64.h stab.def stab_gnu.h diff --git a/pstack/aout/aout64.h b/pstack/aout/aout64.h deleted file mode 100644 index 76f1140b682..00000000000 --- a/pstack/aout/aout64.h +++ /dev/null @@ -1,475 +0,0 @@ -/* `a.out' object-file definitions, including extensions to 64-bit fields */ - -#ifndef __A_OUT_64_H__ -#define __A_OUT_64_H__ - -/* This is the layout on disk of the 32-bit or 64-bit exec header. */ - -#ifndef external_exec -struct external_exec -{ - bfd_byte e_info[4]; /* magic number and stuff */ - bfd_byte e_text[BYTES_IN_WORD]; /* length of text section in bytes */ - bfd_byte e_data[BYTES_IN_WORD]; /* length of data section in bytes */ - bfd_byte e_bss[BYTES_IN_WORD]; /* length of bss area in bytes */ - bfd_byte e_syms[BYTES_IN_WORD]; /* length of symbol table in bytes */ - bfd_byte e_entry[BYTES_IN_WORD]; /* start address */ - bfd_byte e_trsize[BYTES_IN_WORD]; /* length of text relocation info */ - bfd_byte e_drsize[BYTES_IN_WORD]; /* length of data relocation info */ -}; - -#define EXEC_BYTES_SIZE (4 + BYTES_IN_WORD * 7) - -/* Magic numbers for a.out files */ - -#if ARCH_SIZE==64 -#define OMAGIC 0x1001 /* Code indicating object file */ -#define ZMAGIC 0x1002 /* Code indicating demand-paged executable. */ -#define NMAGIC 0x1003 /* Code indicating pure executable. */ - -/* There is no 64-bit QMAGIC as far as I know. */ - -#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \ - && N_MAGIC(x) != NMAGIC \ - && N_MAGIC(x) != ZMAGIC) -#else -#define OMAGIC 0407 /* ...object file or impure executable. */ -#define NMAGIC 0410 /* Code indicating pure executable. */ -#define ZMAGIC 0413 /* Code indicating demand-paged executable. */ -#define BMAGIC 0415 /* Used by a b.out object. */ - -/* This indicates a demand-paged executable with the header in the text. - It is used by 386BSD (and variants) and Linux, at least. */ -#ifndef QMAGIC -#define QMAGIC 0314 -#endif -# ifndef N_BADMAG -# define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \ - && N_MAGIC(x) != NMAGIC \ - && N_MAGIC(x) != ZMAGIC \ - && N_MAGIC(x) != QMAGIC) -# endif /* N_BADMAG */ -#endif - -#endif - -#ifdef QMAGIC -#define N_IS_QMAGIC(x) (N_MAGIC (x) == QMAGIC) -#else -#define N_IS_QMAGIC(x) (0) -#endif - -/* The difference between TARGET_PAGE_SIZE and N_SEGSIZE is that TARGET_PAGE_SIZE is - the finest granularity at which you can page something, thus it - controls the padding (if any) before the text segment of a ZMAGIC - file. N_SEGSIZE is the resolution at which things can be marked as - read-only versus read/write, so it controls the padding between the - text segment and the data segment (in memory; on disk the padding - between them is TARGET_PAGE_SIZE). TARGET_PAGE_SIZE and N_SEGSIZE are the same - for most machines, but different for sun3. */ - -/* By default, segment size is constant. But some machines override this - to be a function of the a.out header (e.g. machine type). */ - -#ifndef N_SEGSIZE -#define N_SEGSIZE(x) SEGMENT_SIZE -#endif - -/* Virtual memory address of the text section. - This is getting very complicated. A good reason to discard a.out format - for something that specifies these fields explicitly. But til then... - - * OMAGIC and NMAGIC files: - (object files: text for "relocatable addr 0" right after the header) - start at 0, offset is EXEC_BYTES_SIZE, size as stated. - * The text address, offset, and size of ZMAGIC files depend - on the entry point of the file: - * entry point below TEXT_START_ADDR: - (hack for SunOS shared libraries) - start at 0, offset is 0, size as stated. - * If N_HEADER_IN_TEXT(x) is true (which defaults to being the - case when the entry point is EXEC_BYTES_SIZE or further into a page): - no padding is needed; text can start after exec header. Sun - considers the text segment of such files to include the exec header; - for BFD's purposes, we don't, which makes more work for us. - start at TEXT_START_ADDR + EXEC_BYTES_SIZE, offset is EXEC_BYTES_SIZE, - size as stated minus EXEC_BYTES_SIZE. - * If N_HEADER_IN_TEXT(x) is false (which defaults to being the case when - the entry point is less than EXEC_BYTES_SIZE into a page (e.g. page - aligned)): (padding is needed so that text can start at a page boundary) - start at TEXT_START_ADDR, offset TARGET_PAGE_SIZE, size as stated. - - Specific configurations may want to hardwire N_HEADER_IN_TEXT, - for efficiency or to allow people to play games with the entry point. - In that case, you would #define N_HEADER_IN_TEXT(x) as 1 for sunos, - and as 0 for most other hosts (Sony News, Vax Ultrix, etc). - (Do this in the appropriate bfd target file.) - (The default is a heuristic that will break if people try changing - the entry point, perhaps with the ld -e flag.) - - * QMAGIC is always like a ZMAGIC for which N_HEADER_IN_TEXT is true, - and for which the starting address is TARGET_PAGE_SIZE (or should this be - SEGMENT_SIZE?) (TEXT_START_ADDR only applies to ZMAGIC, not to QMAGIC). - */ - -/* This macro is only relevant for ZMAGIC files; QMAGIC always has the header - in the text. */ -#ifndef N_HEADER_IN_TEXT -#define N_HEADER_IN_TEXT(x) (((x).a_entry & (TARGET_PAGE_SIZE-1)) >= EXEC_BYTES_SIZE) -#endif - -/* Sun shared libraries, not linux. This macro is only relevant for ZMAGIC - files. */ -#ifndef N_SHARED_LIB -#define N_SHARED_LIB(x) ((x).a_entry < TEXT_START_ADDR) -#endif - -/* Returning 0 not TEXT_START_ADDR for OMAGIC and NMAGIC is based on - the assumption that we are dealing with a .o file, not an - executable. This is necessary for OMAGIC (but means we don't work - right on the output from ld -N); more questionable for NMAGIC. */ - -#ifndef N_TXTADDR -#define N_TXTADDR(x) \ - (/* The address of a QMAGIC file is always one page in, */ \ - /* with the header in the text. */ \ - N_IS_QMAGIC (x) ? TARGET_PAGE_SIZE + EXEC_BYTES_SIZE : \ - N_MAGIC(x) != ZMAGIC ? 0 : /* object file or NMAGIC */\ - N_SHARED_LIB(x) ? 0 : \ - N_HEADER_IN_TEXT(x) ? \ - TEXT_START_ADDR + EXEC_BYTES_SIZE : /* no padding */\ - TEXT_START_ADDR /* a page of padding */\ - ) -#endif - -/* If N_HEADER_IN_TEXT is not true for ZMAGIC, there is some padding - to make the text segment start at a certain boundary. For most - systems, this boundary is TARGET_PAGE_SIZE. But for Linux, in the - time-honored tradition of crazy ZMAGIC hacks, it is 1024 which is - not what TARGET_PAGE_SIZE needs to be for QMAGIC. */ - -#ifndef ZMAGIC_DISK_BLOCK_SIZE -#define ZMAGIC_DISK_BLOCK_SIZE TARGET_PAGE_SIZE -#endif - -#define N_DISK_BLOCK_SIZE(x) \ - (N_MAGIC(x) == ZMAGIC ? ZMAGIC_DISK_BLOCK_SIZE : TARGET_PAGE_SIZE) - -/* Offset in an a.out of the start of the text section. */ -#ifndef N_TXTOFF -#define N_TXTOFF(x) \ - (/* For {O,N,Q}MAGIC, no padding. */ \ - N_MAGIC(x) != ZMAGIC ? EXEC_BYTES_SIZE : \ - N_SHARED_LIB(x) ? 0 : \ - N_HEADER_IN_TEXT(x) ? \ - EXEC_BYTES_SIZE : /* no padding */\ - ZMAGIC_DISK_BLOCK_SIZE /* a page of padding */\ - ) -#endif -/* Size of the text section. It's always as stated, except that we - offset it to `undo' the adjustment to N_TXTADDR and N_TXTOFF - for ZMAGIC files that nominally include the exec header - as part of the first page of text. (BFD doesn't consider the - exec header to be part of the text segment.) */ -#ifndef N_TXTSIZE -#define N_TXTSIZE(x) \ - (/* For QMAGIC, we don't consider the header part of the text section. */\ - N_IS_QMAGIC (x) ? (x).a_text - EXEC_BYTES_SIZE : \ - (N_MAGIC(x) != ZMAGIC || N_SHARED_LIB(x)) ? (x).a_text : \ - N_HEADER_IN_TEXT(x) ? \ - (x).a_text - EXEC_BYTES_SIZE: /* no padding */\ - (x).a_text /* a page of padding */\ - ) -#endif -/* The address of the data segment in virtual memory. - It is the text segment address, plus text segment size, rounded - up to a N_SEGSIZE boundary for pure or pageable files. */ -#ifndef N_DATADDR -#define N_DATADDR(x) \ - (N_MAGIC(x)==OMAGIC? (N_TXTADDR(x)+N_TXTSIZE(x)) \ - : (N_SEGSIZE(x) + ((N_TXTADDR(x)+N_TXTSIZE(x)-1) & ~(N_SEGSIZE(x)-1)))) -#endif -/* The address of the BSS segment -- immediately after the data segment. */ - -#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data) - -/* Offsets of the various portions of the file after the text segment. */ - -/* For {Q,Z}MAGIC, there is padding to make the data segment start on - a page boundary. Most of the time the a_text field (and thus - N_TXTSIZE) already contains this padding. It is possible that for - BSDI and/or 386BSD it sometimes doesn't contain the padding, and - perhaps we should be adding it here. But this seems kind of - questionable and probably should be BSDI/386BSD-specific if we do - do it. - - For NMAGIC (at least for hp300 BSD, probably others), there is - padding in memory only, not on disk, so we must *not* ever pad here - for NMAGIC. */ - -#ifndef N_DATOFF -#define N_DATOFF(x) \ - (N_TXTOFF(x) + N_TXTSIZE(x)) -#endif - -#ifndef N_TRELOFF -#define N_TRELOFF(x) ( N_DATOFF(x) + (x).a_data ) -#endif -#ifndef N_DRELOFF -#define N_DRELOFF(x) ( N_TRELOFF(x) + (x).a_trsize ) -#endif -#ifndef N_SYMOFF -#define N_SYMOFF(x) ( N_DRELOFF(x) + (x).a_drsize ) -#endif -#ifndef N_STROFF -#define N_STROFF(x) ( N_SYMOFF(x) + (x).a_syms ) -#endif - -/* Symbols */ -#ifndef external_nlist -struct external_nlist { - bfd_byte e_strx[BYTES_IN_WORD]; /* index into string table of name */ - bfd_byte e_type[1]; /* type of symbol */ - bfd_byte e_other[1]; /* misc info (usually empty) */ - bfd_byte e_desc[2]; /* description field */ - bfd_byte e_value[BYTES_IN_WORD]; /* value of symbol */ -}; -#define EXTERNAL_NLIST_SIZE (BYTES_IN_WORD+4+BYTES_IN_WORD) -#endif - -struct internal_nlist { - unsigned long n_strx; /* index into string table of name */ - unsigned char n_type; /* type of symbol */ - unsigned char n_other; /* misc info (usually empty) */ - unsigned short n_desc; /* description field */ - bfd_vma n_value; /* value of symbol */ -}; - -/* The n_type field is the symbol type, containing: */ - -#define N_UNDF 0 /* Undefined symbol */ -#define N_ABS 2 /* Absolute symbol -- defined at particular addr */ -#define N_TEXT 4 /* Text sym -- defined at offset in text seg */ -#define N_DATA 6 /* Data sym -- defined at offset in data seg */ -#define N_BSS 8 /* BSS sym -- defined at offset in zero'd seg */ -#define N_COMM 0x12 /* Common symbol (visible after shared lib dynlink) */ -#define N_FN 0x1f /* File name of .o file */ -#define N_FN_SEQ 0x0C /* N_FN from Sequent compilers (sigh) */ -/* Note: N_EXT can only be usefully OR-ed with N_UNDF, N_ABS, N_TEXT, - N_DATA, or N_BSS. When the low-order bit of other types is set, - (e.g. N_WARNING versus N_FN), they are two different types. */ -#define N_EXT 1 /* External symbol (as opposed to local-to-this-file) */ -#define N_TYPE 0x1e -#define N_STAB 0xe0 /* If any of these bits are on, it's a debug symbol */ - -#define N_INDR 0x0a - -/* The following symbols refer to set elements. - All the N_SET[ATDB] symbols with the same name form one set. - Space is allocated for the set in the text section, and each set - elements value is stored into one word of the space. - The first word of the space is the length of the set (number of elements). - - The address of the set is made into an N_SETV symbol - whose name is the same as the name of the set. - This symbol acts like a N_DATA global symbol - in that it can satisfy undefined external references. */ - -/* These appear as input to LD, in a .o file. */ -#define N_SETA 0x14 /* Absolute set element symbol */ -#define N_SETT 0x16 /* Text set element symbol */ -#define N_SETD 0x18 /* Data set element symbol */ -#define N_SETB 0x1A /* Bss set element symbol */ - -/* This is output from LD. */ -#define N_SETV 0x1C /* Pointer to set vector in data area. */ - -/* Warning symbol. The text gives a warning message, the next symbol - in the table will be undefined. When the symbol is referenced, the - message is printed. */ - -#define N_WARNING 0x1e - -/* Weak symbols. These are a GNU extension to the a.out format. The - semantics are those of ELF weak symbols. Weak symbols are always - externally visible. The N_WEAK? values are squeezed into the - available slots. The value of a N_WEAKU symbol is 0. The values - of the other types are the definitions. */ -#define N_WEAKU 0x0d /* Weak undefined symbol. */ -#define N_WEAKA 0x0e /* Weak absolute symbol. */ -#define N_WEAKT 0x0f /* Weak text symbol. */ -#define N_WEAKD 0x10 /* Weak data symbol. */ -#define N_WEAKB 0x11 /* Weak bss symbol. */ - -/* Relocations - - There are two types of relocation flavours for a.out systems, - standard and extended. The standard form is used on systems where the - instruction has room for all the bits of an offset to the operand, whilst - the extended form is used when an address operand has to be split over n - instructions. Eg, on the 68k, each move instruction can reference - the target with a displacement of 16 or 32 bits. On the sparc, move - instructions use an offset of 14 bits, so the offset is stored in - the reloc field, and the data in the section is ignored. -*/ - -/* This structure describes a single relocation to be performed. - The text-relocation section of the file is a vector of these structures, - all of which apply to the text section. - Likewise, the data-relocation section applies to the data section. */ - -struct reloc_std_external { - bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */ - bfd_byte r_index[3]; /* symbol table index of symbol */ - bfd_byte r_type[1]; /* relocation type */ -}; - -#define RELOC_STD_BITS_PCREL_BIG ((unsigned int) 0x80) -#define RELOC_STD_BITS_PCREL_LITTLE ((unsigned int) 0x01) - -#define RELOC_STD_BITS_LENGTH_BIG ((unsigned int) 0x60) -#define RELOC_STD_BITS_LENGTH_SH_BIG 5 -#define RELOC_STD_BITS_LENGTH_LITTLE ((unsigned int) 0x06) -#define RELOC_STD_BITS_LENGTH_SH_LITTLE 1 - -#define RELOC_STD_BITS_EXTERN_BIG ((unsigned int) 0x10) -#define RELOC_STD_BITS_EXTERN_LITTLE ((unsigned int) 0x08) - -#define RELOC_STD_BITS_BASEREL_BIG ((unsigned int) 0x08) -#define RELOC_STD_BITS_BASEREL_LITTLE ((unsigned int) 0x10) - -#define RELOC_STD_BITS_JMPTABLE_BIG ((unsigned int) 0x04) -#define RELOC_STD_BITS_JMPTABLE_LITTLE ((unsigned int) 0x20) - -#define RELOC_STD_BITS_RELATIVE_BIG ((unsigned int) 0x02) -#define RELOC_STD_BITS_RELATIVE_LITTLE ((unsigned int) 0x40) - -#define RELOC_STD_SIZE (BYTES_IN_WORD + 3 + 1) /* Bytes per relocation entry */ - -struct reloc_std_internal -{ - bfd_vma r_address; /* Address (within segment) to be relocated. */ - /* The meaning of r_symbolnum depends on r_extern. */ - unsigned int r_symbolnum:24; - /* Nonzero means value is a pc-relative offset - and it should be relocated for changes in its own address - as well as for changes in the symbol or section specified. */ - unsigned int r_pcrel:1; - /* Length (as exponent of 2) of the field to be relocated. - Thus, a value of 2 indicates 1<<2 bytes. */ - unsigned int r_length:2; - /* 1 => relocate with value of symbol. - r_symbolnum is the index of the symbol - in files the symbol table. - 0 => relocate with the address of a segment. - r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS - (the N_EXT bit may be set also, but signifies nothing). */ - unsigned int r_extern:1; - /* The next three bits are for SunOS shared libraries, and seem to - be undocumented. */ - unsigned int r_baserel:1; /* Linkage table relative */ - unsigned int r_jmptable:1; /* pc-relative to jump table */ - unsigned int r_relative:1; /* "relative relocation" */ - /* unused */ - unsigned int r_pad:1; /* Padding -- set to zero */ -}; - - -/* EXTENDED RELOCS */ - -struct reloc_ext_external { - bfd_byte r_address[BYTES_IN_WORD]; /* offset of of data to relocate */ - bfd_byte r_index[3]; /* symbol table index of symbol */ - bfd_byte r_type[1]; /* relocation type */ - bfd_byte r_addend[BYTES_IN_WORD]; /* datum addend */ -}; - -#define RELOC_EXT_BITS_EXTERN_BIG ((unsigned int) 0x80) -#define RELOC_EXT_BITS_EXTERN_LITTLE ((unsigned int) 0x01) - -#define RELOC_EXT_BITS_TYPE_BIG ((unsigned int) 0x1F) -#define RELOC_EXT_BITS_TYPE_SH_BIG 0 -#define RELOC_EXT_BITS_TYPE_LITTLE ((unsigned int) 0xF8) -#define RELOC_EXT_BITS_TYPE_SH_LITTLE 3 - -/* Bytes per relocation entry */ -#define RELOC_EXT_SIZE (BYTES_IN_WORD + 3 + 1 + BYTES_IN_WORD) - -enum reloc_type -{ - /* simple relocations */ - RELOC_8, /* data[0:7] = addend + sv */ - RELOC_16, /* data[0:15] = addend + sv */ - RELOC_32, /* data[0:31] = addend + sv */ - /* pc-rel displacement */ - RELOC_DISP8, /* data[0:7] = addend - pc + sv */ - RELOC_DISP16, /* data[0:15] = addend - pc + sv */ - RELOC_DISP32, /* data[0:31] = addend - pc + sv */ - /* Special */ - RELOC_WDISP30, /* data[0:29] = (addend + sv - pc)>>2 */ - RELOC_WDISP22, /* data[0:21] = (addend + sv - pc)>>2 */ - RELOC_HI22, /* data[0:21] = (addend + sv)>>10 */ - RELOC_22, /* data[0:21] = (addend + sv) */ - RELOC_13, /* data[0:12] = (addend + sv) */ - RELOC_LO10, /* data[0:9] = (addend + sv) */ - RELOC_SFA_BASE, - RELOC_SFA_OFF13, - /* P.I.C. (base-relative) */ - RELOC_BASE10, /* Not sure - maybe we can do this the */ - RELOC_BASE13, /* right way now */ - RELOC_BASE22, - /* for some sort of pc-rel P.I.C. (?) */ - RELOC_PC10, - RELOC_PC22, - /* P.I.C. jump table */ - RELOC_JMP_TBL, - /* reputedly for shared libraries somehow */ - RELOC_SEGOFF16, - RELOC_GLOB_DAT, - RELOC_JMP_SLOT, - RELOC_RELATIVE, - - RELOC_11, - RELOC_WDISP2_14, - RELOC_WDISP19, - RELOC_HHI22, /* data[0:21] = (addend + sv) >> 42 */ - RELOC_HLO10, /* data[0:9] = (addend + sv) >> 32 */ - - /* 29K relocation types */ - RELOC_JUMPTARG, - RELOC_CONST, - RELOC_CONSTH, - - /* All the new ones I can think of, for sparc v9 */ - - RELOC_64, /* data[0:63] = addend + sv */ - RELOC_DISP64, /* data[0:63] = addend - pc + sv */ - RELOC_WDISP21, /* data[0:20] = (addend + sv - pc)>>2 */ - RELOC_DISP21, /* data[0:20] = addend - pc + sv */ - RELOC_DISP14, /* data[0:13] = addend - pc + sv */ - /* Q . - What are the other ones, - Since this is a clean slate, can we throw away the ones we dont - understand ? Should we sort the values ? What about using a - microcode format like the 68k ? - */ - NO_RELOC - }; - - -struct reloc_internal { - bfd_vma r_address; /* offset of of data to relocate */ - long r_index; /* symbol table index of symbol */ - enum reloc_type r_type; /* relocation type */ - bfd_vma r_addend; /* datum addend */ -}; - -/* Q. - Should the length of the string table be 4 bytes or 8 bytes ? - - Q. - What about archive indexes ? - - */ - -#endif /* __A_OUT_64_H__ */ diff --git a/pstack/aout/stab.def b/pstack/aout/stab.def deleted file mode 100644 index 3c6b456d3a9..00000000000 --- a/pstack/aout/stab.def +++ /dev/null @@ -1,264 +0,0 @@ -/* Table of DBX symbol codes for the GNU system. - Copyright (C) 1988, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* New stab from Solaris 2. This uses an n_type of 0, which in a.out files - overlaps the N_UNDF used for ordinary symbols. In ELF files, the - debug information is in a different file section, so there is no conflict. - This symbol's n_value gives the size of the string section associated - with this file. The symbol's n_strx (relative to the just-updated - string section start address) gives the name of the source file, - e.g. "foo.c", without any path information. The symbol's n_desc gives - the count of upcoming symbols associated with this file (not including - this one). */ -/* __define_stab (N_UNDF, 0x00, "UNDF") */ - -/* Global variable. Only the name is significant. - To find the address, look in the corresponding external symbol. */ -__define_stab (N_GSYM, 0x20, "GSYM") - -/* Function name for BSD Fortran. Only the name is significant. - To find the address, look in the corresponding external symbol. */ -__define_stab (N_FNAME, 0x22, "FNAME") - -/* Function name or text-segment variable for C. Value is its address. - Desc is supposedly starting line number, but GCC doesn't set it - and DBX seems not to miss it. */ -__define_stab (N_FUN, 0x24, "FUN") - -/* Data-segment variable with internal linkage. Value is its address. - "Static Sym". */ -__define_stab (N_STSYM, 0x26, "STSYM") - -/* BSS-segment variable with internal linkage. Value is its address. */ -__define_stab (N_LCSYM, 0x28, "LCSYM") - -/* Name of main routine. Only the name is significant. */ -__define_stab (N_MAIN, 0x2a, "MAIN") - -/* Solaris2: Read-only data symbols. */ -__define_stab (N_ROSYM, 0x2c, "ROSYM") - -/* Global symbol in Pascal. - Supposedly the value is its line number; I'm skeptical. */ -__define_stab (N_PC, 0x30, "PC") - -/* Number of symbols: 0, files,,funcs,lines according to Ultrix V4.0. */ -__define_stab (N_NSYMS, 0x32, "NSYMS") - -/* "No DST map for sym: name, ,0,type,ignored" according to Ultrix V4.0. */ -__define_stab (N_NOMAP, 0x34, "NOMAP") - -/* New stab from Solaris 2. Like N_SO, but for the object file. Two in - a row provide the build directory and the relative path of the .o from it. - Solaris2 uses this to avoid putting the stabs info into the linked - executable; this stab goes into the ".stab.index" section, and the debugger - reads the real stabs directly from the .o files instead. */ -__define_stab (N_OBJ, 0x38, "OBJ") - -/* New stab from Solaris 2. Options for the debugger, related to the - source language for this module. E.g. whether to use ANSI - integral promotions or traditional integral promotions. */ -__define_stab (N_OPT, 0x3c, "OPT") - -/* Register variable. Value is number of register. */ -__define_stab (N_RSYM, 0x40, "RSYM") - -/* Modula-2 compilation unit. Can someone say what info it contains? */ -__define_stab (N_M2C, 0x42, "M2C") - -/* Line number in text segment. Desc is the line number; - value is corresponding address. On Solaris2, the line number is - relative to the start of the current function. */ -__define_stab (N_SLINE, 0x44, "SLINE") - -/* Similar, for data segment. */ -__define_stab (N_DSLINE, 0x46, "DSLINE") - -/* Similar, for bss segment. */ -__define_stab (N_BSLINE, 0x48, "BSLINE") - -/* Sun's source-code browser stabs. ?? Don't know what the fields are. - Supposedly the field is "path to associated .cb file". THIS VALUE - OVERLAPS WITH N_BSLINE! */ -__define_stab_duplicate (N_BROWS, 0x48, "BROWS") - -/* GNU Modula-2 definition module dependency. Value is the modification time - of the definition file. Other is non-zero if it is imported with the - GNU M2 keyword %INITIALIZE. Perhaps N_M2C can be used if there - are enough empty fields? */ -__define_stab(N_DEFD, 0x4a, "DEFD") - -/* New in Solaris2. Function start/body/end line numbers. */ -__define_stab(N_FLINE, 0x4C, "FLINE") - -/* THE FOLLOWING TWO STAB VALUES CONFLICT. Happily, one is for Modula-2 - and one is for C++. Still,... */ -/* GNU C++ exception variable. Name is variable name. */ -__define_stab (N_EHDECL, 0x50, "EHDECL") -/* Modula2 info "for imc": name,,0,0,0 according to Ultrix V4.0. */ -__define_stab_duplicate (N_MOD2, 0x50, "MOD2") - -/* GNU C++ `catch' clause. Value is its address. Desc is nonzero if - this entry is immediately followed by a CAUGHT stab saying what exception - was caught. Multiple CAUGHT stabs means that multiple exceptions - can be caught here. If Desc is 0, it means all exceptions are caught - here. */ -__define_stab (N_CATCH, 0x54, "CATCH") - -/* Structure or union element. Value is offset in the structure. */ -__define_stab (N_SSYM, 0x60, "SSYM") - -/* Solaris2: Last stab emitted for module. */ -__define_stab (N_ENDM, 0x62, "ENDM") - -/* Name of main source file. - Value is starting text address of the compilation. - If multiple N_SO's appear, the first to contain a trailing / is the - compilation directory. The first to not contain a trailing / is the - source file name, relative to the compilation directory. Others (perhaps - resulting from cfront) are ignored. - On Solaris2, value is undefined, but desc is a source-language code. */ - -__define_stab (N_SO, 0x64, "SO") - -/* Automatic variable in the stack. Value is offset from frame pointer. - Also used for type descriptions. */ -__define_stab (N_LSYM, 0x80, "LSYM") - -/* Beginning of an include file. Only Sun uses this. - In an object file, only the name is significant. - The Sun linker puts data into some of the other fields. */ -__define_stab (N_BINCL, 0x82, "BINCL") - -/* Name of sub-source file (#include file). - Value is starting text address of the compilation. */ -__define_stab (N_SOL, 0x84, "SOL") - -/* Parameter variable. Value is offset from argument pointer. - (On most machines the argument pointer is the same as the frame pointer. */ -__define_stab (N_PSYM, 0xa0, "PSYM") - -/* End of an include file. No name. - This and N_BINCL act as brackets around the file's output. - In an object file, there is no significant data in this entry. - The Sun linker puts data into some of the fields. */ -__define_stab (N_EINCL, 0xa2, "EINCL") - -/* Alternate entry point. Value is its address. */ -__define_stab (N_ENTRY, 0xa4, "ENTRY") - -/* Beginning of lexical block. - The desc is the nesting level in lexical blocks. - The value is the address of the start of the text for the block. - The variables declared inside the block *precede* the N_LBRAC symbol. - On Solaris2, the value is relative to the start of the current function. */ -__define_stab (N_LBRAC, 0xc0, "LBRAC") - -/* Place holder for deleted include file. Replaces a N_BINCL and everything - up to the corresponding N_EINCL. The Sun linker generates these when - it finds multiple identical copies of the symbols from an include file. - This appears only in output from the Sun linker. */ -__define_stab (N_EXCL, 0xc2, "EXCL") - -/* Modula-2 scope information. Can someone say what info it contains? */ -__define_stab (N_SCOPE, 0xc4, "SCOPE") - -/* End of a lexical block. Desc matches the N_LBRAC's desc. - The value is the address of the end of the text for the block. - On Solaris2, the value is relative to the start of the current function. */ -__define_stab (N_RBRAC, 0xe0, "RBRAC") - -/* Begin named common block. Only the name is significant. */ -__define_stab (N_BCOMM, 0xe2, "BCOMM") - -/* End named common block. Only the name is significant - (and it should match the N_BCOMM). */ -__define_stab (N_ECOMM, 0xe4, "ECOMM") - -/* Member of a common block; value is offset within the common block. - This should occur within a BCOMM/ECOMM pair. */ -__define_stab (N_ECOML, 0xe8, "ECOML") - -/* Solaris2: Pascal "with" statement: type,,0,0,offset */ -__define_stab (N_WITH, 0xea, "WITH") - -/* These STAB's are used on Gould systems for Non-Base register symbols - or something like that. FIXME. I have assigned the values at random - since I don't have a Gould here. Fixups from Gould folk welcome... */ -__define_stab (N_NBTEXT, 0xF0, "NBTEXT") -__define_stab (N_NBDATA, 0xF2, "NBDATA") -__define_stab (N_NBBSS, 0xF4, "NBBSS") -__define_stab (N_NBSTS, 0xF6, "NBSTS") -__define_stab (N_NBLCS, 0xF8, "NBLCS") - -/* Second symbol entry containing a length-value for the preceding entry. - The value is the length. */ -__define_stab (N_LENG, 0xfe, "LENG") - -/* The above information, in matrix format. - - STAB MATRIX - _________________________________________________ - | 00 - 1F are not dbx stab symbols | - | In most cases, the low bit is the EXTernal bit| - - | 00 UNDEF | 02 ABS | 04 TEXT | 06 DATA | - | 01 |EXT | 03 |EXT | 05 |EXT | 07 |EXT | - - | 08 BSS | 0A INDR | 0C FN_SEQ | 0E WEAKA | - | 09 |EXT | 0B | 0D WEAKU | 0F WEAKT | - - | 10 WEAKD | 12 COMM | 14 SETA | 16 SETT | - | 11 WEAKB | 13 | 15 | 17 | - - | 18 SETD | 1A SETB | 1C SETV | 1E WARNING| - | 19 | 1B | 1D | 1F FN | - - |_______________________________________________| - | Debug entries with bit 01 set are unused. | - | 20 GSYM | 22 FNAME | 24 FUN | 26 STSYM | - | 28 LCSYM | 2A MAIN | 2C ROSYM | 2E | - | 30 PC | 32 NSYMS | 34 NOMAP | 36 | - | 38 OBJ | 3A | 3C OPT | 3E | - | 40 RSYM | 42 M2C | 44 SLINE | 46 DSLINE | - | 48 BSLINE*| 4A DEFD | 4C FLINE | 4E | - | 50 EHDECL*| 52 | 54 CATCH | 56 | - | 58 | 5A | 5C | 5E | - | 60 SSYM | 62 ENDM | 64 SO | 66 | - | 68 | 6A | 6C | 6E | - | 70 | 72 | 74 | 76 | - | 78 | 7A | 7C | 7E | - | 80 LSYM | 82 BINCL | 84 SOL | 86 | - | 88 | 8A | 8C | 8E | - | 90 | 92 | 94 | 96 | - | 98 | 9A | 9C | 9E | - | A0 PSYM | A2 EINCL | A4 ENTRY | A6 | - | A8 | AA | AC | AE | - | B0 | B2 | B4 | B6 | - | B8 | BA | BC | BE | - | C0 LBRAC | C2 EXCL | C4 SCOPE | C6 | - | C8 | CA | CC | CE | - | D0 | D2 | D4 | D6 | - | D8 | DA | DC | DE | - | E0 RBRAC | E2 BCOMM | E4 ECOMM | E6 | - | E8 ECOML | EA WITH | EC | EE | - | F0 | F2 | F4 | F6 | - | F8 | FA | FC | FE LENG | - +-----------------------------------------------+ - * 50 EHDECL is also MOD2. - * 48 BSLINE is also BROWS. - */ diff --git a/pstack/aout/stab_gnu.h b/pstack/aout/stab_gnu.h deleted file mode 100644 index 7d18e14a263..00000000000 --- a/pstack/aout/stab_gnu.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef __GNU_STAB__ - -/* Indicate the GNU stab.h is in use. */ - -#define __GNU_STAB__ - -#define __define_stab(NAME, CODE, STRING) NAME=CODE, -#define __define_stab_duplicate(NAME, CODE, STRING) NAME=CODE, - -enum __stab_debug_code -{ -#include "aout/stab.def" -LAST_UNUSED_STAB_CODE -}; - -#undef __define_stab - -/* Definitions of "desc" field for N_SO stabs in Solaris2. */ - -#define N_SO_AS 1 -#define N_SO_C 2 -#define N_SO_ANSI_C 3 -#define N_SO_CC 4 /* C++ */ -#define N_SO_FORTRAN 5 -#define N_SO_PASCAL 6 - -/* Solaris2: Floating point type values in basic types. */ - -#define NF_NONE 0 -#define NF_SINGLE 1 /* IEEE 32-bit */ -#define NF_DOUBLE 2 /* IEEE 64-bit */ -#define NF_COMPLEX 3 /* Fortran complex */ -#define NF_COMPLEX16 4 /* Fortran double complex */ -#define NF_COMPLEX32 5 /* Fortran complex*16 */ -#define NF_LDOUBLE 6 /* Long double (whatever that is) */ - -#endif /* __GNU_STAB_ */ diff --git a/pstack/bucomm.c b/pstack/bucomm.c deleted file mode 100644 index d3231e71747..00000000000 --- a/pstack/bucomm.c +++ /dev/null @@ -1,238 +0,0 @@ -/* bucomm.c -- Bin Utils COMmon code. - Copyright (C) 1991, 92, 93, 94, 95, 1997 Free Software Foundation, Inc. - - This file is part of GNU Binutils. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -/* We might put this in a library someday so it could be dynamically - loaded, but for now it's not necessary. */ - -#include -#include -#include "bucomm.h" - -#include -#include /* ctime, maybe time_t */ - -#ifdef ANSI_PROTOTYPES -#include -#else -#include -#endif - -/* Error reporting */ - -char *program_name; - -void -bfd_nonfatal (string) - CONST char *string; -{ - CONST char *errmsg = bfd_errmsg (bfd_get_error ()); - - if (string) - fprintf (stderr, "%s: %s: %s\n", program_name, string, errmsg); - else - fprintf (stderr, "%s: %s\n", program_name, errmsg); -} - -void -bfd_fatal (string) - CONST char *string; -{ - bfd_nonfatal (string); - xexit (1); -} - -#ifdef ANSI_PROTOTYPES -void -fatal (const char *format, ...) -{ - va_list args; - - fprintf (stderr, "%s: ", program_name); - va_start (args, format); - vfprintf (stderr, format, args); - va_end (args); - putc ('\n', stderr); - xexit (1); -} -#else -void -fatal (va_alist) - va_dcl -{ - char *Format; - va_list args; - - fprintf (stderr, "%s: ", program_name); - va_start (args); - Format = va_arg (args, char *); - vfprintf (stderr, Format, args); - va_end (args); - putc ('\n', stderr); - xexit (1); -} -#endif - -/* Set the default BFD target based on the configured target. Doing - this permits the binutils to be configured for a particular target, - and linked against a shared BFD library which was configured for a - different target. */ - -#define TARGET "elf32-i386" /* FIXME: hard-coded! */ -void -set_default_bfd_target () -{ - /* The macro TARGET is defined by Makefile. */ - const char *target = TARGET; - - if (! bfd_set_default_target (target)) - { - char *errmsg; - - errmsg = (char *) xmalloc (100 + strlen (target)); - sprintf (errmsg, "can't set BFD default target to `%s'", target); - bfd_fatal (errmsg); - } -} - -/* After a false return from bfd_check_format_matches with - bfd_get_error () == bfd_error_file_ambiguously_recognized, print - the possible matching targets. */ - -void -list_matching_formats (p) - char **p; -{ - fprintf(stderr, "%s: Matching formats:", program_name); - while (*p) - fprintf(stderr, " %s", *p++); - fprintf(stderr, "\n"); -} - -/* List the supported targets. */ - -void -list_supported_targets (name, f) - const char *name; - FILE *f; -{ - extern bfd_target *bfd_target_vector[]; - int t; - - if (name == NULL) - fprintf (f, "Supported targets:"); - else - fprintf (f, "%s: supported targets:", name); - for (t = 0; bfd_target_vector[t] != NULL; t++) - fprintf (f, " %s", bfd_target_vector[t]->name); - fprintf (f, "\n"); -} - -/* Display the archive header for an element as if it were an ls -l listing: - - Mode User\tGroup\tSize\tDate Name */ - -void -print_arelt_descr (file, abfd, verbose) - FILE *file; - bfd *abfd; - boolean verbose; -{ - struct stat buf; - - if (verbose) - { - if (bfd_stat_arch_elt (abfd, &buf) == 0) - { - char modebuf[11]; - char timebuf[40]; - time_t when = buf.st_mtime; - CONST char *ctime_result = (CONST char *) ctime (&when); - - /* POSIX format: skip weekday and seconds from ctime output. */ - sprintf (timebuf, "%.12s %.4s", ctime_result + 4, ctime_result + 20); - - mode_string (buf.st_mode, modebuf); - modebuf[10] = '\0'; - /* POSIX 1003.2/D11 says to skip first character (entry type). */ - fprintf (file, "%s %ld/%ld %6ld %s ", modebuf + 1, - (long) buf.st_uid, (long) buf.st_gid, - (long) buf.st_size, timebuf); - } - } - - fprintf (file, "%s\n", bfd_get_filename (abfd)); -} - -/* Return the name of a temporary file in the same directory as FILENAME. */ - -char * -make_tempname (filename) - char *filename; -{ - static char template[] = "stXXXXXX"; - char *tmpname; - char *slash = strrchr (filename, '/'); - -#if defined (__DJGPP__) || defined (__GO32__) || defined (_WIN32) - if (slash == NULL) - slash = strrchr (filename, '\\'); -#endif - - if (slash != (char *) NULL) - { - char c; - - c = *slash; - *slash = 0; - tmpname = xmalloc (strlen (filename) + sizeof (template) + 1); - strcpy (tmpname, filename); - strcat (tmpname, "/"); - strcat (tmpname, template); - mkstemp (tmpname); - *slash = c; - } - else - { - tmpname = xmalloc (sizeof (template)); - strcpy (tmpname, template); - mkstemp (tmpname); - } - return tmpname; -} - -/* Parse a string into a VMA, with a fatal error if it can't be - parsed. */ - -bfd_vma -parse_vma (s, arg) - const char *s; - const char *arg; -{ - bfd_vma ret; - const char *end; - - ret = bfd_scan_vma (s, &end, 0); - if (*end != '\0') - { - fprintf (stderr, "%s: %s: bad number: %s\n", program_name, arg, s); - exit (1); - } - return ret; -} diff --git a/pstack/bucomm.h b/pstack/bucomm.h deleted file mode 100644 index 6b3633d8d63..00000000000 --- a/pstack/bucomm.h +++ /dev/null @@ -1,91 +0,0 @@ -/* bucomm.h -- binutils common include file. - Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. - -This file is part of GNU Binutils. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef _BUCOMM_H -#define _BUCOMM_H - -#include "ansidecl.h" -#include -#include - -#include -#include - -#include - -#include - -#include - -#ifdef __GNUC__ -# undef alloca -# define alloca __builtin_alloca -#else -# if HAVE_ALLOCA_H -# include -# else -# ifndef alloca /* predefined by HP cc +Olibcalls */ -# if !defined (__STDC__) && !defined (__hpux) -char *alloca (); -# else -void *alloca (); -# endif /* __STDC__, __hpux */ -# endif /* alloca */ -# endif /* HAVE_ALLOCA_H */ -#endif - -#ifndef BFD_TRUE_FALSE -#define boolean bfd_boolean -#define true TRUE -#define false FALSE -#endif - -/* bucomm.c */ -void bfd_nonfatal PARAMS ((CONST char *)); - -void bfd_fatal PARAMS ((CONST char *)); - -void fatal PARAMS ((CONST char *, ...)); - -void set_default_bfd_target PARAMS ((void)); - -void list_matching_formats PARAMS ((char **p)); - -void list_supported_targets PARAMS ((const char *, FILE *)); - -void print_arelt_descr PARAMS ((FILE *file, bfd *abfd, boolean verbose)); - -char *make_tempname PARAMS ((char *)); - -bfd_vma parse_vma PARAMS ((const char *, const char *)); - -extern char *program_name; - -/* filemode.c */ -void mode_string PARAMS ((unsigned long mode, char *buf)); - -/* version.c */ -extern void print_version PARAMS ((const char *)); - -/* libiberty */ -PTR xmalloc PARAMS ((size_t)); - -PTR xrealloc PARAMS ((PTR, size_t)); - -#endif /* _BUCOMM_H */ diff --git a/pstack/budbg.h b/pstack/budbg.h deleted file mode 100644 index 9f0203ad5e7..00000000000 --- a/pstack/budbg.h +++ /dev/null @@ -1,64 +0,0 @@ -/* budbg.c -- Interfaces to the generic debugging information routines. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef BUDBG_H -#define BUDBG_H - -#include - -#ifndef BFD_TRUE_FALSE -#define boolean bfd_boolean -#define true TRUE -#define false FALSE -#endif - -/* Routine used to read generic debugging information. */ - -extern PTR read_debugging_info PARAMS ((bfd *, asymbol **, long)); - -/* Routine used to print generic debugging information. */ - -extern boolean print_debugging_info PARAMS ((FILE *, PTR)); - -/* Routines used to read and write stabs information. */ - -extern PTR start_stab PARAMS ((PTR, bfd *, boolean, asymbol **, long)); - -extern boolean finish_stab PARAMS ((PTR, PTR)); - -extern boolean parse_stab PARAMS ((PTR, PTR, int, int, bfd_vma, const char *)); - -extern boolean write_stabs_in_sections_debugging_info - PARAMS ((bfd *, PTR, bfd_byte **, bfd_size_type *, bfd_byte **, - bfd_size_type *)); - -/* Routines used to read and write IEEE debugging information. */ - -extern boolean parse_ieee - PARAMS ((PTR, bfd *, const bfd_byte *, bfd_size_type)); - -extern boolean write_ieee_debugging_info PARAMS ((bfd *, PTR)); - -/* Routine used to read COFF debugging information. */ - -extern boolean parse_coff PARAMS ((bfd *, asymbol **, long, PTR)); - -#endif diff --git a/pstack/debug.c b/pstack/debug.c deleted file mode 100644 index 73412ae3f03..00000000000 --- a/pstack/debug.c +++ /dev/null @@ -1,3509 +0,0 @@ -/* debug.c -- Handle generic debugging information. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -/* This file implements a generic debugging format. We may eventually - have readers which convert different formats into this generic - format, and writers which write it out. The initial impetus for - this was writing a convertor from stabs to HP IEEE-695 debugging - format. */ - -#include -#include - -#include -#include "bucomm.h" -#include -#include "debug.h" - -/* Global information we keep for debugging. A pointer to this - structure is the debugging handle passed to all the routines. */ - -struct debug_handle -{ - /* A linked list of compilation units. */ - struct debug_unit *units; - /* The current compilation unit. */ - struct debug_unit *current_unit; - /* The current source file. */ - struct debug_file *current_file; - /* The current function. */ - struct debug_function *current_function; - /* The current block. */ - struct debug_block *current_block; - /* The current line number information for the current unit. */ - struct debug_lineno *current_lineno; - /* Mark. This is used by debug_write. */ - unsigned int mark; - /* A struct/class ID used by debug_write. */ - unsigned int class_id; - /* The base for class_id for this call to debug_write. */ - unsigned int base_id; - /* The current line number in debug_write. */ - struct debug_lineno *current_write_lineno; - unsigned int current_write_lineno_index; - /* A list of classes which have assigned ID's during debug_write. - This is linked through the next_id field of debug_class_type. */ - struct debug_class_id *id_list; - /* A list used to avoid recursion during debug_type_samep. */ - struct debug_type_compare_list *compare_list; -}; - -/* Information we keep for a single compilation unit. */ - -struct debug_unit -{ - /* The next compilation unit. */ - struct debug_unit *next; - /* A list of files included in this compilation unit. The first - file is always the main one, and that is where the main file name - is stored. */ - struct debug_file *files; - /* Line number information for this compilation unit. This is not - stored by function, because assembler code may have line number - information without function information. */ - struct debug_lineno *linenos; -}; - -/* Information kept for a single source file. */ - -struct debug_file -{ - /* The next source file in this compilation unit. */ - struct debug_file *next; - /* The name of the source file. */ - const char *filename; - /* Global functions, variables, types, etc. */ - struct debug_namespace *globals; -}; - -/* A type. */ - -struct debug_type -{ - /* Kind of type. */ - enum debug_type_kind kind; - /* Size of type (0 if not known). */ - unsigned int size; - /* Type which is a pointer to this type. */ - debug_type pointer; - /* Tagged union with additional information about the type. */ - union - { - /* DEBUG_KIND_INDIRECT. */ - struct debug_indirect_type *kindirect; - /* DEBUG_KIND_INT. */ - /* Whether the integer is unsigned. */ - boolean kint; - /* DEBUG_KIND_STRUCT, DEBUG_KIND_UNION, DEBUG_KIND_CLASS, - DEBUG_KIND_UNION_CLASS. */ - struct debug_class_type *kclass; - /* DEBUG_KIND_ENUM. */ - struct debug_enum_type *kenum; - /* DEBUG_KIND_POINTER. */ - struct debug_type *kpointer; - /* DEBUG_KIND_FUNCTION. */ - struct debug_function_type *kfunction; - /* DEBUG_KIND_REFERENCE. */ - struct debug_type *kreference; - /* DEBUG_KIND_RANGE. */ - struct debug_range_type *krange; - /* DEBUG_KIND_ARRAY. */ - struct debug_array_type *karray; - /* DEBUG_KIND_SET. */ - struct debug_set_type *kset; - /* DEBUG_KIND_OFFSET. */ - struct debug_offset_type *koffset; - /* DEBUG_KIND_METHOD. */ - struct debug_method_type *kmethod; - /* DEBUG_KIND_CONST. */ - struct debug_type *kconst; - /* DEBUG_KIND_VOLATILE. */ - struct debug_type *kvolatile; - /* DEBUG_KIND_NAMED, DEBUG_KIND_TAGGED. */ - struct debug_named_type *knamed; - } u; -}; - -/* Information kept for an indirect type. */ - -struct debug_indirect_type -{ - /* Slot where the final type will appear. */ - debug_type *slot; - /* Tag. */ - const char *tag; -}; - -/* Information kept for a struct, union, or class. */ - -struct debug_class_type -{ - /* NULL terminated array of fields. */ - debug_field *fields; - /* A mark field which indicates whether the struct has already been - printed. */ - unsigned int mark; - /* This is used to uniquely identify unnamed structs when printing. */ - unsigned int id; - /* The remaining fields are only used for DEBUG_KIND_CLASS and - DEBUG_KIND_UNION_CLASS. */ - /* NULL terminated array of base classes. */ - debug_baseclass *baseclasses; - /* NULL terminated array of methods. */ - debug_method *methods; - /* The type of the class providing the virtual function table for - this class. This may point to the type itself. */ - debug_type vptrbase; -}; - -/* Information kept for an enum. */ - -struct debug_enum_type -{ - /* NULL terminated array of names. */ - const char **names; - /* Array of corresponding values. */ - bfd_signed_vma *values; -}; - -/* Information kept for a function. FIXME: We should be able to - record the parameter types. */ - -struct debug_function_type -{ - /* Return type. */ - debug_type return_type; - /* NULL terminated array of argument types. */ - debug_type *arg_types; - /* Whether the function takes a variable number of arguments. */ - boolean varargs; -}; - -/* Information kept for a range. */ - -struct debug_range_type -{ - /* Range base type. */ - debug_type type; - /* Lower bound. */ - bfd_signed_vma lower; - /* Upper bound. */ - bfd_signed_vma upper; -}; - -/* Information kept for an array. */ - -struct debug_array_type -{ - /* Element type. */ - debug_type element_type; - /* Range type. */ - debug_type range_type; - /* Lower bound. */ - bfd_signed_vma lower; - /* Upper bound. */ - bfd_signed_vma upper; - /* Whether this array is really a string. */ - boolean stringp; -}; - -/* Information kept for a set. */ - -struct debug_set_type -{ - /* Base type. */ - debug_type type; - /* Whether this set is really a bitstring. */ - boolean bitstringp; -}; - -/* Information kept for an offset type (a based pointer). */ - -struct debug_offset_type -{ - /* The type the pointer is an offset from. */ - debug_type base_type; - /* The type the pointer points to. */ - debug_type target_type; -}; - -/* Information kept for a method type. */ - -struct debug_method_type -{ - /* The return type. */ - debug_type return_type; - /* The object type which this method is for. */ - debug_type domain_type; - /* A NULL terminated array of argument types. */ - debug_type *arg_types; - /* Whether the method takes a variable number of arguments. */ - boolean varargs; -}; - -/* Information kept for a named type. */ - -struct debug_named_type -{ - /* Name. */ - struct debug_name *name; - /* Real type. */ - debug_type type; -}; - -/* A field in a struct or union. */ - -struct debug_field -{ - /* Name of the field. */ - const char *name; - /* Type of the field. */ - struct debug_type *type; - /* Visibility of the field. */ - enum debug_visibility visibility; - /* Whether this is a static member. */ - boolean static_member; - union - { - /* If static_member is false. */ - struct - { - /* Bit position of the field in the struct. */ - unsigned int bitpos; - /* Size of the field in bits. */ - unsigned int bitsize; - } f; - /* If static_member is true. */ - struct - { - const char *physname; - } s; - } u; -}; - -/* A base class for an object. */ - -struct debug_baseclass -{ - /* Type of the base class. */ - struct debug_type *type; - /* Bit position of the base class in the object. */ - unsigned int bitpos; - /* Whether the base class is virtual. */ - boolean virtual; - /* Visibility of the base class. */ - enum debug_visibility visibility; -}; - -/* A method of an object. */ - -struct debug_method -{ - /* The name of the method. */ - const char *name; - /* A NULL terminated array of different types of variants. */ - struct debug_method_variant **variants; -}; - -/* The variants of a method function of an object. These indicate - which method to run. */ - -struct debug_method_variant -{ - /* The physical name of the function. */ - const char *physname; - /* The type of the function. */ - struct debug_type *type; - /* The visibility of the function. */ - enum debug_visibility visibility; - /* Whether the function is const. */ - boolean constp; - /* Whether the function is volatile. */ - boolean volatilep; - /* The offset to the function in the virtual function table. */ - bfd_vma voffset; - /* If voffset is VOFFSET_STATIC_METHOD, this is a static method. */ -#define VOFFSET_STATIC_METHOD ((bfd_vma) -1) - /* Context of a virtual method function. */ - struct debug_type *context; -}; - -/* A variable. This is the information we keep for a variable object. - This has no name; a name is associated with a variable in a - debug_name structure. */ - -struct debug_variable -{ - /* Kind of variable. */ - enum debug_var_kind kind; - /* Type. */ - debug_type type; - /* Value. The interpretation of the value depends upon kind. */ - bfd_vma val; -}; - -/* A function. This has no name; a name is associated with a function - in a debug_name structure. */ - -struct debug_function -{ - /* Return type. */ - debug_type return_type; - /* Parameter information. */ - struct debug_parameter *parameters; - /* Block information. The first structure on the list is the main - block of the function, and describes function local variables. */ - struct debug_block *blocks; -}; - -/* A function parameter. */ - -struct debug_parameter -{ - /* Next parameter. */ - struct debug_parameter *next; - /* Name. */ - const char *name; - /* Type. */ - debug_type type; - /* Kind. */ - enum debug_parm_kind kind; - /* Value (meaning depends upon kind). */ - bfd_vma val; -}; - -/* A typed constant. */ - -struct debug_typed_constant -{ - /* Type. */ - debug_type type; - /* Value. FIXME: We may eventually need to support non-integral - values. */ - bfd_vma val; -}; - -/* Information about a block within a function. */ - -struct debug_block -{ - /* Next block with the same parent. */ - struct debug_block *next; - /* Parent block. */ - struct debug_block *parent; - /* List of child blocks. */ - struct debug_block *children; - /* Start address of the block. */ - bfd_vma start; - /* End address of the block. */ - bfd_vma end; - /* Local variables. */ - struct debug_namespace *locals; -}; - -/* Line number information we keep for a compilation unit. FIXME: - This structure is easy to create, but can be very space - inefficient. */ - -struct debug_lineno -{ - /* More line number information for this block. */ - struct debug_lineno *next; - /* Source file. */ - struct debug_file *file; - /* Line numbers, terminated by a -1 or the end of the array. */ -#define DEBUG_LINENO_COUNT 10 - unsigned long linenos[DEBUG_LINENO_COUNT]; - /* Addresses for the line numbers. */ - bfd_vma addrs[DEBUG_LINENO_COUNT]; -}; - -/* A namespace. This is a mapping from names to objects. FIXME: This - should be implemented as a hash table. */ - -struct debug_namespace -{ - /* List of items in this namespace. */ - struct debug_name *list; - /* Pointer to where the next item in this namespace should go. */ - struct debug_name **tail; -}; - -/* Kinds of objects that appear in a namespace. */ - -enum debug_object_kind -{ - /* A type. */ - DEBUG_OBJECT_TYPE, - /* A tagged type (really a different sort of namespace). */ - DEBUG_OBJECT_TAG, - /* A variable. */ - DEBUG_OBJECT_VARIABLE, - /* A function. */ - DEBUG_OBJECT_FUNCTION, - /* An integer constant. */ - DEBUG_OBJECT_INT_CONSTANT, - /* A floating point constant. */ - DEBUG_OBJECT_FLOAT_CONSTANT, - /* A typed constant. */ - DEBUG_OBJECT_TYPED_CONSTANT -}; - -/* Linkage of an object that appears in a namespace. */ - -enum debug_object_linkage -{ - /* Local variable. */ - DEBUG_LINKAGE_AUTOMATIC, - /* Static--either file static or function static, depending upon the - namespace is. */ - DEBUG_LINKAGE_STATIC, - /* Global. */ - DEBUG_LINKAGE_GLOBAL, - /* No linkage. */ - DEBUG_LINKAGE_NONE -}; - -/* A name in a namespace. */ - -struct debug_name -{ - /* Next name in this namespace. */ - struct debug_name *next; - /* Name. */ - const char *name; - /* Mark. This is used by debug_write. */ - unsigned int mark; - /* Kind of object. */ - enum debug_object_kind kind; - /* Linkage of object. */ - enum debug_object_linkage linkage; - /* Tagged union with additional information about the object. */ - union - { - /* DEBUG_OBJECT_TYPE. */ - struct debug_type *type; - /* DEBUG_OBJECT_TAG. */ - struct debug_type *tag; - /* DEBUG_OBJECT_VARIABLE. */ - struct debug_variable *variable; - /* DEBUG_OBJECT_FUNCTION. */ - struct debug_function *function; - /* DEBUG_OBJECT_INT_CONSTANT. */ - bfd_vma int_constant; - /* DEBUG_OBJECT_FLOAT_CONSTANT. */ - double float_constant; - /* DEBUG_OBJECT_TYPED_CONSTANT. */ - struct debug_typed_constant *typed_constant; - } u; -}; - -/* During debug_write, a linked list of these structures is used to - keep track of ID numbers that have been assigned to classes. */ - -struct debug_class_id -{ - /* Next ID number. */ - struct debug_class_id *next; - /* The type with the ID. */ - struct debug_type *type; - /* The tag; NULL if no tag. */ - const char *tag; -}; - -/* During debug_type_samep, a linked list of these structures is kept - on the stack to avoid infinite recursion. */ - -struct debug_type_compare_list -{ - /* Next type on list. */ - struct debug_type_compare_list *next; - /* The types we are comparing. */ - struct debug_type *t1; - struct debug_type *t2; -}; - -/* Local functions. */ - -static void debug_error PARAMS ((const char *)); -static struct debug_name *debug_add_to_namespace - PARAMS ((struct debug_handle *, struct debug_namespace **, const char *, - enum debug_object_kind, enum debug_object_linkage)); -static struct debug_name *debug_add_to_current_namespace - PARAMS ((struct debug_handle *, const char *, enum debug_object_kind, - enum debug_object_linkage)); -static struct debug_type *debug_make_type - PARAMS ((struct debug_handle *, enum debug_type_kind, unsigned int)); -static struct debug_type *debug_get_real_type PARAMS ((PTR, debug_type)); -static boolean debug_write_name - PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR, - struct debug_name *)); -static boolean debug_write_type - PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR, - struct debug_type *, struct debug_name *)); -static boolean debug_write_class_type - PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR, - struct debug_type *, const char *)); -static boolean debug_write_function - PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR, - const char *, enum debug_object_linkage, struct debug_function *)); -static boolean debug_write_block - PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR, - struct debug_block *)); -static boolean debug_write_linenos - PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR, - bfd_vma)); -static boolean debug_set_class_id - PARAMS ((struct debug_handle *, const char *, struct debug_type *)); -static boolean debug_type_samep - PARAMS ((struct debug_handle *, struct debug_type *, struct debug_type *)); -static boolean debug_class_type_samep - PARAMS ((struct debug_handle *, struct debug_type *, struct debug_type *)); - -/* Issue an error message. */ - -static void -debug_error (message) - const char *message; -{ - fprintf (stderr, "%s\n", message); -} - -/* Add an object to a namespace. */ - -static struct debug_name * -debug_add_to_namespace (info, nsp, name, kind, linkage) - struct debug_handle *info; - struct debug_namespace **nsp; - const char *name; - enum debug_object_kind kind; - enum debug_object_linkage linkage; -{ - struct debug_name *n; - struct debug_namespace *ns; - - n = (struct debug_name *) xmalloc (sizeof *n); - memset (n, 0, sizeof *n); - - n->name = name; - n->kind = kind; - n->linkage = linkage; - - ns = *nsp; - if (ns == NULL) - { - ns = (struct debug_namespace *) xmalloc (sizeof *ns); - memset (ns, 0, sizeof *ns); - - ns->tail = &ns->list; - - *nsp = ns; - } - - *ns->tail = n; - ns->tail = &n->next; - - return n; -} - -/* Add an object to the current namespace. */ - -static struct debug_name * -debug_add_to_current_namespace (info, name, kind, linkage) - struct debug_handle *info; - const char *name; - enum debug_object_kind kind; - enum debug_object_linkage linkage; -{ - struct debug_namespace **nsp; - - if (info->current_unit == NULL - || info->current_file == NULL) - { - debug_error ("debug_add_to_current_namespace: no current file"); - return NULL; - } - - if (info->current_block != NULL) - nsp = &info->current_block->locals; - else - nsp = &info->current_file->globals; - - return debug_add_to_namespace (info, nsp, name, kind, linkage); -} - -/* Return a handle for debugging information. */ - -PTR -debug_init () -{ - struct debug_handle *ret; - - ret = (struct debug_handle *) xmalloc (sizeof *ret); - memset (ret, 0, sizeof *ret); - return (PTR) ret; -} - -/* Set the source filename. This implicitly starts a new compilation - unit. */ - -boolean -debug_set_filename (handle, name) - PTR handle; - const char *name; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_file *nfile; - struct debug_unit *nunit; - - if (name == NULL) - name = ""; - - nfile = (struct debug_file *) xmalloc (sizeof *nfile); - memset (nfile, 0, sizeof *nfile); - - nfile->filename = name; - - nunit = (struct debug_unit *) xmalloc (sizeof *nunit); - memset (nunit, 0, sizeof *nunit); - - nunit->files = nfile; - info->current_file = nfile; - - if (info->current_unit != NULL) - info->current_unit->next = nunit; - else - { - assert (info->units == NULL); - info->units = nunit; - } - - info->current_unit = nunit; - - info->current_function = NULL; - info->current_block = NULL; - info->current_lineno = NULL; - - return true; -} - -/* Change source files to the given file name. This is used for - include files in a single compilation unit. */ - -boolean -debug_start_source (handle, name) - PTR handle; - const char *name; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_file *f, **pf; - - if (name == NULL) - name = ""; - - if (info->current_unit == NULL) - { - debug_error ("debug_start_source: no debug_set_filename call"); - return false; - } - - for (f = info->current_unit->files; f != NULL; f = f->next) - { - if (f->filename[0] == name[0] - && f->filename[1] == name[1] - && strcmp (f->filename, name) == 0) - { - info->current_file = f; - return true; - } - } - - f = (struct debug_file *) xmalloc (sizeof *f); - memset (f, 0, sizeof *f); - - f->filename = name; - - for (pf = &info->current_file->next; - *pf != NULL; - pf = &(*pf)->next) - ; - *pf = f; - - info->current_file = f; - - return true; -} - -/* Record a function definition. This implicitly starts a function - block. The debug_type argument is the type of the return value. - The boolean indicates whether the function is globally visible. - The bfd_vma is the address of the start of the function. Currently - the parameter types are specified by calls to - debug_record_parameter. FIXME: There is no way to specify nested - functions. */ - -boolean -debug_record_function (handle, name, return_type, global, addr) - PTR handle; - const char *name; - debug_type return_type; - boolean global; - bfd_vma addr; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_function *f; - struct debug_block *b; - struct debug_name *n; - - if (name == NULL) - name = ""; - if (return_type == NULL) - return false; - - if (info->current_unit == NULL) - { - debug_error ("debug_record_function: no debug_set_filename call"); - return false; - } - - f = (struct debug_function *) xmalloc (sizeof *f); - memset (f, 0, sizeof *f); - - f->return_type = return_type; - - b = (struct debug_block *) xmalloc (sizeof *b); - memset (b, 0, sizeof *b); - - b->start = addr; - b->end = (bfd_vma) -1; - - f->blocks = b; - - info->current_function = f; - info->current_block = b; - - /* FIXME: If we could handle nested functions, this would be the - place: we would want to use a different namespace. */ - n = debug_add_to_namespace (info, - &info->current_file->globals, - name, - DEBUG_OBJECT_FUNCTION, - (global - ? DEBUG_LINKAGE_GLOBAL - : DEBUG_LINKAGE_STATIC)); - if (n == NULL) - return false; - - n->u.function = f; - - return true; -} - -/* Record a parameter for the current function. */ - -boolean -debug_record_parameter (handle, name, type, kind, val) - PTR handle; - const char *name; - debug_type type; - enum debug_parm_kind kind; - bfd_vma val; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_parameter *p, **pp; - - if (name == NULL || type == NULL) - return false; - - if (info->current_unit == NULL - || info->current_function == NULL) - { - debug_error ("debug_record_parameter: no current function"); - return false; - } - - p = (struct debug_parameter *) xmalloc (sizeof *p); - memset (p, 0, sizeof *p); - - p->name = name; - p->type = type; - p->kind = kind; - p->val = val; - - for (pp = &info->current_function->parameters; - *pp != NULL; - pp = &(*pp)->next) - ; - *pp = p; - - return true; -} - -/* End a function. FIXME: This should handle function nesting. */ - -boolean -debug_end_function (handle, addr) - PTR handle; - bfd_vma addr; -{ - struct debug_handle *info = (struct debug_handle *) handle; - - if (info->current_unit == NULL - || info->current_block == NULL - || info->current_function == NULL) - { - debug_error ("debug_end_function: no current function"); - return false; - } - - if (info->current_block->parent != NULL) - { - debug_error ("debug_end_function: some blocks were not closed"); - return false; - } - - info->current_block->end = addr; - - info->current_function = NULL; - info->current_block = NULL; - - return true; -} - -/* Start a block in a function. All local information will be - recorded in this block, until the matching call to debug_end_block. - debug_start_block and debug_end_block may be nested. The bfd_vma - argument is the address at which this block starts. */ - -boolean -debug_start_block (handle, addr) - PTR handle; - bfd_vma addr; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_block *b, **pb; - - /* We must always have a current block: debug_record_function sets - one up. */ - if (info->current_unit == NULL - || info->current_block == NULL) - { - debug_error ("debug_start_block: no current block"); - return false; - } - - b = (struct debug_block *) xmalloc (sizeof *b); - memset (b, 0, sizeof *b); - - b->parent = info->current_block; - b->start = addr; - b->end = (bfd_vma) -1; - - /* This new block is a child of the current block. */ - for (pb = &info->current_block->children; - *pb != NULL; - pb = &(*pb)->next) - ; - *pb = b; - - info->current_block = b; - - return true; -} - -/* Finish a block in a function. This matches the call to - debug_start_block. The argument is the address at which this block - ends. */ - -boolean -debug_end_block (handle, addr) - PTR handle; - bfd_vma addr; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_block *parent; - - if (info->current_unit == NULL - || info->current_block == NULL) - { - debug_error ("debug_end_block: no current block"); - return false; - } - - parent = info->current_block->parent; - if (parent == NULL) - { - debug_error ("debug_end_block: attempt to close top level block"); - return false; - } - - info->current_block->end = addr; - - info->current_block = parent; - - return true; -} - -/* Associate a line number in the current source file and function - with a given address. */ - -boolean -debug_record_line (handle, lineno, addr) - PTR handle; - unsigned long lineno; - bfd_vma addr; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_lineno *l; - unsigned int i; - - if (info->current_unit == NULL) - { - debug_error ("debug_record_line: no current unit"); - return false; - } - - l = info->current_lineno; - if (l != NULL && l->file == info->current_file) - { - for (i = 0; i < DEBUG_LINENO_COUNT; i++) - { - if (l->linenos[i] == (unsigned long) -1) - { - l->linenos[i] = lineno; - l->addrs[i] = addr; - return true; - } - } - } - - /* If we get here, then either 1) there is no current_lineno - structure, which means this is the first line number in this - compilation unit, 2) the current_lineno structure is for a - different file, or 3) the current_lineno structure is full. - Regardless, we want to allocate a new debug_lineno structure, put - it in the right place, and make it the new current_lineno - structure. */ - - l = (struct debug_lineno *) xmalloc (sizeof *l); - memset (l, 0, sizeof *l); - - l->file = info->current_file; - l->linenos[0] = lineno; - l->addrs[0] = addr; - for (i = 1; i < DEBUG_LINENO_COUNT; i++) - l->linenos[i] = (unsigned long) -1; - - if (info->current_lineno != NULL) - info->current_lineno->next = l; - else - info->current_unit->linenos = l; - - info->current_lineno = l; - - return true; -} - -/* Start a named common block. This is a block of variables that may - move in memory. */ - -boolean -debug_start_common_block (handle, name) - PTR handle; - const char *name; -{ - /* FIXME */ - debug_error ("debug_start_common_block: not implemented"); - return false; -} - -/* End a named common block. */ - -boolean -debug_end_common_block (handle, name) - PTR handle; - const char *name; -{ - /* FIXME */ - debug_error ("debug_end_common_block: not implemented"); - return false; -} - -/* Record a named integer constant. */ - -boolean -debug_record_int_const (handle, name, val) - PTR handle; - const char *name; - bfd_vma val; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_name *n; - - if (name == NULL) - return false; - - n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_INT_CONSTANT, - DEBUG_LINKAGE_NONE); - if (n == NULL) - return false; - - n->u.int_constant = val; - - return true; -} - -/* Record a named floating point constant. */ - -boolean -debug_record_float_const (handle, name, val) - PTR handle; - const char *name; - double val; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_name *n; - - if (name == NULL) - return false; - - n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_FLOAT_CONSTANT, - DEBUG_LINKAGE_NONE); - if (n == NULL) - return false; - - n->u.float_constant = val; - - return true; -} - -/* Record a typed constant with an integral value. */ - -boolean -debug_record_typed_const (handle, name, type, val) - PTR handle; - const char *name; - debug_type type; - bfd_vma val; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_name *n; - struct debug_typed_constant *tc; - - if (name == NULL || type == NULL) - return false; - - n = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_TYPED_CONSTANT, - DEBUG_LINKAGE_NONE); - if (n == NULL) - return false; - - tc = (struct debug_typed_constant *) xmalloc (sizeof *tc); - memset (tc, 0, sizeof *tc); - - tc->type = type; - tc->val = val; - - n->u.typed_constant = tc; - - return true; -} - -/* Record a label. */ - -boolean -debug_record_label (handle, name, type, addr) - PTR handle; - const char *name; - debug_type type; - bfd_vma addr; -{ - /* FIXME. */ - debug_error ("debug_record_label not implemented"); - return false; -} - -/* Record a variable. */ - -boolean -debug_record_variable (handle, name, type, kind, val) - PTR handle; - const char *name; - debug_type type; - enum debug_var_kind kind; - bfd_vma val; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_namespace **nsp; - enum debug_object_linkage linkage; - struct debug_name *n; - struct debug_variable *v; - - if (name == NULL || type == NULL) - return false; - - if (info->current_unit == NULL - || info->current_file == NULL) - { - debug_error ("debug_record_variable: no current file"); - return false; - } - - if (kind == DEBUG_GLOBAL || kind == DEBUG_STATIC) - { - nsp = &info->current_file->globals; - if (kind == DEBUG_GLOBAL) - linkage = DEBUG_LINKAGE_GLOBAL; - else - linkage = DEBUG_LINKAGE_STATIC; - } - else - { - if (info->current_block == NULL) - { - debug_error ("debug_record_variable: no current block"); - return false; - } - nsp = &info->current_block->locals; - linkage = DEBUG_LINKAGE_AUTOMATIC; - } - - n = debug_add_to_namespace (info, nsp, name, DEBUG_OBJECT_VARIABLE, linkage); - if (n == NULL) - return false; - - v = (struct debug_variable *) xmalloc (sizeof *v); - memset (v, 0, sizeof *v); - - v->kind = kind; - v->type = type; - v->val = val; - - n->u.variable = v; - - return true; -} - -/* Make a type with a given kind and size. */ - -/*ARGSUSED*/ -static struct debug_type * -debug_make_type (info, kind, size) - struct debug_handle *info; - enum debug_type_kind kind; - unsigned int size; -{ - struct debug_type *t; - - t = (struct debug_type *) xmalloc (sizeof *t); - memset (t, 0, sizeof *t); - - t->kind = kind; - t->size = size; - - return t; -} - -/* Make an indirect type which may be used as a placeholder for a type - which is referenced before it is defined. */ - -debug_type -debug_make_indirect_type (handle, slot, tag) - PTR handle; - debug_type *slot; - const char *tag; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_indirect_type *i; - - t = debug_make_type (info, DEBUG_KIND_INDIRECT, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - i = (struct debug_indirect_type *) xmalloc (sizeof *i); - memset (i, 0, sizeof *i); - - i->slot = slot; - i->tag = tag; - - t->u.kindirect = i; - - return t; -} - -/* Make a void type. There is only one of these. */ - -debug_type -debug_make_void_type (handle) - PTR handle; -{ - struct debug_handle *info = (struct debug_handle *) handle; - - return debug_make_type (info, DEBUG_KIND_VOID, 0); -} - -/* Make an integer type of a given size. The boolean argument is true - if the integer is unsigned. */ - -debug_type -debug_make_int_type (handle, size, unsignedp) - PTR handle; - unsigned int size; - boolean unsignedp; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - - t = debug_make_type (info, DEBUG_KIND_INT, size); - if (t == NULL) - return DEBUG_TYPE_NULL; - - t->u.kint = unsignedp; - - return t; -} - -/* Make a floating point type of a given size. FIXME: On some - platforms, like an Alpha, you probably need to be able to specify - the format. */ - -debug_type -debug_make_float_type (handle, size) - PTR handle; - unsigned int size; -{ - struct debug_handle *info = (struct debug_handle *) handle; - - return debug_make_type (info, DEBUG_KIND_FLOAT, size); -} - -/* Make a boolean type of a given size. */ - -debug_type -debug_make_bool_type (handle, size) - PTR handle; - unsigned int size; -{ - struct debug_handle *info = (struct debug_handle *) handle; - - return debug_make_type (info, DEBUG_KIND_BOOL, size); -} - -/* Make a complex type of a given size. */ - -debug_type -debug_make_complex_type (handle, size) - PTR handle; - unsigned int size; -{ - struct debug_handle *info = (struct debug_handle *) handle; - - return debug_make_type (info, DEBUG_KIND_COMPLEX, size); -} - -/* Make a structure type. The second argument is true for a struct, - false for a union. The third argument is the size of the struct. - The fourth argument is a NULL terminated array of fields. */ - -debug_type -debug_make_struct_type (handle, structp, size, fields) - PTR handle; - boolean structp; - bfd_vma size; - debug_field *fields; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_class_type *c; - - t = debug_make_type (info, - structp ? DEBUG_KIND_STRUCT : DEBUG_KIND_UNION, - size); - if (t == NULL) - return DEBUG_TYPE_NULL; - - c = (struct debug_class_type *) xmalloc (sizeof *c); - memset (c, 0, sizeof *c); - - c->fields = fields; - - t->u.kclass = c; - - return t; -} - -/* Make an object type. The first three arguments after the handle - are the same as for debug_make_struct_type. The next arguments are - a NULL terminated array of base classes, a NULL terminated array of - methods, the type of the object holding the virtual function table - if it is not this object, and a boolean which is true if this - object has its own virtual function table. */ - -debug_type -debug_make_object_type (handle, structp, size, fields, baseclasses, - methods, vptrbase, ownvptr) - PTR handle; - boolean structp; - bfd_vma size; - debug_field *fields; - debug_baseclass *baseclasses; - debug_method *methods; - debug_type vptrbase; - boolean ownvptr; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_class_type *c; - - t = debug_make_type (info, - structp ? DEBUG_KIND_CLASS : DEBUG_KIND_UNION_CLASS, - size); - if (t == NULL) - return DEBUG_TYPE_NULL; - - c = (struct debug_class_type *) xmalloc (sizeof *c); - memset (c, 0, sizeof *c); - - c->fields = fields; - c->baseclasses = baseclasses; - c->methods = methods; - if (ownvptr) - c->vptrbase = t; - else - c->vptrbase = vptrbase; - - t->u.kclass = c; - - return t; -} - -/* Make an enumeration type. The arguments are a null terminated - array of strings, and an array of corresponding values. */ - -debug_type -debug_make_enum_type (handle, names, values) - PTR handle; - const char **names; - bfd_signed_vma *values; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_enum_type *e; - - t = debug_make_type (info, DEBUG_KIND_ENUM, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - e = (struct debug_enum_type *) xmalloc (sizeof *e); - memset (e, 0, sizeof *e); - - e->names = names; - e->values = values; - - t->u.kenum = e; - - return t; -} - -/* Make a pointer to a given type. */ - -debug_type -debug_make_pointer_type (handle, type) - PTR handle; - debug_type type; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - if (type->pointer != DEBUG_TYPE_NULL) - return type->pointer; - - t = debug_make_type (info, DEBUG_KIND_POINTER, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - t->u.kpointer = type; - - type->pointer = t; - - return t; -} - -/* Make a function returning a given type. FIXME: We should be able - to record the parameter types. */ - -debug_type -debug_make_function_type (handle, type, arg_types, varargs) - PTR handle; - debug_type type; - debug_type *arg_types; - boolean varargs; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_function_type *f; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_FUNCTION, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - f = (struct debug_function_type *) xmalloc (sizeof *f); - memset (f, 0, sizeof *f); - - f->return_type = type; - f->arg_types = arg_types; - f->varargs = varargs; - - t->u.kfunction = f; - - return t; -} - -/* Make a reference to a given type. */ - -debug_type -debug_make_reference_type (handle, type) - PTR handle; - debug_type type; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_REFERENCE, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - t->u.kreference = type; - - return t; -} - -/* Make a range of a given type from a lower to an upper bound. */ - -debug_type -debug_make_range_type (handle, type, lower, upper) - PTR handle; - debug_type type; - bfd_signed_vma lower; - bfd_signed_vma upper; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_range_type *r; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_RANGE, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - r = (struct debug_range_type *) xmalloc (sizeof *r); - memset (r, 0, sizeof *r); - - r->type = type; - r->lower = lower; - r->upper = upper; - - t->u.krange = r; - - return t; -} - -/* Make an array type. The second argument is the type of an element - of the array. The third argument is the type of a range of the - array. The fourth and fifth argument are the lower and upper - bounds, respectively. The sixth argument is true if this array is - actually a string, as in C. */ - -debug_type -debug_make_array_type (handle, element_type, range_type, lower, upper, - stringp) - PTR handle; - debug_type element_type; - debug_type range_type; - bfd_signed_vma lower; - bfd_signed_vma upper; - boolean stringp; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_array_type *a; - - if (element_type == NULL || range_type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_ARRAY, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - a = (struct debug_array_type *) xmalloc (sizeof *a); - memset (a, 0, sizeof *a); - - a->element_type = element_type; - a->range_type = range_type; - a->lower = lower; - a->upper = upper; - a->stringp = stringp; - - t->u.karray = a; - - return t; -} - -/* Make a set of a given type. For example, a Pascal set type. The - boolean argument is true if this set is actually a bitstring, as in - CHILL. */ - -debug_type -debug_make_set_type (handle, type, bitstringp) - PTR handle; - debug_type type; - boolean bitstringp; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_set_type *s; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_SET, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - s = (struct debug_set_type *) xmalloc (sizeof *s); - memset (s, 0, sizeof *s); - - s->type = type; - s->bitstringp = bitstringp; - - t->u.kset = s; - - return t; -} - -/* Make a type for a pointer which is relative to an object. The - second argument is the type of the object to which the pointer is - relative. The third argument is the type that the pointer points - to. */ - -debug_type -debug_make_offset_type (handle, base_type, target_type) - PTR handle; - debug_type base_type; - debug_type target_type; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_offset_type *o; - - if (base_type == NULL || target_type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_OFFSET, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - o = (struct debug_offset_type *) xmalloc (sizeof *o); - memset (o, 0, sizeof *o); - - o->base_type = base_type; - o->target_type = target_type; - - t->u.koffset = o; - - return t; -} - -/* Make a type for a method function. The second argument is the - return type, the third argument is the domain, and the fourth - argument is a NULL terminated array of argument types. */ - -debug_type -debug_make_method_type (handle, return_type, domain_type, arg_types, varargs) - PTR handle; - debug_type return_type; - debug_type domain_type; - debug_type *arg_types; - boolean varargs; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_method_type *m; - - if (return_type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_METHOD, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - m = (struct debug_method_type *) xmalloc (sizeof *m); - memset (m, 0, sizeof *m); - - m->return_type = return_type; - m->domain_type = domain_type; - m->arg_types = arg_types; - m->varargs = varargs; - - t->u.kmethod = m; - - return t; -} - -/* Make a const qualified version of a given type. */ - -debug_type -debug_make_const_type (handle, type) - PTR handle; - debug_type type; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_CONST, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - t->u.kconst = type; - - return t; -} - -/* Make a volatile qualified version of a given type. */ - -debug_type -debug_make_volatile_type (handle, type) - PTR handle; - debug_type type; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - - if (type == NULL) - return DEBUG_TYPE_NULL; - - t = debug_make_type (info, DEBUG_KIND_VOLATILE, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - t->u.kvolatile = type; - - return t; -} - -/* Make an undefined tagged type. For example, a struct which has - been mentioned, but not defined. */ - -debug_type -debug_make_undefined_tagged_type (handle, name, kind) - PTR handle; - const char *name; - enum debug_type_kind kind; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - - if (name == NULL) - return DEBUG_TYPE_NULL; - - switch (kind) - { - case DEBUG_KIND_STRUCT: - case DEBUG_KIND_UNION: - case DEBUG_KIND_CLASS: - case DEBUG_KIND_UNION_CLASS: - case DEBUG_KIND_ENUM: - break; - - default: - debug_error ("debug_make_undefined_type: unsupported kind"); - return DEBUG_TYPE_NULL; - } - - t = debug_make_type (info, kind, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - return debug_tag_type (handle, name, t); -} - -/* Make a base class for an object. The second argument is the base - class type. The third argument is the bit position of this base - class in the object (always 0 unless doing multiple inheritance). - The fourth argument is whether this is a virtual class. The fifth - argument is the visibility of the base class. */ - -/*ARGSUSED*/ -debug_baseclass -debug_make_baseclass (handle, type, bitpos, virtual, visibility) - PTR handle; - debug_type type; - bfd_vma bitpos; - boolean virtual; - enum debug_visibility visibility; -{ - struct debug_baseclass *b; - - b = (struct debug_baseclass *) xmalloc (sizeof *b); - memset (b, 0, sizeof *b); - - b->type = type; - b->bitpos = bitpos; - b->virtual = virtual; - b->visibility = visibility; - - return b; -} - -/* Make a field for a struct. The second argument is the name. The - third argument is the type of the field. The fourth argument is - the bit position of the field. The fifth argument is the size of - the field (it may be zero). The sixth argument is the visibility - of the field. */ - -/*ARGSUSED*/ -debug_field -debug_make_field (handle, name, type, bitpos, bitsize, visibility) - PTR handle; - const char *name; - debug_type type; - bfd_vma bitpos; - bfd_vma bitsize; - enum debug_visibility visibility; -{ - struct debug_field *f; - - f = (struct debug_field *) xmalloc (sizeof *f); - memset (f, 0, sizeof *f); - - f->name = name; - f->type = type; - f->static_member = false; - f->u.f.bitpos = bitpos; - f->u.f.bitsize = bitsize; - f->visibility = visibility; - - return f; -} - -/* Make a static member of an object. The second argument is the - name. The third argument is the type of the member. The fourth - argument is the physical name of the member (i.e., the name as a - global variable). The fifth argument is the visibility of the - member. */ - -/*ARGSUSED*/ -debug_field -debug_make_static_member (handle, name, type, physname, visibility) - PTR handle; - const char *name; - debug_type type; - const char *physname; - enum debug_visibility visibility; -{ - struct debug_field *f; - - f = (struct debug_field *) xmalloc (sizeof *f); - memset (f, 0, sizeof *f); - - f->name = name; - f->type = type; - f->static_member = true; - f->u.s.physname = physname; - f->visibility = visibility; - - return f; -} - -/* Make a method. The second argument is the name, and the third - argument is a NULL terminated array of method variants. */ - -/*ARGSUSED*/ -debug_method -debug_make_method (handle, name, variants) - PTR handle; - const char *name; - debug_method_variant *variants; -{ - struct debug_method *m; - - m = (struct debug_method *) xmalloc (sizeof *m); - memset (m, 0, sizeof *m); - - m->name = name; - m->variants = variants; - - return m; -} - -/* Make a method argument. The second argument is the real name of - the function. The third argument is the type of the function. The - fourth argument is the visibility. The fifth argument is whether - this is a const function. The sixth argument is whether this is a - volatile function. The seventh argument is the offset in the - virtual function table, if any. The eighth argument is the virtual - function context. FIXME: Are the const and volatile arguments - necessary? Could we just use debug_make_const_type? */ - -/*ARGSUSED*/ -debug_method_variant -debug_make_method_variant (handle, physname, type, visibility, constp, - volatilep, voffset, context) - PTR handle; - const char *physname; - debug_type type; - enum debug_visibility visibility; - boolean constp; - boolean volatilep; - bfd_vma voffset; - debug_type context; -{ - struct debug_method_variant *m; - - m = (struct debug_method_variant *) xmalloc (sizeof *m); - memset (m, 0, sizeof *m); - - m->physname = physname; - m->type = type; - m->visibility = visibility; - m->constp = constp; - m->volatilep = volatilep; - m->voffset = voffset; - m->context = context; - - return m; -} - -/* Make a static method argument. The arguments are the same as for - debug_make_method_variant, except that the last two are omitted - since a static method can not also be virtual. */ - -debug_method_variant -debug_make_static_method_variant (handle, physname, type, visibility, - constp, volatilep) - PTR handle; - const char *physname; - debug_type type; - enum debug_visibility visibility; - boolean constp; - boolean volatilep; -{ - struct debug_method_variant *m; - - m = (struct debug_method_variant *) xmalloc (sizeof *m); - memset (m, 0, sizeof *m); - - m->physname = physname; - m->type = type; - m->visibility = visibility; - m->constp = constp; - m->volatilep = volatilep; - m->voffset = VOFFSET_STATIC_METHOD; - - return m; -} - -/* Name a type. */ - -debug_type -debug_name_type (handle, name, type) - PTR handle; - const char *name; - debug_type type; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_named_type *n; - struct debug_name *nm; - - if (name == NULL || type == NULL) - return DEBUG_TYPE_NULL; - - if (info->current_unit == NULL - || info->current_file == NULL) - { - debug_error ("debug_name_type: no current file"); - return DEBUG_TYPE_NULL; - /* return false; */ - } - - t = debug_make_type (info, DEBUG_KIND_NAMED, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - n = (struct debug_named_type *) xmalloc (sizeof *n); - memset (n, 0, sizeof *n); - - n->type = type; - - t->u.knamed = n; - - /* We always add the name to the global namespace. This is probably - wrong in some cases, but it seems to be right for stabs. FIXME. */ - - nm = debug_add_to_namespace (info, &info->current_file->globals, name, - DEBUG_OBJECT_TYPE, DEBUG_LINKAGE_NONE); - if (nm == NULL) - return DEBUG_TYPE_NULL; - - nm->u.type = t; - - n->name = nm; - - return t; -} - -/* Tag a type. */ - -debug_type -debug_tag_type (handle, name, type) - PTR handle; - const char *name; - debug_type type; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_type *t; - struct debug_named_type *n; - struct debug_name *nm; - - if (name == NULL || type == NULL) - return DEBUG_TYPE_NULL; - - if (info->current_file == NULL) - { - debug_error ("debug_tag_type: no current file"); - return DEBUG_TYPE_NULL; - } - - if (type->kind == DEBUG_KIND_TAGGED) - { - if (strcmp (type->u.knamed->name->name, name) == 0) - return type; - debug_error ("debug_tag_type: extra tag attempted"); - return DEBUG_TYPE_NULL; - } - - t = debug_make_type (info, DEBUG_KIND_TAGGED, 0); - if (t == NULL) - return DEBUG_TYPE_NULL; - - n = (struct debug_named_type *) xmalloc (sizeof *n); - memset (n, 0, sizeof *n); - - n->type = type; - - t->u.knamed = n; - - /* We keep a global namespace of tags for each compilation unit. I - don't know if that is the right thing to do. */ - - nm = debug_add_to_namespace (info, &info->current_file->globals, name, - DEBUG_OBJECT_TAG, DEBUG_LINKAGE_NONE); - if (nm == NULL) - return DEBUG_TYPE_NULL; - - nm->u.tag = t; - - n->name = nm; - - return t; -} - -/* Record the size of a given type. */ - -/*ARGSUSED*/ -boolean -debug_record_type_size (handle, type, size) - PTR handle; - debug_type type; - unsigned int size; -{ -#if 0 - if (type->size != 0 && type->size != size) - fprintf (stderr, "Warning: changing type size from %d to %d\n", - type->size, size); -#endif - - type->size = size; - - return true; -} - -/* Find a named type. */ - -debug_type -debug_find_named_type (handle, name) - PTR handle; - const char *name; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_block *b; - struct debug_file *f; - - /* We only search the current compilation unit. I don't know if - this is right or not. */ - - if (info->current_unit == NULL) - { - debug_error ("debug_find_named_type: no current compilation unit"); - return DEBUG_TYPE_NULL; - } - - for (b = info->current_block; b != NULL; b = b->parent) - { - if (b->locals != NULL) - { - struct debug_name *n; - - for (n = b->locals->list; n != NULL; n = n->next) - { - if (n->kind == DEBUG_OBJECT_TYPE - && n->name[0] == name[0] - && strcmp (n->name, name) == 0) - return n->u.type; - } - } - } - - for (f = info->current_unit->files; f != NULL; f = f->next) - { - if (f->globals != NULL) - { - struct debug_name *n; - - for (n = f->globals->list; n != NULL; n = n->next) - { - if (n->kind == DEBUG_OBJECT_TYPE - && n->name[0] == name[0] - && strcmp (n->name, name) == 0) - return n->u.type; - } - } - } - - return DEBUG_TYPE_NULL; -} - -/* Find a tagged type. */ - -debug_type -debug_find_tagged_type (handle, name, kind) - PTR handle; - const char *name; - enum debug_type_kind kind; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_unit *u; - - /* We search the globals of all the compilation units. I don't know - if this is correct or not. It would be easy to change. */ - - for (u = info->units; u != NULL; u = u->next) - { - struct debug_file *f; - - for (f = u->files; f != NULL; f = f->next) - { - struct debug_name *n; - - if (f->globals != NULL) - { - for (n = f->globals->list; n != NULL; n = n->next) - { - if (n->kind == DEBUG_OBJECT_TAG - && (kind == DEBUG_KIND_ILLEGAL - || n->u.tag->kind == kind) - && n->name[0] == name[0] - && strcmp (n->name, name) == 0) - return n->u.tag; - } - } - } - } - - return DEBUG_TYPE_NULL; -} - -/* Get a base type. */ - -static struct debug_type * -debug_get_real_type (handle, type) - PTR handle; - debug_type type; -{ - switch (type->kind) - { - default: - return type; - case DEBUG_KIND_INDIRECT: - if (*type->u.kindirect->slot != NULL) - return debug_get_real_type (handle, *type->u.kindirect->slot); - return type; - case DEBUG_KIND_NAMED: - case DEBUG_KIND_TAGGED: - return debug_get_real_type (handle, type->u.knamed->type); - } - /*NOTREACHED*/ -} - -/* Get the kind of a type. */ - -enum debug_type_kind -debug_get_type_kind (handle, type) - PTR handle; - debug_type type; -{ - if (type == NULL) - return DEBUG_KIND_ILLEGAL; - type = debug_get_real_type (handle, type); - return type->kind; -} - -/* Get the name of a type. */ - -const char * -debug_get_type_name (handle, type) - PTR handle; - debug_type type; -{ - if (type->kind == DEBUG_KIND_INDIRECT) - { - if (*type->u.kindirect->slot != NULL) - return debug_get_type_name (handle, *type->u.kindirect->slot); - return type->u.kindirect->tag; - } - if (type->kind == DEBUG_KIND_NAMED - || type->kind == DEBUG_KIND_TAGGED) - return type->u.knamed->name->name; - return NULL; -} - -/* Get the size of a type. */ - -bfd_vma -debug_get_type_size (handle, type) - PTR handle; - debug_type type; -{ - if (type == NULL) - return 0; - - /* We don't call debug_get_real_type, because somebody might have - called debug_record_type_size on a named or indirect type. */ - - if (type->size != 0) - return type->size; - - switch (type->kind) - { - default: - return 0; - case DEBUG_KIND_INDIRECT: - if (*type->u.kindirect->slot != NULL) - return debug_get_type_size (handle, *type->u.kindirect->slot); - return 0; - case DEBUG_KIND_NAMED: - case DEBUG_KIND_TAGGED: - return debug_get_type_size (handle, type->u.knamed->type); - } - /*NOTREACHED*/ -} - -/* Get the return type of a function or method type. */ - -debug_type -debug_get_return_type (handle, type) - PTR handle; - debug_type type; -{ - if (type == NULL) - return DEBUG_TYPE_NULL; - type = debug_get_real_type (handle, type); - switch (type->kind) - { - default: - return DEBUG_TYPE_NULL; - case DEBUG_KIND_FUNCTION: - return type->u.kfunction->return_type; - case DEBUG_KIND_METHOD: - return type->u.kmethod->return_type; - } - /*NOTREACHED*/ -} - -/* Get the parameter types of a function or method type (except that - we don't currently store the parameter types of a function). */ - -const debug_type * -debug_get_parameter_types (handle, type, pvarargs) - PTR handle; - debug_type type; - boolean *pvarargs; -{ - if (type == NULL) - return NULL; - type = debug_get_real_type (handle, type); - switch (type->kind) - { - default: - return NULL; - case DEBUG_KIND_FUNCTION: - *pvarargs = type->u.kfunction->varargs; - return type->u.kfunction->arg_types; - case DEBUG_KIND_METHOD: - *pvarargs = type->u.kmethod->varargs; - return type->u.kmethod->arg_types; - } - /*NOTREACHED*/ -} - -/* Get the target type of a type. */ - -debug_type -debug_get_target_type (handle, type) - PTR handle; - debug_type type; -{ - if (type == NULL) - return NULL; - type = debug_get_real_type (handle, type); - switch (type->kind) - { - default: - return NULL; - case DEBUG_KIND_POINTER: - return type->u.kpointer; - case DEBUG_KIND_REFERENCE: - return type->u.kreference; - case DEBUG_KIND_CONST: - return type->u.kconst; - case DEBUG_KIND_VOLATILE: - return type->u.kvolatile; - } - /*NOTREACHED*/ -} - -/* Get the NULL terminated array of fields for a struct, union, or - class. */ - -const debug_field * -debug_get_fields (handle, type) - PTR handle; - debug_type type; -{ - if (type == NULL) - return NULL; - type = debug_get_real_type (handle, type); - switch (type->kind) - { - default: - return NULL; - case DEBUG_KIND_STRUCT: - case DEBUG_KIND_UNION: - case DEBUG_KIND_CLASS: - case DEBUG_KIND_UNION_CLASS: - return type->u.kclass->fields; - } - /*NOTREACHED*/ -} - -/* Get the type of a field. */ - -/*ARGSUSED*/ -debug_type -debug_get_field_type (handle, field) - PTR handle; - debug_field field; -{ - if (field == NULL) - return NULL; - return field->type; -} - -/* Get the name of a field. */ - -/*ARGSUSED*/ -const char * -debug_get_field_name (handle, field) - PTR handle; - debug_field field; -{ - if (field == NULL) - return NULL; - return field->name; -} - -/* Get the bit position of a field. */ - -/*ARGSUSED*/ -bfd_vma -debug_get_field_bitpos (handle, field) - PTR handle; - debug_field field; -{ - if (field == NULL || field->static_member) - return (bfd_vma) -1; - return field->u.f.bitpos; -} - -/* Get the bit size of a field. */ - -/*ARGSUSED*/ -bfd_vma -debug_get_field_bitsize (handle, field) - PTR handle; - debug_field field; -{ - if (field == NULL || field->static_member) - return (bfd_vma) -1; - return field->u.f.bitsize; -} - -/* Get the visibility of a field. */ - -/*ARGSUSED*/ -enum debug_visibility -debug_get_field_visibility (handle, field) - PTR handle; - debug_field field; -{ - if (field == NULL) - return DEBUG_VISIBILITY_IGNORE; - return field->visibility; -} - -/* Get the physical name of a field. */ - -const char * -debug_get_field_physname (handle, field) - PTR handle; - debug_field field; -{ - if (field == NULL || ! field->static_member) - return NULL; - return field->u.s.physname; -} - -/* Write out the debugging information. This is given a handle to - debugging information, and a set of function pointers to call. */ - -boolean -debug_write (handle, fns, fhandle) - PTR handle; - const struct debug_write_fns *fns; - PTR fhandle; -{ - struct debug_handle *info = (struct debug_handle *) handle; - struct debug_unit *u; - - /* We use a mark to tell whether we have already written out a - particular name. We use an integer, so that we don't have to - clear the mark fields if we happen to write out the same - information more than once. */ - ++info->mark; - - /* The base_id field holds an ID value which will never be used, so - that we can tell whether we have assigned an ID during this call - to debug_write. */ - info->base_id = info->class_id; - - /* We keep a linked list of classes for which was have assigned ID's - during this call to debug_write. */ - info->id_list = NULL; - - for (u = info->units; u != NULL; u = u->next) - { - struct debug_file *f; - boolean first_file; - - info->current_write_lineno = u->linenos; - info->current_write_lineno_index = 0; - - if (! (*fns->start_compilation_unit) (fhandle, u->files->filename)) - return false; - - first_file = true; - for (f = u->files; f != NULL; f = f->next) - { - struct debug_name *n; - - if (first_file) - first_file = false; - else - { - if (! (*fns->start_source) (fhandle, f->filename)) - return false; - } - - if (f->globals != NULL) - { - for (n = f->globals->list; n != NULL; n = n->next) - { - if (! debug_write_name (info, fns, fhandle, n)) - return false; - } - } - } - - /* Output any line number information which hasn't already been - handled. */ - if (! debug_write_linenos (info, fns, fhandle, (bfd_vma) -1)) - return false; - } - - return true; -} - -/* Write out an element in a namespace. */ - -static boolean -debug_write_name (info, fns, fhandle, n) - struct debug_handle *info; - const struct debug_write_fns *fns; - PTR fhandle; - struct debug_name *n; -{ - switch (n->kind) - { - case DEBUG_OBJECT_TYPE: - if (! debug_write_type (info, fns, fhandle, n->u.type, n) - || ! (*fns->typdef) (fhandle, n->name)) - return false; - return true; - case DEBUG_OBJECT_TAG: - if (! debug_write_type (info, fns, fhandle, n->u.tag, n)) - return false; - return (*fns->tag) (fhandle, n->name); - case DEBUG_OBJECT_VARIABLE: - if (! debug_write_type (info, fns, fhandle, n->u.variable->type, - (struct debug_name *) NULL)) - return false; - return (*fns->variable) (fhandle, n->name, n->u.variable->kind, - n->u.variable->val); - case DEBUG_OBJECT_FUNCTION: - return debug_write_function (info, fns, fhandle, n->name, - n->linkage, n->u.function); - case DEBUG_OBJECT_INT_CONSTANT: - return (*fns->int_constant) (fhandle, n->name, n->u.int_constant); - case DEBUG_OBJECT_FLOAT_CONSTANT: - return (*fns->float_constant) (fhandle, n->name, n->u.float_constant); - case DEBUG_OBJECT_TYPED_CONSTANT: - if (! debug_write_type (info, fns, fhandle, n->u.typed_constant->type, - (struct debug_name *) NULL)) - return false; - return (*fns->typed_constant) (fhandle, n->name, - n->u.typed_constant->val); - default: - abort (); - return false; - } - /*NOTREACHED*/ -} - -/* Write out a type. If the type is DEBUG_KIND_NAMED or - DEBUG_KIND_TAGGED, then the name argument is the name for which we - are about to call typedef or tag. If the type is anything else, - then the name argument is a tag from a DEBUG_KIND_TAGGED type which - points to this one. */ - -static boolean -debug_write_type (info, fns, fhandle, type, name) - struct debug_handle *info; - const struct debug_write_fns *fns; - PTR fhandle; - struct debug_type *type; - struct debug_name *name; -{ - unsigned int i; - int is; - const char *tag; - - /* If we have a name for this type, just output it. We only output - typedef names after they have been defined. We output type tags - whenever we are not actually defining them. */ - if ((type->kind == DEBUG_KIND_NAMED - || type->kind == DEBUG_KIND_TAGGED) - && (type->u.knamed->name->mark == info->mark - || (type->kind == DEBUG_KIND_TAGGED - && type->u.knamed->name != name))) - { - if (type->kind == DEBUG_KIND_NAMED) - return (*fns->typedef_type) (fhandle, type->u.knamed->name->name); - else - { - struct debug_type *real; - unsigned int id; - - real = debug_get_real_type ((PTR) info, type); - id = 0; - if ((real->kind == DEBUG_KIND_STRUCT - || real->kind == DEBUG_KIND_UNION - || real->kind == DEBUG_KIND_CLASS - || real->kind == DEBUG_KIND_UNION_CLASS) - && real->u.kclass != NULL) - { - if (real->u.kclass->id <= info->base_id) - { - if (! debug_set_class_id (info, - type->u.knamed->name->name, - real)) - return false; - } - id = real->u.kclass->id; - } - - return (*fns->tag_type) (fhandle, type->u.knamed->name->name, id, - real->kind); - } - } - - /* Mark the name after we have already looked for a known name, so - that we don't just define a type in terms of itself. We need to - mark the name here so that a struct containing a pointer to - itself will work. */ - if (name != NULL) - name->mark = info->mark; - - tag = NULL; - if (name != NULL - && type->kind != DEBUG_KIND_NAMED - && type->kind != DEBUG_KIND_TAGGED) - { - assert (name->kind == DEBUG_OBJECT_TAG); - tag = name->name; - } - - switch (type->kind) - { - case DEBUG_KIND_ILLEGAL: - debug_error ("debug_write_type: illegal type encountered"); - return false; - case DEBUG_KIND_INDIRECT: - if (*type->u.kindirect->slot == DEBUG_TYPE_NULL) - return (*fns->empty_type) (fhandle); - return debug_write_type (info, fns, fhandle, *type->u.kindirect->slot, - name); - case DEBUG_KIND_VOID: - return (*fns->void_type) (fhandle); - case DEBUG_KIND_INT: - return (*fns->int_type) (fhandle, type->size, type->u.kint); - case DEBUG_KIND_FLOAT: - return (*fns->float_type) (fhandle, type->size); - case DEBUG_KIND_COMPLEX: - return (*fns->complex_type) (fhandle, type->size); - case DEBUG_KIND_BOOL: - return (*fns->bool_type) (fhandle, type->size); - case DEBUG_KIND_STRUCT: - case DEBUG_KIND_UNION: - if (type->u.kclass != NULL) - { - if (type->u.kclass->id <= info->base_id) - { - if (! debug_set_class_id (info, tag, type)) - return false; - } - - if (info->mark == type->u.kclass->mark) - { - /* We are currently outputting this struct, or we have - already output it. I don't know if this can happen, - but it can happen for a class. */ - assert (type->u.kclass->id > info->base_id); - return (*fns->tag_type) (fhandle, tag, type->u.kclass->id, - type->kind); - } - type->u.kclass->mark = info->mark; - } - - if (! (*fns->start_struct_type) (fhandle, tag, - (type->u.kclass != NULL - ? type->u.kclass->id - : 0), - type->kind == DEBUG_KIND_STRUCT, - type->size)) - return false; - if (type->u.kclass != NULL - && type->u.kclass->fields != NULL) - { - for (i = 0; type->u.kclass->fields[i] != NULL; i++) - { - struct debug_field *f; - - f = type->u.kclass->fields[i]; - if (! debug_write_type (info, fns, fhandle, f->type, - (struct debug_name *) NULL) - || ! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos, - f->u.f.bitsize, f->visibility)) - return false; - } - } - return (*fns->end_struct_type) (fhandle); - case DEBUG_KIND_CLASS: - case DEBUG_KIND_UNION_CLASS: - return debug_write_class_type (info, fns, fhandle, type, tag); - case DEBUG_KIND_ENUM: - if (type->u.kenum == NULL) - return (*fns->enum_type) (fhandle, tag, (const char **) NULL, - (bfd_signed_vma *) NULL); - return (*fns->enum_type) (fhandle, tag, type->u.kenum->names, - type->u.kenum->values); - case DEBUG_KIND_POINTER: - if (! debug_write_type (info, fns, fhandle, type->u.kpointer, - (struct debug_name *) NULL)) - return false; - return (*fns->pointer_type) (fhandle); - case DEBUG_KIND_FUNCTION: - if (! debug_write_type (info, fns, fhandle, - type->u.kfunction->return_type, - (struct debug_name *) NULL)) - return false; - if (type->u.kfunction->arg_types == NULL) - is = -1; - else - { - for (is = 0; type->u.kfunction->arg_types[is] != NULL; is++) - if (! debug_write_type (info, fns, fhandle, - type->u.kfunction->arg_types[is], - (struct debug_name *) NULL)) - return false; - } - return (*fns->function_type) (fhandle, is, - type->u.kfunction->varargs); - case DEBUG_KIND_REFERENCE: - if (! debug_write_type (info, fns, fhandle, type->u.kreference, - (struct debug_name *) NULL)) - return false; - return (*fns->reference_type) (fhandle); - case DEBUG_KIND_RANGE: - if (! debug_write_type (info, fns, fhandle, type->u.krange->type, - (struct debug_name *) NULL)) - return false; - return (*fns->range_type) (fhandle, type->u.krange->lower, - type->u.krange->upper); - case DEBUG_KIND_ARRAY: - if (! debug_write_type (info, fns, fhandle, type->u.karray->element_type, - (struct debug_name *) NULL) - || ! debug_write_type (info, fns, fhandle, - type->u.karray->range_type, - (struct debug_name *) NULL)) - return false; - return (*fns->array_type) (fhandle, type->u.karray->lower, - type->u.karray->upper, - type->u.karray->stringp); - case DEBUG_KIND_SET: - if (! debug_write_type (info, fns, fhandle, type->u.kset->type, - (struct debug_name *) NULL)) - return false; - return (*fns->set_type) (fhandle, type->u.kset->bitstringp); - case DEBUG_KIND_OFFSET: - if (! debug_write_type (info, fns, fhandle, type->u.koffset->base_type, - (struct debug_name *) NULL) - || ! debug_write_type (info, fns, fhandle, - type->u.koffset->target_type, - (struct debug_name *) NULL)) - return false; - return (*fns->offset_type) (fhandle); - case DEBUG_KIND_METHOD: - if (! debug_write_type (info, fns, fhandle, - type->u.kmethod->return_type, - (struct debug_name *) NULL)) - return false; - if (type->u.kmethod->arg_types == NULL) - is = -1; - else - { - for (is = 0; type->u.kmethod->arg_types[is] != NULL; is++) - if (! debug_write_type (info, fns, fhandle, - type->u.kmethod->arg_types[is], - (struct debug_name *) NULL)) - return false; - } - if (type->u.kmethod->domain_type != NULL) - { - if (! debug_write_type (info, fns, fhandle, - type->u.kmethod->domain_type, - (struct debug_name *) NULL)) - return false; - } - return (*fns->method_type) (fhandle, - type->u.kmethod->domain_type != NULL, - is, - type->u.kmethod->varargs); - case DEBUG_KIND_CONST: - if (! debug_write_type (info, fns, fhandle, type->u.kconst, - (struct debug_name *) NULL)) - return false; - return (*fns->const_type) (fhandle); - case DEBUG_KIND_VOLATILE: - if (! debug_write_type (info, fns, fhandle, type->u.kvolatile, - (struct debug_name *) NULL)) - return false; - return (*fns->volatile_type) (fhandle); - case DEBUG_KIND_NAMED: - return debug_write_type (info, fns, fhandle, type->u.knamed->type, - (struct debug_name *) NULL); - case DEBUG_KIND_TAGGED: - return debug_write_type (info, fns, fhandle, type->u.knamed->type, - type->u.knamed->name); - default: - abort (); - return false; - } -} - -/* Write out a class type. */ - -static boolean -debug_write_class_type (info, fns, fhandle, type, tag) - struct debug_handle *info; - const struct debug_write_fns *fns; - PTR fhandle; - struct debug_type *type; - const char *tag; -{ - unsigned int i; - unsigned int id; - struct debug_type *vptrbase; - - if (type->u.kclass == NULL) - { - id = 0; - vptrbase = NULL; - } - else - { - if (type->u.kclass->id <= info->base_id) - { - if (! debug_set_class_id (info, tag, type)) - return false; - } - - if (info->mark == type->u.kclass->mark) - { - /* We are currently outputting this class, or we have - already output it. This can happen when there are - methods for an anonymous class. */ - assert (type->u.kclass->id > info->base_id); - return (*fns->tag_type) (fhandle, tag, type->u.kclass->id, - type->kind); - } - type->u.kclass->mark = info->mark; - id = type->u.kclass->id; - - vptrbase = type->u.kclass->vptrbase; - if (vptrbase != NULL && vptrbase != type) - { - if (! debug_write_type (info, fns, fhandle, vptrbase, - (struct debug_name *) NULL)) - return false; - } - } - - if (! (*fns->start_class_type) (fhandle, tag, id, - type->kind == DEBUG_KIND_CLASS, - type->size, - vptrbase != NULL, - vptrbase == type)) - return false; - - if (type->u.kclass != NULL) - { - if (type->u.kclass->fields != NULL) - { - for (i = 0; type->u.kclass->fields[i] != NULL; i++) - { - struct debug_field *f; - - f = type->u.kclass->fields[i]; - if (! debug_write_type (info, fns, fhandle, f->type, - (struct debug_name *) NULL)) - return false; - if (f->static_member) - { - if (! (*fns->class_static_member) (fhandle, f->name, - f->u.s.physname, - f->visibility)) - return false; - } - else - { - if (! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos, - f->u.f.bitsize, f->visibility)) - return false; - } - } - } - - if (type->u.kclass->baseclasses != NULL) - { - for (i = 0; type->u.kclass->baseclasses[i] != NULL; i++) - { - struct debug_baseclass *b; - - b = type->u.kclass->baseclasses[i]; - if (! debug_write_type (info, fns, fhandle, b->type, - (struct debug_name *) NULL)) - return false; - if (! (*fns->class_baseclass) (fhandle, b->bitpos, b->virtual, - b->visibility)) - return false; - } - } - - if (type->u.kclass->methods != NULL) - { - for (i = 0; type->u.kclass->methods[i] != NULL; i++) - { - struct debug_method *m; - unsigned int j; - - m = type->u.kclass->methods[i]; - if (! (*fns->class_start_method) (fhandle, m->name)) - return false; - for (j = 0; m->variants[j] != NULL; j++) - { - struct debug_method_variant *v; - - v = m->variants[j]; - if (v->context != NULL) - { - if (! debug_write_type (info, fns, fhandle, v->context, - (struct debug_name *) NULL)) - return false; - } - if (! debug_write_type (info, fns, fhandle, v->type, - (struct debug_name *) NULL)) - return false; - if (v->voffset != VOFFSET_STATIC_METHOD) - { - if (! (*fns->class_method_variant) (fhandle, v->physname, - v->visibility, - v->constp, - v->volatilep, - v->voffset, - v->context != NULL)) - return false; - } - else - { - if (! (*fns->class_static_method_variant) (fhandle, - v->physname, - v->visibility, - v->constp, - v->volatilep)) - return false; - } - } - if (! (*fns->class_end_method) (fhandle)) - return false; - } - } - } - - return (*fns->end_class_type) (fhandle); -} - -/* Write out information for a function. */ - -static boolean -debug_write_function (info, fns, fhandle, name, linkage, function) - struct debug_handle *info; - const struct debug_write_fns *fns; - PTR fhandle; - const char *name; - enum debug_object_linkage linkage; - struct debug_function *function; -{ - struct debug_parameter *p; - struct debug_block *b; - - if (! debug_write_linenos (info, fns, fhandle, function->blocks->start)) - return false; - - if (! debug_write_type (info, fns, fhandle, function->return_type, - (struct debug_name *) NULL)) - return false; - - if (! (*fns->start_function) (fhandle, name, - linkage == DEBUG_LINKAGE_GLOBAL)) - return false; - - for (p = function->parameters; p != NULL; p = p->next) - { - if (! debug_write_type (info, fns, fhandle, p->type, - (struct debug_name *) NULL) - || ! (*fns->function_parameter) (fhandle, p->name, p->kind, p->val)) - return false; - } - - for (b = function->blocks; b != NULL; b = b->next) - { - if (! debug_write_block (info, fns, fhandle, b)) - return false; - } - - return (*fns->end_function) (fhandle); -} - -/* Write out information for a block. */ - -static boolean -debug_write_block (info, fns, fhandle, block) - struct debug_handle *info; - const struct debug_write_fns *fns; - PTR fhandle; - struct debug_block *block; -{ - struct debug_name *n; - struct debug_block *b; - - if (! debug_write_linenos (info, fns, fhandle, block->start)) - return false; - - /* I can't see any point to writing out a block with no local - variables, so we don't bother, except for the top level block. */ - if (block->locals != NULL || block->parent == NULL) - { - if (! (*fns->start_block) (fhandle, block->start)) - return false; - } - - if (block->locals != NULL) - { - for (n = block->locals->list; n != NULL; n = n->next) - { - if (! debug_write_name (info, fns, fhandle, n)) - return false; - } - } - - for (b = block->children; b != NULL; b = b->next) - { - if (! debug_write_block (info, fns, fhandle, b)) - return false; - } - - if (! debug_write_linenos (info, fns, fhandle, block->end)) - return false; - - if (block->locals != NULL || block->parent == NULL) - { - if (! (*fns->end_block) (fhandle, block->end)) - return false; - } - - return true; -} - -/* Write out line number information up to ADDRESS. */ - -static boolean -debug_write_linenos (info, fns, fhandle, address) - struct debug_handle *info; - const struct debug_write_fns *fns; - PTR fhandle; - bfd_vma address; -{ - while (info->current_write_lineno != NULL) - { - struct debug_lineno *l; - - l = info->current_write_lineno; - - while (info->current_write_lineno_index < DEBUG_LINENO_COUNT) - { - if (l->linenos[info->current_write_lineno_index] - == (unsigned long) -1) - break; - - if (l->addrs[info->current_write_lineno_index] >= address) - return true; - - if (! (*fns->lineno) (fhandle, l->file->filename, - l->linenos[info->current_write_lineno_index], - l->addrs[info->current_write_lineno_index])) - return false; - - ++info->current_write_lineno_index; - } - - info->current_write_lineno = l->next; - info->current_write_lineno_index = 0; - } - - return true; -} - -/* Get the ID number for a class. If during the same call to - debug_write we find a struct with the same definition with the same - name, we use the same ID. This type of things happens because the - same struct will be defined by multiple compilation units. */ - -static boolean -debug_set_class_id (info, tag, type) - struct debug_handle *info; - const char *tag; - struct debug_type *type; -{ - struct debug_class_type *c; - struct debug_class_id *l; - - assert (type->kind == DEBUG_KIND_STRUCT - || type->kind == DEBUG_KIND_UNION - || type->kind == DEBUG_KIND_CLASS - || type->kind == DEBUG_KIND_UNION_CLASS); - - c = type->u.kclass; - - if (c->id > info->base_id) - return true; - - for (l = info->id_list; l != NULL; l = l->next) - { - if (l->type->kind != type->kind) - continue; - - if (tag == NULL) - { - if (l->tag != NULL) - continue; - } - else - { - if (l->tag == NULL - || l->tag[0] != tag[0] - || strcmp (l->tag, tag) != 0) - continue; - } - - if (debug_type_samep (info, l->type, type)) - { - c->id = l->type->u.kclass->id; - return true; - } - } - - /* There are no identical types. Use a new ID, and add it to the - list. */ - ++info->class_id; - c->id = info->class_id; - - l = (struct debug_class_id *) xmalloc (sizeof *l); - memset (l, 0, sizeof *l); - - l->type = type; - l->tag = tag; - - l->next = info->id_list; - info->id_list = l; - - return true; -} - -/* See if two types are the same. At this point, we don't care about - tags and the like. */ - -static boolean -debug_type_samep (info, t1, t2) - struct debug_handle *info; - struct debug_type *t1; - struct debug_type *t2; -{ - struct debug_type_compare_list *l; - struct debug_type_compare_list top; - boolean ret; - - if (t1 == NULL) - return t2 == NULL; - if (t2 == NULL) - return false; - - while (t1->kind == DEBUG_KIND_INDIRECT) - { - t1 = *t1->u.kindirect->slot; - if (t1 == NULL) - return false; - } - while (t2->kind == DEBUG_KIND_INDIRECT) - { - t2 = *t2->u.kindirect->slot; - if (t2 == NULL) - return false; - } - - if (t1 == t2) - return true; - - /* As a special case, permit a typedef to match a tag, since C++ - debugging output will sometimes add a typedef where C debugging - output will not. */ - if (t1->kind == DEBUG_KIND_NAMED - && t2->kind == DEBUG_KIND_TAGGED) - return debug_type_samep (info, t1->u.knamed->type, t2); - else if (t1->kind == DEBUG_KIND_TAGGED - && t2->kind == DEBUG_KIND_NAMED) - return debug_type_samep (info, t1, t2->u.knamed->type); - - if (t1->kind != t2->kind - || t1->size != t2->size) - return false; - - /* Get rid of the trivial cases first. */ - switch (t1->kind) - { - default: - break; - case DEBUG_KIND_VOID: - case DEBUG_KIND_FLOAT: - case DEBUG_KIND_COMPLEX: - case DEBUG_KIND_BOOL: - return true; - case DEBUG_KIND_INT: - return t1->u.kint == t2->u.kint; - } - - /* We have to avoid an infinite recursion. We do this by keeping a - list of types which we are comparing. We just keep the list on - the stack. If we encounter a pair of types we are currently - comparing, we just assume that they are equal. */ - for (l = info->compare_list; l != NULL; l = l->next) - { - if (l->t1 == t1 && l->t2 == t2) - return true; - } - - top.t1 = t1; - top.t2 = t2; - top.next = info->compare_list; - info->compare_list = ⊤ - - switch (t1->kind) - { - default: - abort (); - ret = false; - break; - - case DEBUG_KIND_STRUCT: - case DEBUG_KIND_UNION: - case DEBUG_KIND_CLASS: - case DEBUG_KIND_UNION_CLASS: - if (t1->u.kclass == NULL) - ret = t2->u.kclass == NULL; - else if (t2->u.kclass == NULL) - ret = false; - else if (t1->u.kclass->id > info->base_id - && t1->u.kclass->id == t2->u.kclass->id) - ret = true; - else - ret = debug_class_type_samep (info, t1, t2); - break; - - case DEBUG_KIND_ENUM: - if (t1->u.kenum == NULL) - ret = t2->u.kenum == NULL; - else if (t2->u.kenum == NULL) - ret = false; - else - { - const char **pn1, **pn2; - bfd_signed_vma *pv1, *pv2; - - pn1 = t1->u.kenum->names; - pn2 = t2->u.kenum->names; - pv1 = t1->u.kenum->values; - pv2 = t2->u.kenum->values; - while (*pn1 != NULL && *pn2 != NULL) - { - if (**pn1 != **pn2 - || *pv1 != *pv2 - || strcmp (*pn1, *pn2) != 0) - break; - ++pn1; - ++pn2; - ++pv1; - ++pv2; - } - ret = *pn1 == NULL && *pn2 == NULL; - } - break; - - case DEBUG_KIND_POINTER: - ret = debug_type_samep (info, t1->u.kpointer, t2->u.kpointer); - break; - - case DEBUG_KIND_FUNCTION: - if (t1->u.kfunction->varargs != t2->u.kfunction->varargs - || ! debug_type_samep (info, t1->u.kfunction->return_type, - t2->u.kfunction->return_type) - || ((t1->u.kfunction->arg_types == NULL) - != (t2->u.kfunction->arg_types == NULL))) - ret = false; - else if (t1->u.kfunction->arg_types == NULL) - ret = true; - else - { - struct debug_type **a1, **a2; - - a1 = t1->u.kfunction->arg_types; - a2 = t2->u.kfunction->arg_types; - while (*a1 != NULL && *a2 != NULL) - if (! debug_type_samep (info, *a1, *a2)) - break; - ret = *a1 == NULL && *a2 == NULL; - } - break; - - case DEBUG_KIND_REFERENCE: - ret = debug_type_samep (info, t1->u.kreference, t2->u.kreference); - break; - - case DEBUG_KIND_RANGE: - ret = (t1->u.krange->lower == t2->u.krange->lower - && t1->u.krange->upper == t2->u.krange->upper - && debug_type_samep (info, t1->u.krange->type, - t2->u.krange->type)); - - case DEBUG_KIND_ARRAY: - ret = (t1->u.karray->lower == t2->u.karray->lower - && t1->u.karray->upper == t2->u.karray->upper - && t1->u.karray->stringp == t2->u.karray->stringp - && debug_type_samep (info, t1->u.karray->element_type, - t2->u.karray->element_type)); - break; - - case DEBUG_KIND_SET: - ret = (t1->u.kset->bitstringp == t2->u.kset->bitstringp - && debug_type_samep (info, t1->u.kset->type, t2->u.kset->type)); - break; - - case DEBUG_KIND_OFFSET: - ret = (debug_type_samep (info, t1->u.koffset->base_type, - t2->u.koffset->base_type) - && debug_type_samep (info, t1->u.koffset->target_type, - t2->u.koffset->target_type)); - break; - - case DEBUG_KIND_METHOD: - if (t1->u.kmethod->varargs != t2->u.kmethod->varargs - || ! debug_type_samep (info, t1->u.kmethod->return_type, - t2->u.kmethod->return_type) - || ! debug_type_samep (info, t1->u.kmethod->domain_type, - t2->u.kmethod->domain_type) - || ((t1->u.kmethod->arg_types == NULL) - != (t2->u.kmethod->arg_types == NULL))) - ret = false; - else if (t1->u.kmethod->arg_types == NULL) - ret = true; - else - { - struct debug_type **a1, **a2; - - a1 = t1->u.kmethod->arg_types; - a2 = t2->u.kmethod->arg_types; - while (*a1 != NULL && *a2 != NULL) - if (! debug_type_samep (info, *a1, *a2)) - break; - ret = *a1 == NULL && *a2 == NULL; - } - break; - - case DEBUG_KIND_CONST: - ret = debug_type_samep (info, t1->u.kconst, t2->u.kconst); - break; - - case DEBUG_KIND_VOLATILE: - ret = debug_type_samep (info, t1->u.kvolatile, t2->u.kvolatile); - break; - - case DEBUG_KIND_NAMED: - case DEBUG_KIND_TAGGED: - ret = (strcmp (t1->u.knamed->name->name, t2->u.knamed->name->name) == 0 - && debug_type_samep (info, t1->u.knamed->type, - t2->u.knamed->type)); - break; - } - - info->compare_list = top.next; - - return ret; -} - -/* See if two classes are the same. This is a subroutine of - debug_type_samep. */ - -static boolean -debug_class_type_samep (info, t1, t2) - struct debug_handle *info; - struct debug_type *t1; - struct debug_type *t2; -{ - struct debug_class_type *c1, *c2; - - c1 = t1->u.kclass; - c2 = t2->u.kclass; - - if ((c1->fields == NULL) != (c2->fields == NULL) - || (c1->baseclasses == NULL) != (c2->baseclasses == NULL) - || (c1->methods == NULL) != (c2->methods == NULL) - || (c1->vptrbase == NULL) != (c2->vptrbase == NULL)) - return false; - - if (c1->fields != NULL) - { - struct debug_field **pf1, **pf2; - - for (pf1 = c1->fields, pf2 = c2->fields; - *pf1 != NULL && *pf2 != NULL; - pf1++, pf2++) - { - struct debug_field *f1, *f2; - - f1 = *pf1; - f2 = *pf2; - if (f1->name[0] != f2->name[0] - || f1->visibility != f2->visibility - || f1->static_member != f2->static_member) - return false; - if (f1->static_member) - { - if (strcmp (f1->u.s.physname, f2->u.s.physname) != 0) - return false; - } - else - { - if (f1->u.f.bitpos != f2->u.f.bitpos - || f1->u.f.bitsize != f2->u.f.bitsize) - return false; - } - /* We do the checks which require function calls last. We - don't require that the types of fields have the same - names, since that sometimes fails in the presence of - typedefs and we really don't care. */ - if (strcmp (f1->name, f2->name) != 0 - || ! debug_type_samep (info, - debug_get_real_type ((PTR) info, - f1->type), - debug_get_real_type ((PTR) info, - f2->type))) - return false; - } - if (*pf1 != NULL || *pf2 != NULL) - return false; - } - - if (c1->vptrbase != NULL) - { - if (! debug_type_samep (info, c1->vptrbase, c2->vptrbase)) - return false; - } - - if (c1->baseclasses != NULL) - { - struct debug_baseclass **pb1, **pb2; - - for (pb1 = c1->baseclasses, pb2 = c2->baseclasses; - *pb1 != NULL && *pb2 != NULL; - ++pb1, ++pb2) - { - struct debug_baseclass *b1, *b2; - - b1 = *pb1; - b2 = *pb2; - if (b1->bitpos != b2->bitpos - || b1->virtual != b2->virtual - || b1->visibility != b2->visibility - || ! debug_type_samep (info, b1->type, b2->type)) - return false; - } - if (*pb1 != NULL || *pb2 != NULL) - return false; - } - - if (c1->methods != NULL) - { - struct debug_method **pm1, **pm2; - - for (pm1 = c1->methods, pm2 = c2->methods; - *pm1 != NULL && *pm2 != NULL; - ++pm1, ++pm2) - { - struct debug_method *m1, *m2; - - m1 = *pm1; - m2 = *pm2; - if (m1->name[0] != m2->name[0] - || strcmp (m1->name, m2->name) != 0 - || (m1->variants == NULL) != (m2->variants == NULL)) - return false; - if (m1->variants == NULL) - { - struct debug_method_variant **pv1, **pv2; - - for (pv1 = m1->variants, pv2 = m2->variants; - *pv1 != NULL && *pv2 != NULL; - ++pv1, ++pv2) - { - struct debug_method_variant *v1, *v2; - - v1 = *pv1; - v2 = *pv2; - if (v1->physname[0] != v2->physname[0] - || v1->visibility != v2->visibility - || v1->constp != v2->constp - || v1->volatilep != v2->volatilep - || v1->voffset != v2->voffset - || (v1->context == NULL) != (v2->context == NULL) - || strcmp (v1->physname, v2->physname) != 0 - || ! debug_type_samep (info, v1->type, v2->type)) - return false; - if (v1->context != NULL) - { - if (! debug_type_samep (info, v1->context, - v2->context)) - return false; - } - } - if (*pv1 != NULL || *pv2 != NULL) - return false; - } - } - if (*pm1 != NULL || *pm2 != NULL) - return false; - } - - return true; -} diff --git a/pstack/debug.h b/pstack/debug.h deleted file mode 100644 index a4d3d8306cd..00000000000 --- a/pstack/debug.h +++ /dev/null @@ -1,798 +0,0 @@ -/* debug.h -- Describe generic debugging information. - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -#ifndef DEBUG_H -#define DEBUG_H - -/* This header file describes a generic debugging information format. - We may eventually have readers which convert different formats into - this generic format, and writers which write it out. The initial - impetus for this was writing a convertor from stabs to HP IEEE-695 - debugging format. */ - -/* Different kinds of types. */ - -enum debug_type_kind -{ - /* Not used. */ - DEBUG_KIND_ILLEGAL, - /* Indirect via a pointer. */ - DEBUG_KIND_INDIRECT, - /* Void. */ - DEBUG_KIND_VOID, - /* Integer. */ - DEBUG_KIND_INT, - /* Floating point. */ - DEBUG_KIND_FLOAT, - /* Complex. */ - DEBUG_KIND_COMPLEX, - /* Boolean. */ - DEBUG_KIND_BOOL, - /* Struct. */ - DEBUG_KIND_STRUCT, - /* Union. */ - DEBUG_KIND_UNION, - /* Class. */ - DEBUG_KIND_CLASS, - /* Union class (can this really happen?). */ - DEBUG_KIND_UNION_CLASS, - /* Enumeration type. */ - DEBUG_KIND_ENUM, - /* Pointer. */ - DEBUG_KIND_POINTER, - /* Function. */ - DEBUG_KIND_FUNCTION, - /* Reference. */ - DEBUG_KIND_REFERENCE, - /* Range. */ - DEBUG_KIND_RANGE, - /* Array. */ - DEBUG_KIND_ARRAY, - /* Set. */ - DEBUG_KIND_SET, - /* Based pointer. */ - DEBUG_KIND_OFFSET, - /* Method. */ - DEBUG_KIND_METHOD, - /* Const qualified type. */ - DEBUG_KIND_CONST, - /* Volatile qualified type. */ - DEBUG_KIND_VOLATILE, - /* Named type. */ - DEBUG_KIND_NAMED, - /* Tagged type. */ - DEBUG_KIND_TAGGED -}; - -/* Different kinds of variables. */ - -enum debug_var_kind -{ - /* Not used. */ - DEBUG_VAR_ILLEGAL, - /* A global variable. */ - DEBUG_GLOBAL, - /* A static variable. */ - DEBUG_STATIC, - /* A local static variable. */ - DEBUG_LOCAL_STATIC, - /* A local variable. */ - DEBUG_LOCAL, - /* A register variable. */ - DEBUG_REGISTER -}; - -/* Different kinds of function parameters. */ - -enum debug_parm_kind -{ - /* Not used. */ - DEBUG_PARM_ILLEGAL, - /* A stack based parameter. */ - DEBUG_PARM_STACK, - /* A register parameter. */ - DEBUG_PARM_REG, - /* A stack based reference parameter. */ - DEBUG_PARM_REFERENCE, - /* A register reference parameter. */ - DEBUG_PARM_REF_REG -}; - -/* Different kinds of visibility. */ - -enum debug_visibility -{ - /* A public field (e.g., a field in a C struct). */ - DEBUG_VISIBILITY_PUBLIC, - /* A protected field. */ - DEBUG_VISIBILITY_PROTECTED, - /* A private field. */ - DEBUG_VISIBILITY_PRIVATE, - /* A field which should be ignored. */ - DEBUG_VISIBILITY_IGNORE -}; - -/* A type. */ - -typedef struct debug_type *debug_type; - -#define DEBUG_TYPE_NULL ((debug_type) NULL) - -/* A field in a struct or union. */ - -typedef struct debug_field *debug_field; - -#define DEBUG_FIELD_NULL ((debug_field) NULL) - -/* A base class for an object. */ - -typedef struct debug_baseclass *debug_baseclass; - -#define DEBUG_BASECLASS_NULL ((debug_baseclass) NULL) - -/* A method of an object. */ - -typedef struct debug_method *debug_method; - -#define DEBUG_METHOD_NULL ((debug_method) NULL) - -/* The arguments to a method function of an object. These indicate - which method to run. */ - -typedef struct debug_method_variant *debug_method_variant; - -#define DEBUG_METHOD_VARIANT_NULL ((debug_method_variant) NULL) - -/* This structure is passed to debug_write. It holds function - pointers that debug_write will call based on the accumulated - debugging information. */ - -struct debug_write_fns -{ - /* This is called at the start of each new compilation unit with the - name of the main file in the new unit. */ - boolean (*start_compilation_unit) PARAMS ((PTR, const char *)); - - /* This is called at the start of each source file within a - compilation unit, before outputting any global information for - that file. The argument is the name of the file. */ - boolean (*start_source) PARAMS ((PTR, const char *)); - - /* Each writer must keep a stack of types. */ - - /* Push an empty type onto the type stack. This type can appear if - there is a reference to a type which is never defined. */ - boolean (*empty_type) PARAMS ((PTR)); - - /* Push a void type onto the type stack. */ - boolean (*void_type) PARAMS ((PTR)); - - /* Push an integer type onto the type stack, given the size and - whether it is unsigned. */ - boolean (*int_type) PARAMS ((PTR, unsigned int, boolean)); - - /* Push a floating type onto the type stack, given the size. */ - boolean (*float_type) PARAMS ((PTR, unsigned int)); - - /* Push a complex type onto the type stack, given the size. */ - boolean (*complex_type) PARAMS ((PTR, unsigned int)); - - /* Push a boolean type onto the type stack, given the size. */ - boolean (*bool_type) PARAMS ((PTR, unsigned int)); - - /* Push an enum type onto the type stack, given the tag, a NULL - terminated array of names and the associated values. If there is - no tag, the tag argument will be NULL. If this is an undefined - enum, the names and values arguments will be NULL. */ - boolean (*enum_type) PARAMS ((PTR, const char *, const char **, - bfd_signed_vma *)); - - /* Pop the top type on the type stack, and push a pointer to that - type onto the type stack. */ - boolean (*pointer_type) PARAMS ((PTR)); - - /* Push a function type onto the type stack. The second argument - indicates the number of argument types that have been pushed onto - the stack. If the number of argument types is passed as -1, then - the argument types of the function are unknown, and no types have - been pushed onto the stack. The third argument is true if the - function takes a variable number of arguments. The return type - of the function is pushed onto the type stack below the argument - types, if any. */ - boolean (*function_type) PARAMS ((PTR, int, boolean)); - - /* Pop the top type on the type stack, and push a reference to that - type onto the type stack. */ - boolean (*reference_type) PARAMS ((PTR)); - - /* Pop the top type on the type stack, and push a range of that type - with the given lower and upper bounds onto the type stack. */ - boolean (*range_type) PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma)); - - /* Push an array type onto the type stack. The top type on the type - stack is the range, and the next type on the type stack is the - element type. These should be popped before the array type is - pushed. The arguments are the lower bound, the upper bound, and - whether the array is a string. */ - boolean (*array_type) PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, - boolean)); - - /* Pop the top type on the type stack, and push a set of that type - onto the type stack. The argument indicates whether this set is - a bitstring. */ - boolean (*set_type) PARAMS ((PTR, boolean)); - - /* Push an offset type onto the type stack. The top type on the - type stack is the target type, and the next type on the type - stack is the base type. These should be popped before the offset - type is pushed. */ - boolean (*offset_type) PARAMS ((PTR)); - - /* Push a method type onto the type stack. If the second argument - is true, the top type on the stack is the class to which the - method belongs; otherwise, the class must be determined by the - class to which the method is attached. The third argument is the - number of argument types; these are pushed onto the type stack in - reverse order (the first type popped is the last argument to the - method). A value of -1 for the third argument means that no - argument information is available. The fourth argument is true - if the function takes a variable number of arguments. The next - type on the type stack below the domain and the argument types is - the return type of the method. All these types must be popped, - and then the method type must be pushed. */ - boolean (*method_type) PARAMS ((PTR, boolean, int, boolean)); - - /* Pop the top type off the type stack, and push a const qualified - version of that type onto the type stack. */ - boolean (*const_type) PARAMS ((PTR)); - - /* Pop the top type off the type stack, and push a volatile - qualified version of that type onto the type stack. */ - boolean (*volatile_type) PARAMS ((PTR)); - - /* Start building a struct. This is followed by calls to the - struct_field function, and finished by a call to the - end_struct_type function. The second argument is the tag; this - will be NULL if there isn't one. If the second argument is NULL, - the third argument is a constant identifying this struct for use - with tag_type. The fourth argument is true for a struct, false - for a union. The fifth argument is the size. If this is an - undefined struct or union, the size will be 0 and struct_field - will not be called before end_struct_type is called. */ - boolean (*start_struct_type) PARAMS ((PTR, const char *, unsigned int, - boolean, unsigned int)); - - /* Add a field to the struct type currently being built. The type - of the field should be popped off the type stack. The arguments - are the name, the bit position, the bit size (may be zero if the - field is not packed), and the visibility. */ - boolean (*struct_field) PARAMS ((PTR, const char *, bfd_vma, bfd_vma, - enum debug_visibility)); - - /* Finish building a struct, and push it onto the type stack. */ - boolean (*end_struct_type) PARAMS ((PTR)); - - /* Start building a class. This is followed by calls to several - functions: struct_field, class_static_member, class_baseclass, - class_start_method, class_method_variant, - class_static_method_variant, and class_end_method. The class is - finished by a call to end_class_type. The first five arguments - are the same as for start_struct_type. The sixth argument is - true if there is a virtual function table; if there is, the - seventh argument is true if the virtual function table can be - found in the type itself, and is false if the type of the object - holding the virtual function table should be popped from the type - stack. */ - boolean (*start_class_type) PARAMS ((PTR, const char *, unsigned int, - boolean, unsigned int, boolean, - boolean)); - - /* Add a static member to the class currently being built. The - arguments are the field name, the physical name, and the - visibility. The type must be popped off the type stack. */ - boolean (*class_static_member) PARAMS ((PTR, const char *, const char *, - enum debug_visibility)); - - /* Add a baseclass to the class currently being built. The type of - the baseclass must be popped off the type stack. The arguments - are the bit position, whether the class is virtual, and the - visibility. */ - boolean (*class_baseclass) PARAMS ((PTR, bfd_vma, boolean, - enum debug_visibility)); - - /* Start adding a method to the class currently being built. This - is followed by calls to class_method_variant and - class_static_method_variant to describe different variants of the - method which take different arguments. The method is finished - with a call to class_end_method. The argument is the method - name. */ - boolean (*class_start_method) PARAMS ((PTR, const char *)); - - /* Describe a variant to the class method currently being built. - The type of the variant must be popped off the type stack. The - second argument is the physical name of the function. The - following arguments are the visibility, whether the variant is - const, whether the variant is volatile, the offset in the virtual - function table, and whether the context is on the type stack - (below the variant type). */ - boolean (*class_method_variant) PARAMS ((PTR, const char *, - enum debug_visibility, - boolean, boolean, - bfd_vma, boolean)); - - /* Describe a static variant to the class method currently being - built. The arguments are the same as for class_method_variant, - except that the last two arguments are omitted. The type of the - variant must be popped off the type stack. */ - boolean (*class_static_method_variant) PARAMS ((PTR, const char *, - enum debug_visibility, - boolean, boolean)); - - /* Finish describing a class method. */ - boolean (*class_end_method) PARAMS ((PTR)); - - /* Finish describing a class, and push it onto the type stack. */ - boolean (*end_class_type) PARAMS ((PTR)); - - /* Push a type on the stack which was given a name by an earlier - call to typdef. */ - boolean (*typedef_type) PARAMS ((PTR, const char *)); - - /* Push a tagged type on the stack which was defined earlier. If - the second argument is not NULL, the type was defined by a call - to tag. If the second argument is NULL, the type was defined by - a call to start_struct_type or start_class_type with a tag of - NULL and the number of the third argument. Either way, the - fourth argument is the tag kind. Note that this may be called - for a struct (class) being defined, in between the call to - start_struct_type (start_class_type) and the call to - end_struct_type (end_class_type). */ - boolean (*tag_type) PARAMS ((PTR, const char *, unsigned int, - enum debug_type_kind)); - - /* Pop the type stack, and typedef it to the given name. */ - boolean (*typdef) PARAMS ((PTR, const char *)); - - /* Pop the type stack, and declare it as a tagged struct or union or - enum or whatever. The tag passed down here is redundant, since - was also passed when enum_type, start_struct_type, or - start_class_type was called. */ - boolean (*tag) PARAMS ((PTR, const char *)); - - /* This is called to record a named integer constant. */ - boolean (*int_constant) PARAMS ((PTR, const char *, bfd_vma)); - - /* This is called to record a named floating point constant. */ - boolean (*float_constant) PARAMS ((PTR, const char *, double)); - - /* This is called to record a typed integer constant. The type is - popped off the type stack. */ - boolean (*typed_constant) PARAMS ((PTR, const char *, bfd_vma)); - - /* This is called to record a variable. The type is popped off the - type stack. */ - boolean (*variable) PARAMS ((PTR, const char *, enum debug_var_kind, - bfd_vma)); - - /* Start writing out a function. The return type must be popped off - the stack. The boolean is true if the function is global. This - is followed by calls to function_parameter, followed by block - information. */ - boolean (*start_function) PARAMS ((PTR, const char *, boolean)); - - /* Record a function parameter for the current function. The type - must be popped off the stack. */ - boolean (*function_parameter) PARAMS ((PTR, const char *, - enum debug_parm_kind, bfd_vma)); - - /* Start writing out a block. There is at least one top level block - per function. Blocks may be nested. The argument is the - starting address of the block. */ - boolean (*start_block) PARAMS ((PTR, bfd_vma)); - - /* Finish writing out a block. The argument is the ending address - of the block. */ - boolean (*end_block) PARAMS ((PTR, bfd_vma)); - - /* Finish writing out a function. */ - boolean (*end_function) PARAMS ((PTR)); - - /* Record line number information for the current compilation unit. */ - boolean (*lineno) PARAMS ((PTR, const char *, unsigned long, bfd_vma)); -}; - -/* Exported functions. */ - -/* The first argument to most of these functions is a handle. This - handle is returned by the debug_init function. The purpose of the - handle is to permit the debugging routines to not use static - variables, and hence to be reentrant. This would be useful for a - program which wanted to handle two executables simultaneously. */ - -/* Return a debugging handle. */ - -extern PTR debug_init PARAMS ((void)); - -/* Set the source filename. This implicitly starts a new compilation - unit. */ - -extern boolean debug_set_filename PARAMS ((PTR, const char *)); - -/* Change source files to the given file name. This is used for - include files in a single compilation unit. */ - -extern boolean debug_start_source PARAMS ((PTR, const char *)); - -/* Record a function definition. This implicitly starts a function - block. The debug_type argument is the type of the return value. - The boolean indicates whether the function is globally visible. - The bfd_vma is the address of the start of the function. Currently - the parameter types are specified by calls to - debug_record_parameter. */ - -extern boolean debug_record_function - PARAMS ((PTR, const char *, debug_type, boolean, bfd_vma)); - -/* Record a parameter for the current function. */ - -extern boolean debug_record_parameter - PARAMS ((PTR, const char *, debug_type, enum debug_parm_kind, bfd_vma)); - -/* End a function definition. The argument is the address where the - function ends. */ - -extern boolean debug_end_function PARAMS ((PTR, bfd_vma)); - -/* Start a block in a function. All local information will be - recorded in this block, until the matching call to debug_end_block. - debug_start_block and debug_end_block may be nested. The argument - is the address at which this block starts. */ - -extern boolean debug_start_block PARAMS ((PTR, bfd_vma)); - -/* Finish a block in a function. This matches the call to - debug_start_block. The argument is the address at which this block - ends. */ - -extern boolean debug_end_block PARAMS ((PTR, bfd_vma)); - -/* Associate a line number in the current source file with a given - address. */ - -extern boolean debug_record_line PARAMS ((PTR, unsigned long, bfd_vma)); - -/* Start a named common block. This is a block of variables that may - move in memory. */ - -extern boolean debug_start_common_block PARAMS ((PTR, const char *)); - -/* End a named common block. */ - -extern boolean debug_end_common_block PARAMS ((PTR, const char *)); - -/* Record a named integer constant. */ - -extern boolean debug_record_int_const PARAMS ((PTR, const char *, bfd_vma)); - -/* Record a named floating point constant. */ - -extern boolean debug_record_float_const PARAMS ((PTR, const char *, double)); - -/* Record a typed constant with an integral value. */ - -extern boolean debug_record_typed_const - PARAMS ((PTR, const char *, debug_type, bfd_vma)); - -/* Record a label. */ - -extern boolean debug_record_label - PARAMS ((PTR, const char *, debug_type, bfd_vma)); - -/* Record a variable. */ - -extern boolean debug_record_variable - PARAMS ((PTR, const char *, debug_type, enum debug_var_kind, bfd_vma)); - -/* Make an indirect type. The first argument is a pointer to the - location where the real type will be placed. The second argument - is the type tag, if there is one; this may be NULL; the only - purpose of this argument is so that debug_get_type_name can return - something useful. This function may be used when a type is - referenced before it is defined. */ - -extern debug_type debug_make_indirect_type - PARAMS ((PTR, debug_type *, const char *)); - -/* Make a void type. */ - -extern debug_type debug_make_void_type PARAMS ((PTR)); - -/* Make an integer type of a given size. The boolean argument is true - if the integer is unsigned. */ - -extern debug_type debug_make_int_type PARAMS ((PTR, unsigned int, boolean)); - -/* Make a floating point type of a given size. FIXME: On some - platforms, like an Alpha, you probably need to be able to specify - the format. */ - -extern debug_type debug_make_float_type PARAMS ((PTR, unsigned int)); - -/* Make a boolean type of a given size. */ - -extern debug_type debug_make_bool_type PARAMS ((PTR, unsigned int)); - -/* Make a complex type of a given size. */ - -extern debug_type debug_make_complex_type PARAMS ((PTR, unsigned int)); - -/* Make a structure type. The second argument is true for a struct, - false for a union. The third argument is the size of the struct. - The fourth argument is a NULL terminated array of fields. */ - -extern debug_type debug_make_struct_type - PARAMS ((PTR, boolean, bfd_vma, debug_field *)); - -/* Make an object type. The first three arguments after the handle - are the same as for debug_make_struct_type. The next arguments are - a NULL terminated array of base classes, a NULL terminated array of - methods, the type of the object holding the virtual function table - if it is not this object, and a boolean which is true if this - object has its own virtual function table. */ - -extern debug_type debug_make_object_type - PARAMS ((PTR, boolean, bfd_vma, debug_field *, debug_baseclass *, - debug_method *, debug_type, boolean)); - -/* Make an enumeration type. The arguments are a null terminated - array of strings, and an array of corresponding values. */ - -extern debug_type debug_make_enum_type - PARAMS ((PTR, const char **, bfd_signed_vma *)); - -/* Make a pointer to a given type. */ - -extern debug_type debug_make_pointer_type - PARAMS ((PTR, debug_type)); - -/* Make a function type. The second argument is the return type. The - third argument is a NULL terminated array of argument types. The - fourth argument is true if the function takes a variable number of - arguments. If the third argument is NULL, then the argument types - are unknown. */ - -extern debug_type debug_make_function_type - PARAMS ((PTR, debug_type, debug_type *, boolean)); - -/* Make a reference to a given type. */ - -extern debug_type debug_make_reference_type PARAMS ((PTR, debug_type)); - -/* Make a range of a given type from a lower to an upper bound. */ - -extern debug_type debug_make_range_type - PARAMS ((PTR, debug_type, bfd_signed_vma, bfd_signed_vma)); - -/* Make an array type. The second argument is the type of an element - of the array. The third argument is the type of a range of the - array. The fourth and fifth argument are the lower and upper - bounds, respectively (if the bounds are not known, lower should be - 0 and upper should be -1). The sixth argument is true if this - array is actually a string, as in C. */ - -extern debug_type debug_make_array_type - PARAMS ((PTR, debug_type, debug_type, bfd_signed_vma, bfd_signed_vma, - boolean)); - -/* Make a set of a given type. For example, a Pascal set type. The - boolean argument is true if this set is actually a bitstring, as in - CHILL. */ - -extern debug_type debug_make_set_type PARAMS ((PTR, debug_type, boolean)); - -/* Make a type for a pointer which is relative to an object. The - second argument is the type of the object to which the pointer is - relative. The third argument is the type that the pointer points - to. */ - -extern debug_type debug_make_offset_type - PARAMS ((PTR, debug_type, debug_type)); - -/* Make a type for a method function. The second argument is the - return type. The third argument is the domain. The fourth - argument is a NULL terminated array of argument types. The fifth - argument is true if the function takes a variable number of - arguments, in which case the array of argument types indicates the - types of the first arguments. The domain and the argument array - may be NULL, in which case this is a stub method and that - information is not available. Stabs debugging uses this, and gets - the argument types from the mangled name. */ - -extern debug_type debug_make_method_type - PARAMS ((PTR, debug_type, debug_type, debug_type *, boolean)); - -/* Make a const qualified version of a given type. */ - -extern debug_type debug_make_const_type PARAMS ((PTR, debug_type)); - -/* Make a volatile qualified version of a given type. */ - -extern debug_type debug_make_volatile_type PARAMS ((PTR, debug_type)); - -/* Make an undefined tagged type. For example, a struct which has - been mentioned, but not defined. */ - -extern debug_type debug_make_undefined_tagged_type - PARAMS ((PTR, const char *, enum debug_type_kind)); - -/* Make a base class for an object. The second argument is the base - class type. The third argument is the bit position of this base - class in the object. The fourth argument is whether this is a - virtual class. The fifth argument is the visibility of the base - class. */ - -extern debug_baseclass debug_make_baseclass - PARAMS ((PTR, debug_type, bfd_vma, boolean, enum debug_visibility)); - -/* Make a field for a struct. The second argument is the name. The - third argument is the type of the field. The fourth argument is - the bit position of the field. The fifth argument is the size of - the field (it may be zero). The sixth argument is the visibility - of the field. */ - -extern debug_field debug_make_field - PARAMS ((PTR, const char *, debug_type, bfd_vma, bfd_vma, - enum debug_visibility)); - -/* Make a static member of an object. The second argument is the - name. The third argument is the type of the member. The fourth - argument is the physical name of the member (i.e., the name as a - global variable). The fifth argument is the visibility of the - member. */ - -extern debug_field debug_make_static_member - PARAMS ((PTR, const char *, debug_type, const char *, - enum debug_visibility)); - -/* Make a method. The second argument is the name, and the third - argument is a NULL terminated array of method variants. Each - method variant is a method with this name but with different - argument types. */ - -extern debug_method debug_make_method - PARAMS ((PTR, const char *, debug_method_variant *)); - -/* Make a method variant. The second argument is the physical name of - the function. The third argument is the type of the function, - probably constructed by debug_make_method_type. The fourth - argument is the visibility. The fifth argument is whether this is - a const function. The sixth argument is whether this is a volatile - function. The seventh argument is the index in the virtual - function table, if any. The eighth argument is the virtual - function context. */ - -extern debug_method_variant debug_make_method_variant - PARAMS ((PTR, const char *, debug_type, enum debug_visibility, boolean, - boolean, bfd_vma, debug_type)); - -/* Make a static method argument. The arguments are the same as for - debug_make_method_variant, except that the last two are omitted - since a static method can not also be virtual. */ - -extern debug_method_variant debug_make_static_method_variant - PARAMS ((PTR, const char *, debug_type, enum debug_visibility, boolean, - boolean)); - -/* Name a type. This returns a new type with an attached name. */ - -extern debug_type debug_name_type PARAMS ((PTR, const char *, debug_type)); - -/* Give a tag to a type, such as a struct or union. This returns a - new type with an attached tag. */ - -extern debug_type debug_tag_type PARAMS ((PTR, const char *, debug_type)); - -/* Record the size of a given type. */ - -extern boolean debug_record_type_size PARAMS ((PTR, debug_type, unsigned int)); - -/* Find a named type. */ - -extern debug_type debug_find_named_type PARAMS ((PTR, const char *)); - -/* Find a tagged type. */ - -extern debug_type debug_find_tagged_type - PARAMS ((PTR, const char *, enum debug_type_kind)); - -/* Get the kind of a type. */ - -extern enum debug_type_kind debug_get_type_kind PARAMS ((PTR, debug_type)); - -/* Get the name of a type. */ - -extern const char *debug_get_type_name PARAMS ((PTR, debug_type)); - -/* Get the size of a type. */ - -extern bfd_vma debug_get_type_size PARAMS ((PTR, debug_type)); - -/* Get the return type of a function or method type. */ - -extern debug_type debug_get_return_type PARAMS ((PTR, debug_type)); - -/* Get the NULL terminated array of parameter types for a function or - method type (actually, parameter types are not currently stored for - function types). This may be used to determine whether a method - type is a stub method or not. The last argument points to a - boolean which is set to true if the function takes a variable - number of arguments. */ - -extern const debug_type *debug_get_parameter_types PARAMS ((PTR, - debug_type, - boolean *)); - -/* Get the target type of a pointer or reference or const or volatile - type. */ - -extern debug_type debug_get_target_type PARAMS ((PTR, debug_type)); - -/* Get the NULL terminated array of fields for a struct, union, or - class. */ - -extern const debug_field *debug_get_fields PARAMS ((PTR, debug_type)); - -/* Get the type of a field. */ - -extern debug_type debug_get_field_type PARAMS ((PTR, debug_field)); - -/* Get the name of a field. */ - -extern const char *debug_get_field_name PARAMS ((PTR, debug_field)); - -/* Get the bit position of a field within the containing structure. - If the field is a static member, this will return (bfd_vma) -1. */ - -extern bfd_vma debug_get_field_bitpos PARAMS ((PTR, debug_field)); - -/* Get the bit size of a field. If the field is a static member, this - will return (bfd_vma) -1. */ - -extern bfd_vma debug_get_field_bitsize PARAMS ((PTR, debug_field)); - -/* Get the visibility of a field. */ - -extern enum debug_visibility debug_get_field_visibility - PARAMS ((PTR, debug_field)); - -/* Get the physical name of a field, if it is a static member. If the - field is not a static member, this will return NULL. */ - -extern const char *debug_get_field_physname PARAMS ((PTR, debug_field)); - -/* Write out the recorded debugging information. This takes a set of - function pointers which are called to do the actual writing. The - first PTR is the debugging handle. The second PTR is a handle - which is passed to the functions. */ - -extern boolean debug_write PARAMS ((PTR, const struct debug_write_fns *, PTR)); - -#endif /* DEBUG_H */ diff --git a/pstack/demangle.h b/pstack/demangle.h deleted file mode 100644 index a961436ca77..00000000000 --- a/pstack/demangle.h +++ /dev/null @@ -1,90 +0,0 @@ -/* Defs for interface to demanglers. - Copyright 1992, 1995, 1996 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - - -#if !defined (DEMANGLE_H) -#define DEMANGLE_H - -#ifdef IN_GCC -#include "gansidecl.h" -#define PARAMS(ARGS) PROTO(ARGS) -#else /* ! IN_GCC */ -#include -#endif /* IN_GCC */ - -/* Options passed to cplus_demangle (in 2nd parameter). */ - -#define DMGL_NO_OPTS 0 /* For readability... */ -#define DMGL_PARAMS (1 << 0) /* Include function args */ -#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ -#define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */ - -#define DMGL_AUTO (1 << 8) -#define DMGL_GNU (1 << 9) -#define DMGL_LUCID (1 << 10) -#define DMGL_ARM (1 << 11) -/* If none of these are set, use 'current_demangling_style' as the default. */ -#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM) - -/* Enumeration of possible demangling styles. - - Lucid and ARM styles are still kept logically distinct, even though - they now both behave identically. The resulting style is actual the - union of both. I.E. either style recognizes both "__pt__" and "__rf__" - for operator "->", even though the first is lucid style and the second - is ARM style. (FIXME?) */ - -extern enum demangling_styles -{ - unknown_demangling = 0, - auto_demangling = DMGL_AUTO, - gnu_demangling = DMGL_GNU, - lucid_demangling = DMGL_LUCID, - arm_demangling = DMGL_ARM -} current_demangling_style; - -/* Define string names for the various demangling styles. */ - -#define AUTO_DEMANGLING_STYLE_STRING "auto" -#define GNU_DEMANGLING_STYLE_STRING "gnu" -#define LUCID_DEMANGLING_STYLE_STRING "lucid" -#define ARM_DEMANGLING_STYLE_STRING "arm" - -/* Some macros to test what demangling style is active. */ - -#define CURRENT_DEMANGLING_STYLE current_demangling_style -#define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO) -#define GNU_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU) -#define LUCID_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_LUCID) -#define ARM_DEMANGLING (CURRENT_DEMANGLING_STYLE & DMGL_ARM) - -extern char * -cplus_demangle PARAMS ((const char *mangled, int options)); - -extern int -cplus_demangle_opname PARAMS ((const char *opname, char *result, int options)); - -extern const char * -cplus_mangle_opname PARAMS ((const char *opname, int options)); - -/* Note: This sets global state. FIXME if you care about multi-threading. */ - -extern void -set_cplus_marker_for_demangling PARAMS ((int ch)); - -#endif /* DEMANGLE_H */ diff --git a/pstack/filemode.c b/pstack/filemode.c deleted file mode 100644 index 58b52ba7489..00000000000 --- a/pstack/filemode.c +++ /dev/null @@ -1,266 +0,0 @@ -/* filemode.c -- make a string describing file modes - Copyright (C) 1985, 90, 91, 94, 95, 1997 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -#include "bfd.h" -#include "bucomm.h" - -static char ftypelet PARAMS ((unsigned long)); -static void setst PARAMS ((unsigned long, char *)); - -/* filemodestring - fill in string STR with an ls-style ASCII - representation of the st_mode field of file stats block STATP. - 10 characters are stored in STR; no terminating null is added. - The characters stored in STR are: - - 0 File type. 'd' for directory, 'c' for character - special, 'b' for block special, 'm' for multiplex, - 'l' for symbolic link, 's' for socket, 'p' for fifo, - '-' for any other file type - - 1 'r' if the owner may read, '-' otherwise. - - 2 'w' if the owner may write, '-' otherwise. - - 3 'x' if the owner may execute, 's' if the file is - set-user-id, '-' otherwise. - 'S' if the file is set-user-id, but the execute - bit isn't set. - - 4 'r' if group members may read, '-' otherwise. - - 5 'w' if group members may write, '-' otherwise. - - 6 'x' if group members may execute, 's' if the file is - set-group-id, '-' otherwise. - 'S' if it is set-group-id but not executable. - - 7 'r' if any user may read, '-' otherwise. - - 8 'w' if any user may write, '-' otherwise. - - 9 'x' if any user may execute, 't' if the file is "sticky" - (will be retained in swap space after execution), '-' - otherwise. - 'T' if the file is sticky but not executable. */ - -#if 0 - -/* This is not used; only mode_string is used. */ - -void -filemodestring (statp, str) - struct stat *statp; - char *str; -{ - mode_string ((unsigned long) statp->st_mode, str); -} - -#endif - -/* Get definitions for the file permission bits. */ - -#ifndef S_IRWXU -#define S_IRWXU 0700 -#endif -#ifndef S_IRUSR -#define S_IRUSR 0400 -#endif -#ifndef S_IWUSR -#define S_IWUSR 0200 -#endif -#ifndef S_IXUSR -#define S_IXUSR 0100 -#endif - -#ifndef S_IRWXG -#define S_IRWXG 0070 -#endif -#ifndef S_IRGRP -#define S_IRGRP 0040 -#endif -#ifndef S_IWGRP -#define S_IWGRP 0020 -#endif -#ifndef S_IXGRP -#define S_IXGRP 0010 -#endif - -#ifndef S_IRWXO -#define S_IRWXO 0007 -#endif -#ifndef S_IROTH -#define S_IROTH 0004 -#endif -#ifndef S_IWOTH -#define S_IWOTH 0002 -#endif -#ifndef S_IXOTH -#define S_IXOTH 0001 -#endif - -/* Like filemodestring, but only the relevant part of the `struct stat' - is given as an argument. */ - -void -mode_string (mode, str) - unsigned long mode; - char *str; -{ - str[0] = ftypelet ((unsigned long) mode); - str[1] = (mode & S_IRUSR) != 0 ? 'r' : '-'; - str[2] = (mode & S_IWUSR) != 0 ? 'w' : '-'; - str[3] = (mode & S_IXUSR) != 0 ? 'x' : '-'; - str[4] = (mode & S_IRGRP) != 0 ? 'r' : '-'; - str[5] = (mode & S_IWGRP) != 0 ? 'w' : '-'; - str[6] = (mode & S_IXGRP) != 0 ? 'x' : '-'; - str[7] = (mode & S_IROTH) != 0 ? 'r' : '-'; - str[8] = (mode & S_IWOTH) != 0 ? 'w' : '-'; - str[9] = (mode & S_IXOTH) != 0 ? 'x' : '-'; - setst ((unsigned long) mode, str); -} - -/* Return a character indicating the type of file described by - file mode BITS: - 'd' for directories - 'b' for block special files - 'c' for character special files - 'm' for multiplexor files - 'l' for symbolic links - 's' for sockets - 'p' for fifos - '-' for any other file type. */ - -#ifndef S_ISDIR -#ifdef S_IFDIR -#define S_ISDIR(i) (((i) & S_IFMT) == S_IFDIR) -#else /* ! defined (S_IFDIR) */ -#define S_ISDIR(i) (((i) & 0170000) == 040000) -#endif /* ! defined (S_IFDIR) */ -#endif /* ! defined (S_ISDIR) */ - -#ifndef S_ISBLK -#ifdef S_IFBLK -#define S_ISBLK(i) (((i) & S_IFMT) == S_IFBLK) -#else /* ! defined (S_IFBLK) */ -#define S_ISBLK(i) 0 -#endif /* ! defined (S_IFBLK) */ -#endif /* ! defined (S_ISBLK) */ - -#ifndef S_ISCHR -#ifdef S_IFCHR -#define S_ISCHR(i) (((i) & S_IFMT) == S_IFCHR) -#else /* ! defined (S_IFCHR) */ -#define S_ISCHR(i) 0 -#endif /* ! defined (S_IFCHR) */ -#endif /* ! defined (S_ISCHR) */ - -#ifndef S_ISFIFO -#ifdef S_IFIFO -#define S_ISFIFO(i) (((i) & S_IFMT) == S_IFIFO) -#else /* ! defined (S_IFIFO) */ -#define S_ISFIFO(i) 0 -#endif /* ! defined (S_IFIFO) */ -#endif /* ! defined (S_ISFIFO) */ - -#ifndef S_ISSOCK -#ifdef S_IFSOCK -#define S_ISSOCK(i) (((i) & S_IFMT) == S_IFSOCK) -#else /* ! defined (S_IFSOCK) */ -#define S_ISSOCK(i) 0 -#endif /* ! defined (S_IFSOCK) */ -#endif /* ! defined (S_ISSOCK) */ - -#ifndef S_ISLNK -#ifdef S_IFLNK -#define S_ISLNK(i) (((i) & S_IFMT) == S_IFLNK) -#else /* ! defined (S_IFLNK) */ -#define S_ISLNK(i) 0 -#endif /* ! defined (S_IFLNK) */ -#endif /* ! defined (S_ISLNK) */ - -static char -ftypelet (bits) - unsigned long bits; -{ - if (S_ISDIR (bits)) - return 'd'; - if (S_ISLNK (bits)) - return 'l'; - if (S_ISBLK (bits)) - return 'b'; - if (S_ISCHR (bits)) - return 'c'; - if (S_ISSOCK (bits)) - return 's'; - if (S_ISFIFO (bits)) - return 'p'; - -#ifdef S_IFMT -#ifdef S_IFMPC - if ((bits & S_IFMT) == S_IFMPC - || (bits & S_IFMT) == S_IFMPB) - return 'm'; -#endif -#ifdef S_IFNWK - if ((bits & S_IFMT) == S_IFNWK) - return 'n'; -#endif -#endif - - return '-'; -} - -/* Set the 's' and 't' flags in file attributes string CHARS, - according to the file mode BITS. */ - -static void -setst (bits, chars) - unsigned long bits; - char *chars; -{ -#ifdef S_ISUID - if (bits & S_ISUID) - { - if (chars[3] != 'x') - /* Set-uid, but not executable by owner. */ - chars[3] = 'S'; - else - chars[3] = 's'; - } -#endif -#ifdef S_ISGID - if (bits & S_ISGID) - { - if (chars[6] != 'x') - /* Set-gid, but not executable by group. */ - chars[6] = 'S'; - else - chars[6] = 's'; - } -#endif -#ifdef S_ISVTX - if (bits & S_ISVTX) - { - if (chars[9] != 'x') - /* Sticky, but not executable by others. */ - chars[9] = 'T'; - else - chars[9] = 't'; - } -#endif -} diff --git a/pstack/ieee.c b/pstack/ieee.c deleted file mode 100644 index 8084656a5ef..00000000000 --- a/pstack/ieee.c +++ /dev/null @@ -1,7602 +0,0 @@ -/* ieee.c -- Read and write IEEE-695 debugging information. - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -/* This file reads and writes IEEE-695 debugging information. */ - -#include -#include - -#include -#include "ieee.h" -#include "bucomm.h" -#include -#include "debug.h" -#include "budbg.h" - -/* This structure holds an entry on the block stack. */ - -struct ieee_block -{ - /* The kind of block. */ - int kind; - /* The source file name, for a BB5 block. */ - const char *filename; - /* The index of the function type, for a BB4 or BB6 block. */ - unsigned int fnindx; - /* True if this function is being skipped. */ - boolean skip; -}; - -/* This structure is the block stack. */ - -#define BLOCKSTACK_SIZE (16) - -struct ieee_blockstack -{ - /* The stack pointer. */ - struct ieee_block *bsp; - /* The stack. */ - struct ieee_block stack[BLOCKSTACK_SIZE]; -}; - -/* This structure holds information for a variable. */ - -struct ieee_var -{ - /* Start of name. */ - const char *name; - /* Length of name. */ - unsigned long namlen; - /* Type. */ - debug_type type; - /* Slot if we make an indirect type. */ - debug_type *pslot; - /* Kind of variable or function. */ - enum - { - IEEE_UNKNOWN, - IEEE_EXTERNAL, - IEEE_GLOBAL, - IEEE_STATIC, - IEEE_LOCAL, - IEEE_FUNCTION - } kind; -}; - -/* This structure holds all the variables. */ - -struct ieee_vars -{ - /* Number of slots allocated. */ - unsigned int alloc; - /* Variables. */ - struct ieee_var *vars; -}; - -/* This structure holds information for a type. We need this because - we don't want to represent bitfields as real types. */ - -struct ieee_type -{ - /* Type. */ - debug_type type; - /* Slot if this is type is referenced before it is defined. */ - debug_type *pslot; - /* Slots for arguments if we make indirect types for them. */ - debug_type *arg_slots; - /* If this is a bitfield, this is the size in bits. If this is not - a bitfield, this is zero. */ - unsigned long bitsize; -}; - -/* This structure holds all the type information. */ - -struct ieee_types -{ - /* Number of slots allocated. */ - unsigned int alloc; - /* Types. */ - struct ieee_type *types; - /* Builtin types. */ -#define BUILTIN_TYPE_COUNT (60) - debug_type builtins[BUILTIN_TYPE_COUNT]; -}; - -/* This structure holds a linked last of structs with their tag names, - so that we can convert them to C++ classes if necessary. */ - -struct ieee_tag -{ - /* Next tag. */ - struct ieee_tag *next; - /* This tag name. */ - const char *name; - /* The type of the tag. */ - debug_type type; - /* The tagged type is an indirect type pointing at this slot. */ - debug_type slot; - /* This is an array of slots used when a field type is converted - into a indirect type, in case it needs to be later converted into - a reference type. */ - debug_type *fslots; -}; - -/* This structure holds the information we pass around to the parsing - functions. */ - -struct ieee_info -{ - /* The debugging handle. */ - PTR dhandle; - /* The BFD. */ - bfd *abfd; - /* The start of the bytes to be parsed. */ - const bfd_byte *bytes; - /* The end of the bytes to be parsed. */ - const bfd_byte *pend; - /* The block stack. */ - struct ieee_blockstack blockstack; - /* Whether we have seen a BB1 or BB2. */ - boolean saw_filename; - /* The variables. */ - struct ieee_vars vars; - /* The global variables, after a global typedef block. */ - struct ieee_vars *global_vars; - /* The types. */ - struct ieee_types types; - /* The global types, after a global typedef block. */ - struct ieee_types *global_types; - /* The list of tagged structs. */ - struct ieee_tag *tags; -}; - -/* Basic builtin types, not including the pointers. */ - -enum builtin_types -{ - builtin_unknown = 0, - builtin_void = 1, - builtin_signed_char = 2, - builtin_unsigned_char = 3, - builtin_signed_short_int = 4, - builtin_unsigned_short_int = 5, - builtin_signed_long = 6, - builtin_unsigned_long = 7, - builtin_signed_long_long = 8, - builtin_unsigned_long_long = 9, - builtin_float = 10, - builtin_double = 11, - builtin_long_double = 12, - builtin_long_long_double = 13, - builtin_quoted_string = 14, - builtin_instruction_address = 15, - builtin_int = 16, - builtin_unsigned = 17, - builtin_unsigned_int = 18, - builtin_char = 19, - builtin_long = 20, - builtin_short = 21, - builtin_unsigned_short = 22, - builtin_short_int = 23, - builtin_signed_short = 24, - builtin_bcd_float = 25 -}; - -/* These are the values found in the derivation flags of a 'b' - component record of a 'T' type extension record in a C++ pmisc - record. These are bitmasks. */ - -/* Set for a private base class, clear for a public base class. - Protected base classes are not supported. */ -#define BASEFLAGS_PRIVATE (0x1) -/* Set for a virtual base class. */ -#define BASEFLAGS_VIRTUAL (0x2) -/* Set for a friend class, clear for a base class. */ -#define BASEFLAGS_FRIEND (0x10) - -/* These are the values found in the specs flags of a 'd', 'm', or 'v' - component record of a 'T' type extension record in a C++ pmisc - record. The same flags are used for a 'M' record in a C++ pmisc - record. */ - -/* The lower two bits hold visibility information. */ -#define CXXFLAGS_VISIBILITY (0x3) -/* This value in the lower two bits indicates a public member. */ -#define CXXFLAGS_VISIBILITY_PUBLIC (0x0) -/* This value in the lower two bits indicates a private member. */ -#define CXXFLAGS_VISIBILITY_PRIVATE (0x1) -/* This value in the lower two bits indicates a protected member. */ -#define CXXFLAGS_VISIBILITY_PROTECTED (0x2) -/* Set for a static member. */ -#define CXXFLAGS_STATIC (0x4) -/* Set for a virtual override. */ -#define CXXFLAGS_OVERRIDE (0x8) -/* Set for a friend function. */ -#define CXXFLAGS_FRIEND (0x10) -/* Set for a const function. */ -#define CXXFLAGS_CONST (0x20) -/* Set for a volatile function. */ -#define CXXFLAGS_VOLATILE (0x40) -/* Set for an overloaded function. */ -#define CXXFLAGS_OVERLOADED (0x80) -/* Set for an operator function. */ -#define CXXFLAGS_OPERATOR (0x100) -/* Set for a constructor or destructor. */ -#define CXXFLAGS_CTORDTOR (0x400) -/* Set for a constructor. */ -#define CXXFLAGS_CTOR (0x200) -/* Set for an inline function. */ -#define CXXFLAGS_INLINE (0x800) - -/* Local functions. */ - -static void ieee_error - PARAMS ((struct ieee_info *, const bfd_byte *, const char *)); -static void ieee_eof PARAMS ((struct ieee_info *)); -static char *savestring PARAMS ((const char *, unsigned long)); -static boolean ieee_read_number - PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *)); -static boolean ieee_read_optional_number - PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *, boolean *)); -static boolean ieee_read_id - PARAMS ((struct ieee_info *, const bfd_byte **, const char **, - unsigned long *)); -static boolean ieee_read_optional_id - PARAMS ((struct ieee_info *, const bfd_byte **, const char **, - unsigned long *, boolean *)); -static boolean ieee_read_expression - PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *)); -static debug_type ieee_builtin_type - PARAMS ((struct ieee_info *, const bfd_byte *, unsigned int)); -static boolean ieee_alloc_type - PARAMS ((struct ieee_info *, unsigned int, boolean)); -static boolean ieee_read_type_index - PARAMS ((struct ieee_info *, const bfd_byte **, debug_type *)); -static int ieee_regno_to_genreg PARAMS ((bfd *, int)); -static int ieee_genreg_to_regno PARAMS ((bfd *, int)); -static boolean parse_ieee_bb PARAMS ((struct ieee_info *, const bfd_byte **)); -static boolean parse_ieee_be PARAMS ((struct ieee_info *, const bfd_byte **)); -static boolean parse_ieee_nn PARAMS ((struct ieee_info *, const bfd_byte **)); -static boolean parse_ieee_ty PARAMS ((struct ieee_info *, const bfd_byte **)); -static boolean parse_ieee_atn PARAMS ((struct ieee_info *, const bfd_byte **)); -static boolean ieee_read_cxx_misc - PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long)); -static boolean ieee_read_cxx_class - PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long)); -static boolean ieee_read_cxx_defaults - PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long)); -static boolean ieee_read_reference - PARAMS ((struct ieee_info *, const bfd_byte **)); -static boolean ieee_require_asn - PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *)); -static boolean ieee_require_atn65 - PARAMS ((struct ieee_info *, const bfd_byte **, const char **, - unsigned long *)); - -/* Report an error in the IEEE debugging information. */ - -static void -ieee_error (info, p, s) - struct ieee_info *info; - const bfd_byte *p; - const char *s; -{ - if (p != NULL) - fprintf (stderr, "%s: 0x%lx: %s (0x%x)\n", bfd_get_filename (info->abfd), - (unsigned long) (p - info->bytes), s, *p); - else - fprintf (stderr, "%s: %s\n", bfd_get_filename (info->abfd), s); -} - -/* Report an unexpected EOF in the IEEE debugging information. */ - -static void -ieee_eof (info) - struct ieee_info *info; -{ - ieee_error (info, (const bfd_byte *) NULL, - "unexpected end of debugging information"); -} - -/* Save a string in memory. */ - -static char * -savestring (start, len) - const char *start; - unsigned long len; -{ - char *ret; - - ret = (char *) xmalloc (len + 1); - memcpy (ret, start, len); - ret[len] = '\0'; - return ret; -} - -/* Read a number which must be present in an IEEE file. */ - -static boolean -ieee_read_number (info, pp, pv) - struct ieee_info *info; - const bfd_byte **pp; - bfd_vma *pv; -{ - return ieee_read_optional_number (info, pp, pv, (boolean *) NULL); -} - -/* Read a number in an IEEE file. If ppresent is not NULL, the number - need not be there. */ - -static boolean -ieee_read_optional_number (info, pp, pv, ppresent) - struct ieee_info *info; - const bfd_byte **pp; - bfd_vma *pv; - boolean *ppresent; -{ - ieee_record_enum_type b; - - if (*pp >= info->pend) - { - if (ppresent != NULL) - { - *ppresent = false; - return true; - } - ieee_eof (info); - return false; - } - - b = (ieee_record_enum_type) **pp; - ++*pp; - - if (b <= ieee_number_end_enum) - { - *pv = (bfd_vma) b; - if (ppresent != NULL) - *ppresent = true; - return true; - } - - if (b >= ieee_number_repeat_start_enum && b <= ieee_number_repeat_end_enum) - { - unsigned int i; - - i = (int) b - (int) ieee_number_repeat_start_enum; - if (*pp + i - 1 >= info->pend) - { - ieee_eof (info); - return false; - } - - *pv = 0; - for (; i > 0; i--) - { - *pv <<= 8; - *pv += **pp; - ++*pp; - } - - if (ppresent != NULL) - *ppresent = true; - - return true; - } - - if (ppresent != NULL) - { - --*pp; - *ppresent = false; - return true; - } - - ieee_error (info, *pp - 1, "invalid number"); - return false; -} - -/* Read a required string from an IEEE file. */ - -static boolean -ieee_read_id (info, pp, pname, pnamlen) - struct ieee_info *info; - const bfd_byte **pp; - const char **pname; - unsigned long *pnamlen; -{ - return ieee_read_optional_id (info, pp, pname, pnamlen, (boolean *) NULL); -} - -/* Read a string from an IEEE file. If ppresent is not NULL, the - string is optional. */ - -static boolean -ieee_read_optional_id (info, pp, pname, pnamlen, ppresent) - struct ieee_info *info; - const bfd_byte **pp; - const char **pname; - unsigned long *pnamlen; - boolean *ppresent; -{ - bfd_byte b; - unsigned long len; - - if (*pp >= info->pend) - { - ieee_eof (info); - return false; - } - - b = **pp; - ++*pp; - - if (b <= 0x7f) - len = b; - else if ((ieee_record_enum_type) b == ieee_extension_length_1_enum) - { - len = **pp; - ++*pp; - } - else if ((ieee_record_enum_type) b == ieee_extension_length_2_enum) - { - len = (**pp << 8) + (*pp)[1]; - *pp += 2; - } - else - { - if (ppresent != NULL) - { - --*pp; - *ppresent = false; - return true; - } - ieee_error (info, *pp - 1, "invalid string length"); - return false; - } - - if ((unsigned long) (info->pend - *pp) < len) - { - ieee_eof (info); - return false; - } - - *pname = (const char *) *pp; - *pnamlen = len; - *pp += len; - - if (ppresent != NULL) - *ppresent = true; - - return true; -} - -/* Read an expression from an IEEE file. Since this code is only used - to parse debugging information, I haven't bothered to write a full - blown IEEE expression parser. I've only thrown in the things I've - seen in debugging information. This can be easily extended if - necessary. */ - -static boolean -ieee_read_expression (info, pp, pv) - struct ieee_info *info; - const bfd_byte **pp; - bfd_vma *pv; -{ - const bfd_byte *expr_start; -#define EXPR_STACK_SIZE (10) - bfd_vma expr_stack[EXPR_STACK_SIZE]; - bfd_vma *esp; - - expr_start = *pp; - - esp = expr_stack; - - while (1) - { - const bfd_byte *start; - bfd_vma val; - boolean present; - ieee_record_enum_type c; - - start = *pp; - - if (! ieee_read_optional_number (info, pp, &val, &present)) - return false; - - if (present) - { - if (esp - expr_stack >= EXPR_STACK_SIZE) - { - ieee_error (info, start, "expression stack overflow"); - return false; - } - *esp++ = val; - continue; - } - - c = (ieee_record_enum_type) **pp; - - if (c >= ieee_module_beginning_enum) - break; - - ++*pp; - - if (c == ieee_comma) - break; - - switch (c) - { - default: - ieee_error (info, start, "unsupported IEEE expression operator"); - break; - - case ieee_variable_R_enum: - { - bfd_vma indx; - asection *s; - - if (! ieee_read_number (info, pp, &indx)) - return false; - for (s = info->abfd->sections; s != NULL; s = s->next) - if ((bfd_vma) s->target_index == indx) - break; - if (s == NULL) - { - ieee_error (info, start, "unknown section"); - return false; - } - - if (esp - expr_stack >= EXPR_STACK_SIZE) - { - ieee_error (info, start, "expression stack overflow"); - return false; - } - - *esp++ = bfd_get_section_vma (info->abfd, s); - } - break; - - case ieee_function_plus_enum: - case ieee_function_minus_enum: - { - bfd_vma v1, v2; - - if (esp - expr_stack < 2) - { - ieee_error (info, start, "expression stack underflow"); - return false; - } - - v1 = *--esp; - v2 = *--esp; - *esp++ = v1 + v2; - } - break; - } - } - - if (esp - 1 != expr_stack) - { - ieee_error (info, expr_start, "expression stack mismatch"); - return false; - } - - *pv = *--esp; - - return true; -} - -/* Return an IEEE builtin type. */ - -static debug_type -ieee_builtin_type (info, p, indx) - struct ieee_info *info; - const bfd_byte *p; - unsigned int indx; -{ - PTR dhandle; - debug_type type; - const char *name; - - if (indx < BUILTIN_TYPE_COUNT - && info->types.builtins[indx] != DEBUG_TYPE_NULL) - return info->types.builtins[indx]; - - dhandle = info->dhandle; - - if (indx >= 32 && indx < 64) - { - type = debug_make_pointer_type (dhandle, - ieee_builtin_type (info, p, indx - 32)); - assert (indx < BUILTIN_TYPE_COUNT); - info->types.builtins[indx] = type; - return type; - } - - switch ((enum builtin_types) indx) - { - default: - ieee_error (info, p, "unknown builtin type"); - return NULL; - - case builtin_unknown: - type = debug_make_void_type (dhandle); - name = NULL; - break; - - case builtin_void: - type = debug_make_void_type (dhandle); - name = "void"; - break; - - case builtin_signed_char: - type = debug_make_int_type (dhandle, 1, false); - name = "signed char"; - break; - - case builtin_unsigned_char: - type = debug_make_int_type (dhandle, 1, true); - name = "unsigned char"; - break; - - case builtin_signed_short_int: - type = debug_make_int_type (dhandle, 2, false); - name = "signed short int"; - break; - - case builtin_unsigned_short_int: - type = debug_make_int_type (dhandle, 2, true); - name = "unsigned short int"; - break; - - case builtin_signed_long: - type = debug_make_int_type (dhandle, 4, false); - name = "signed long"; - break; - - case builtin_unsigned_long: - type = debug_make_int_type (dhandle, 4, true); - name = "unsigned long"; - break; - - case builtin_signed_long_long: - type = debug_make_int_type (dhandle, 8, false); - name = "signed long long"; - break; - - case builtin_unsigned_long_long: - type = debug_make_int_type (dhandle, 8, true); - name = "unsigned long long"; - break; - - case builtin_float: - type = debug_make_float_type (dhandle, 4); - name = "float"; - break; - - case builtin_double: - type = debug_make_float_type (dhandle, 8); - name = "double"; - break; - - case builtin_long_double: - /* FIXME: The size for this type should depend upon the - processor. */ - type = debug_make_float_type (dhandle, 12); - name = "long double"; - break; - - case builtin_long_long_double: - type = debug_make_float_type (dhandle, 16); - name = "long long double"; - break; - - case builtin_quoted_string: - type = debug_make_array_type (dhandle, - ieee_builtin_type (info, p, - ((unsigned int) - builtin_char)), - ieee_builtin_type (info, p, - ((unsigned int) - builtin_int)), - 0, -1, true); - name = "QUOTED STRING"; - break; - - case builtin_instruction_address: - /* FIXME: This should be a code address. */ - type = debug_make_int_type (dhandle, 4, true); - name = "instruction address"; - break; - - case builtin_int: - /* FIXME: The size for this type should depend upon the - processor. */ - type = debug_make_int_type (dhandle, 4, false); - name = "int"; - break; - - case builtin_unsigned: - /* FIXME: The size for this type should depend upon the - processor. */ - type = debug_make_int_type (dhandle, 4, true); - name = "unsigned"; - break; - - case builtin_unsigned_int: - /* FIXME: The size for this type should depend upon the - processor. */ - type = debug_make_int_type (dhandle, 4, true); - name = "unsigned int"; - break; - - case builtin_char: - type = debug_make_int_type (dhandle, 1, false); - name = "char"; - break; - - case builtin_long: - type = debug_make_int_type (dhandle, 4, false); - name = "long"; - break; - - case builtin_short: - type = debug_make_int_type (dhandle, 2, false); - name = "short"; - break; - - case builtin_unsigned_short: - type = debug_make_int_type (dhandle, 2, true); - name = "unsigned short"; - break; - - case builtin_short_int: - type = debug_make_int_type (dhandle, 2, false); - name = "short int"; - break; - - case builtin_signed_short: - type = debug_make_int_type (dhandle, 2, false); - name = "signed short"; - break; - - case builtin_bcd_float: - ieee_error (info, p, "BCD float type not supported"); - return DEBUG_TYPE_NULL; - } - - if (name != NULL) - type = debug_name_type (dhandle, name, type); - - assert (indx < BUILTIN_TYPE_COUNT); - - info->types.builtins[indx] = type; - - return type; -} - -/* Allocate more space in the type table. If ref is true, this is a - reference to the type; if it is not already defined, we should set - up an indirect type. */ - -static boolean -ieee_alloc_type (info, indx, ref) - struct ieee_info *info; - unsigned int indx; - boolean ref; -{ - unsigned int nalloc; - register struct ieee_type *t; - struct ieee_type *tend; - - if (indx >= info->types.alloc) - { - nalloc = info->types.alloc; - if (nalloc == 0) - nalloc = 4; - while (indx >= nalloc) - nalloc *= 2; - - info->types.types = ((struct ieee_type *) - xrealloc (info->types.types, - nalloc * sizeof *info->types.types)); - - memset (info->types.types + info->types.alloc, 0, - (nalloc - info->types.alloc) * sizeof *info->types.types); - - tend = info->types.types + nalloc; - for (t = info->types.types + info->types.alloc; t < tend; t++) - t->type = DEBUG_TYPE_NULL; - - info->types.alloc = nalloc; - } - - if (ref) - { - t = info->types.types + indx; - if (t->type == NULL) - { - t->pslot = (debug_type *) xmalloc (sizeof *t->pslot); - *t->pslot = DEBUG_TYPE_NULL; - t->type = debug_make_indirect_type (info->dhandle, t->pslot, - (const char *) NULL); - if (t->type == NULL) - return false; - } - } - - return true; -} - -/* Read a type index and return the corresponding type. */ - -static boolean -ieee_read_type_index (info, pp, ptype) - struct ieee_info *info; - const bfd_byte **pp; - debug_type *ptype; -{ - const bfd_byte *start; - bfd_vma indx; - - start = *pp; - - if (! ieee_read_number (info, pp, &indx)) - return false; - - if (indx < 256) - { - *ptype = ieee_builtin_type (info, start, indx); - if (*ptype == NULL) - return false; - return true; - } - - indx -= 256; - if (! ieee_alloc_type (info, indx, true)) - return false; - - *ptype = info->types.types[indx].type; - - return true; -} - -/* Parse IEEE debugging information for a file. This is passed the - bytes which compose the Debug Information Part of an IEEE file. */ - -boolean -parse_ieee (dhandle, abfd, bytes, len) - PTR dhandle; - bfd *abfd; - const bfd_byte *bytes; - bfd_size_type len; -{ - struct ieee_info info; - unsigned int i; - const bfd_byte *p, *pend; - - info.dhandle = dhandle; - info.abfd = abfd; - info.bytes = bytes; - info.pend = bytes + len; - info.blockstack.bsp = info.blockstack.stack; - info.saw_filename = false; - info.vars.alloc = 0; - info.vars.vars = NULL; - info.types.alloc = 0; - info.types.types = NULL; - info.tags = NULL; - for (i = 0; i < BUILTIN_TYPE_COUNT; i++) - info.types.builtins[i] = DEBUG_TYPE_NULL; - - p = bytes; - pend = info.pend; - while (p < pend) - { - const bfd_byte *record_start; - ieee_record_enum_type c; - - record_start = p; - - c = (ieee_record_enum_type) *p++; - - if (c == ieee_at_record_enum) - c = (ieee_record_enum_type) (((unsigned int) c << 8) | *p++); - - if (c <= ieee_number_repeat_end_enum) - { - ieee_error (&info, record_start, "unexpected number"); - return false; - } - - switch (c) - { - default: - ieee_error (&info, record_start, "unexpected record type"); - return false; - - case ieee_bb_record_enum: - if (! parse_ieee_bb (&info, &p)) - return false; - break; - - case ieee_be_record_enum: - if (! parse_ieee_be (&info, &p)) - return false; - break; - - case ieee_nn_record: - if (! parse_ieee_nn (&info, &p)) - return false; - break; - - case ieee_ty_record_enum: - if (! parse_ieee_ty (&info, &p)) - return false; - break; - - case ieee_atn_record_enum: - if (! parse_ieee_atn (&info, &p)) - return false; - break; - } - } - - if (info.blockstack.bsp != info.blockstack.stack) - { - ieee_error (&info, (const bfd_byte *) NULL, - "blocks left on stack at end"); - return false; - } - - return true; -} - -/* Handle an IEEE BB record. */ - -static boolean -parse_ieee_bb (info, pp) - struct ieee_info *info; - const bfd_byte **pp; -{ - const bfd_byte *block_start; - bfd_byte b; - bfd_vma size; - const char *name; - unsigned long namlen; - char *namcopy = NULL; - unsigned int fnindx; - boolean skip; - - block_start = *pp; - - b = **pp; - ++*pp; - - if (! ieee_read_number (info, pp, &size) - || ! ieee_read_id (info, pp, &name, &namlen)) - return false; - - fnindx = (unsigned int) -1; - skip = false; - - switch (b) - { - case 1: - /* BB1: Type definitions local to a module. */ - namcopy = savestring (name, namlen); - if (namcopy == NULL) - return false; - if (! debug_set_filename (info->dhandle, namcopy)) - return false; - info->saw_filename = true; - - /* Discard any variables or types we may have seen before. */ - if (info->vars.vars != NULL) - free (info->vars.vars); - info->vars.vars = NULL; - info->vars.alloc = 0; - if (info->types.types != NULL) - free (info->types.types); - info->types.types = NULL; - info->types.alloc = 0; - - /* Initialize the types to the global types. */ - if (info->global_types != NULL) - { - info->types.alloc = info->global_types->alloc; - info->types.types = ((struct ieee_type *) - xmalloc (info->types.alloc - * sizeof (*info->types.types))); - memcpy (info->types.types, info->global_types->types, - info->types.alloc * sizeof (*info->types.types)); - } - - break; - - case 2: - /* BB2: Global type definitions. The name is supposed to be - empty, but we don't check. */ - if (! debug_set_filename (info->dhandle, "*global*")) - return false; - info->saw_filename = true; - break; - - case 3: - /* BB3: High level module block begin. We don't have to do - anything here. The name is supposed to be the same as for - the BB1, but we don't check. */ - break; - - case 4: - /* BB4: Global function. */ - { - bfd_vma stackspace, typindx, offset; - debug_type return_type; - - if (! ieee_read_number (info, pp, &stackspace) - || ! ieee_read_number (info, pp, &typindx) - || ! ieee_read_expression (info, pp, &offset)) - return false; - - /* We have no way to record the stack space. FIXME. */ - - if (typindx < 256) - { - return_type = ieee_builtin_type (info, block_start, typindx); - if (return_type == DEBUG_TYPE_NULL) - return false; - } - else - { - typindx -= 256; - if (! ieee_alloc_type (info, typindx, true)) - return false; - fnindx = typindx; - return_type = info->types.types[typindx].type; - if (debug_get_type_kind (info->dhandle, return_type) - == DEBUG_KIND_FUNCTION) - return_type = debug_get_return_type (info->dhandle, - return_type); - } - - namcopy = savestring (name, namlen); - if (namcopy == NULL) - return false; - if (! debug_record_function (info->dhandle, namcopy, return_type, - true, offset)) - return false; - } - break; - - case 5: - /* BB5: File name for source line numbers. */ - { - unsigned int i; - - /* We ignore the date and time. FIXME. */ - for (i = 0; i < 6; i++) - { - bfd_vma ignore; - boolean present; - - if (! ieee_read_optional_number (info, pp, &ignore, &present)) - return false; - if (! present) - break; - } - - namcopy = savestring (name, namlen); - if (namcopy == NULL) - return false; - if (! debug_start_source (info->dhandle, namcopy)) - return false; - } - break; - - case 6: - /* BB6: Local function or block. */ - { - bfd_vma stackspace, typindx, offset; - - if (! ieee_read_number (info, pp, &stackspace) - || ! ieee_read_number (info, pp, &typindx) - || ! ieee_read_expression (info, pp, &offset)) - return false; - - /* We have no way to record the stack space. FIXME. */ - - if (namlen == 0) - { - if (! debug_start_block (info->dhandle, offset)) - return false; - /* Change b to indicate that this is a block - rather than a function. */ - b = 0x86; - } - else - { - /* The MRI C++ compiler will output a fake function named - __XRYCPP to hold C++ debugging information. We skip - that function. This is not crucial, but it makes - converting from IEEE to other debug formats work - better. */ - if (strncmp (name, "__XRYCPP", namlen) == 0) - skip = true; - else - { - debug_type return_type; - - if (typindx < 256) - { - return_type = ieee_builtin_type (info, block_start, - typindx); - if (return_type == NULL) - return false; - } - else - { - typindx -= 256; - if (! ieee_alloc_type (info, typindx, true)) - return false; - fnindx = typindx; - return_type = info->types.types[typindx].type; - if (debug_get_type_kind (info->dhandle, return_type) - == DEBUG_KIND_FUNCTION) - return_type = debug_get_return_type (info->dhandle, - return_type); - } - - namcopy = savestring (name, namlen); - if (namcopy == NULL) - return false; - if (! debug_record_function (info->dhandle, namcopy, - return_type, false, offset)) - return false; - } - } - } - break; - - case 10: - /* BB10: Assembler module scope. In the normal case, we - completely ignore all this information. FIXME. */ - { - const char *inam, *vstr; - unsigned long inamlen, vstrlen; - bfd_vma tool_type; - boolean present; - unsigned int i; - - if (! info->saw_filename) - { - namcopy = savestring (name, namlen); - if (namcopy == NULL) - return false; - if (! debug_set_filename (info->dhandle, namcopy)) - return false; - info->saw_filename = true; - } - - if (! ieee_read_id (info, pp, &inam, &inamlen) - || ! ieee_read_number (info, pp, &tool_type) - || ! ieee_read_optional_id (info, pp, &vstr, &vstrlen, &present)) - return false; - for (i = 0; i < 6; i++) - { - bfd_vma ignore; - - if (! ieee_read_optional_number (info, pp, &ignore, &present)) - return false; - if (! present) - break; - } - } - break; - - case 11: - /* BB11: Module section. We completely ignore all this - information. FIXME. */ - { - bfd_vma sectype, secindx, offset, map; - boolean present; - - if (! ieee_read_number (info, pp, §ype) - || ! ieee_read_number (info, pp, &secindx) - || ! ieee_read_expression (info, pp, &offset) - || ! ieee_read_optional_number (info, pp, &map, &present)) - return false; - } - break; - - default: - ieee_error (info, block_start, "unknown BB type"); - return false; - } - - - /* Push this block on the block stack. */ - - if (info->blockstack.bsp >= info->blockstack.stack + BLOCKSTACK_SIZE) - { - ieee_error (info, (const bfd_byte *) NULL, "stack overflow"); - return false; - } - - info->blockstack.bsp->kind = b; - if (b == 5) - info->blockstack.bsp->filename = namcopy; - info->blockstack.bsp->fnindx = fnindx; - info->blockstack.bsp->skip = skip; - ++info->blockstack.bsp; - - return true; -} - -/* Handle an IEEE BE record. */ - -static boolean -parse_ieee_be (info, pp) - struct ieee_info *info; - const bfd_byte **pp; -{ - bfd_vma offset; - - if (info->blockstack.bsp <= info->blockstack.stack) - { - ieee_error (info, *pp, "stack underflow"); - return false; - } - --info->blockstack.bsp; - - switch (info->blockstack.bsp->kind) - { - case 2: - /* When we end the global typedefs block, we copy out the the - contents of info->vars. This is because the variable indices - may be reused in the local blocks. However, we need to - preserve them so that we can locate a function returning a - reference variable whose type is named in the global typedef - block. */ - info->global_vars = ((struct ieee_vars *) - xmalloc (sizeof *info->global_vars)); - info->global_vars->alloc = info->vars.alloc; - info->global_vars->vars = ((struct ieee_var *) - xmalloc (info->vars.alloc - * sizeof (*info->vars.vars))); - memcpy (info->global_vars->vars, info->vars.vars, - info->vars.alloc * sizeof (*info->vars.vars)); - - /* We also copy out the non builtin parts of info->types, since - the types are discarded when we start a new block. */ - info->global_types = ((struct ieee_types *) - xmalloc (sizeof *info->global_types)); - info->global_types->alloc = info->types.alloc; - info->global_types->types = ((struct ieee_type *) - xmalloc (info->types.alloc - * sizeof (*info->types.types))); - memcpy (info->global_types->types, info->types.types, - info->types.alloc * sizeof (*info->types.types)); - memset (info->global_types->builtins, 0, - sizeof (info->global_types->builtins)); - - break; - - case 4: - case 6: - if (! ieee_read_expression (info, pp, &offset)) - return false; - if (! info->blockstack.bsp->skip) - { - if (! debug_end_function (info->dhandle, offset + 1)) - return false; - } - break; - - case 0x86: - /* This is BE6 when BB6 started a block rather than a local - function. */ - if (! ieee_read_expression (info, pp, &offset)) - return false; - if (! debug_end_block (info->dhandle, offset + 1)) - return false; - break; - - case 5: - /* When we end a BB5, we look up the stack for the last BB5, if - there is one, so that we can call debug_start_source. */ - if (info->blockstack.bsp > info->blockstack.stack) - { - struct ieee_block *bl; - - bl = info->blockstack.bsp; - do - { - --bl; - if (bl->kind == 5) - { - if (! debug_start_source (info->dhandle, bl->filename)) - return false; - break; - } - } - while (bl != info->blockstack.stack); - } - break; - - case 11: - if (! ieee_read_expression (info, pp, &offset)) - return false; - /* We just ignore the module size. FIXME. */ - break; - - default: - /* Other block types do not have any trailing information. */ - break; - } - - return true; -} - -/* Parse an NN record. */ - -static boolean -parse_ieee_nn (info, pp) - struct ieee_info *info; - const bfd_byte **pp; -{ - const bfd_byte *nn_start; - bfd_vma varindx; - const char *name; - unsigned long namlen; - - nn_start = *pp; - - if (! ieee_read_number (info, pp, &varindx) - || ! ieee_read_id (info, pp, &name, &namlen)) - return false; - - if (varindx < 32) - { - ieee_error (info, nn_start, "illegal variable index"); - return false; - } - varindx -= 32; - - if (varindx >= info->vars.alloc) - { - unsigned int alloc; - - alloc = info->vars.alloc; - if (alloc == 0) - alloc = 4; - while (varindx >= alloc) - alloc *= 2; - info->vars.vars = ((struct ieee_var *) - xrealloc (info->vars.vars, - alloc * sizeof *info->vars.vars)); - memset (info->vars.vars + info->vars.alloc, 0, - (alloc - info->vars.alloc) * sizeof *info->vars.vars); - info->vars.alloc = alloc; - } - - info->vars.vars[varindx].name = name; - info->vars.vars[varindx].namlen = namlen; - - return true; -} - -/* Parse a TY record. */ - -static boolean -parse_ieee_ty (info, pp) - struct ieee_info *info; - const bfd_byte **pp; -{ - const bfd_byte *ty_start, *ty_var_start, *ty_code_start; - bfd_vma typeindx, varindx, tc; - PTR dhandle; - boolean tag, typdef; - debug_type *arg_slots; - unsigned long type_bitsize; - debug_type type; - - ty_start = *pp; - - if (! ieee_read_number (info, pp, &typeindx)) - return false; - - if (typeindx < 256) - { - ieee_error (info, ty_start, "illegal type index"); - return false; - } - - typeindx -= 256; - if (! ieee_alloc_type (info, typeindx, false)) - return false; - - if (**pp != 0xce) - { - ieee_error (info, *pp, "unknown TY code"); - return false; - } - ++*pp; - - ty_var_start = *pp; - - if (! ieee_read_number (info, pp, &varindx)) - return false; - - if (varindx < 32) - { - ieee_error (info, ty_var_start, "illegal variable index"); - return false; - } - varindx -= 32; - - if (varindx >= info->vars.alloc || info->vars.vars[varindx].name == NULL) - { - ieee_error (info, ty_var_start, "undefined variable in TY"); - return false; - } - - ty_code_start = *pp; - - if (! ieee_read_number (info, pp, &tc)) - return false; - - dhandle = info->dhandle; - - tag = false; - typdef = false; - arg_slots = NULL; - type_bitsize = 0; - switch (tc) - { - default: - ieee_error (info, ty_code_start, "unknown TY code"); - return false; - - case '!': - /* Unknown type, with size. We treat it as int. FIXME. */ - { - bfd_vma size; - - if (! ieee_read_number (info, pp, &size)) - return false; - type = debug_make_int_type (dhandle, size, false); - } - break; - - case 'A': /* Array. */ - case 'a': /* FORTRAN array in column/row order. FIXME: Not - distinguished from normal array. */ - { - debug_type ele_type; - bfd_vma lower, upper; - - if (! ieee_read_type_index (info, pp, &ele_type) - || ! ieee_read_number (info, pp, &lower) - || ! ieee_read_number (info, pp, &upper)) - return false; - type = debug_make_array_type (dhandle, ele_type, - ieee_builtin_type (info, ty_code_start, - ((unsigned int) - builtin_int)), - (bfd_signed_vma) lower, - (bfd_signed_vma) upper, - false); - } - break; - - case 'E': - /* Simple enumeration. */ - { - bfd_vma size; - unsigned int alloc; - const char **names; - unsigned int c; - bfd_signed_vma *vals; - unsigned int i; - - if (! ieee_read_number (info, pp, &size)) - return false; - /* FIXME: we ignore the enumeration size. */ - - alloc = 10; - names = (const char **) xmalloc (alloc * sizeof *names); - memset (names, 0, alloc * sizeof *names); - c = 0; - while (1) - { - const char *name; - unsigned long namlen; - boolean present; - - if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return false; - if (! present) - break; - - if (c + 1 >= alloc) - { - alloc += 10; - names = ((const char **) - xrealloc (names, alloc * sizeof *names)); - } - - names[c] = savestring (name, namlen); - if (names[c] == NULL) - return false; - ++c; - } - - names[c] = NULL; - - vals = (bfd_signed_vma *) xmalloc (c * sizeof *vals); - for (i = 0; i < c; i++) - vals[i] = i; - - type = debug_make_enum_type (dhandle, names, vals); - tag = true; - } - break; - - case 'G': - /* Struct with bit fields. */ - { - bfd_vma size; - unsigned int alloc; - debug_field *fields; - unsigned int c; - - if (! ieee_read_number (info, pp, &size)) - return false; - - alloc = 10; - fields = (debug_field *) xmalloc (alloc * sizeof *fields); - c = 0; - while (1) - { - const char *name; - unsigned long namlen; - boolean present; - debug_type ftype; - bfd_vma bitpos, bitsize; - - if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return false; - if (! present) - break; - if (! ieee_read_type_index (info, pp, &ftype) - || ! ieee_read_number (info, pp, &bitpos) - || ! ieee_read_number (info, pp, &bitsize)) - return false; - - if (c + 1 >= alloc) - { - alloc += 10; - fields = ((debug_field *) - xrealloc (fields, alloc * sizeof *fields)); - } - - fields[c] = debug_make_field (dhandle, savestring (name, namlen), - ftype, bitpos, bitsize, - DEBUG_VISIBILITY_PUBLIC); - if (fields[c] == NULL) - return false; - ++c; - } - - fields[c] = NULL; - - type = debug_make_struct_type (dhandle, true, size, fields); - tag = true; - } - break; - - case 'N': - /* Enumeration. */ - { - unsigned int alloc; - const char **names; - bfd_signed_vma *vals; - unsigned int c; - - alloc = 10; - names = (const char **) xmalloc (alloc * sizeof *names); - vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *names); - c = 0; - while (1) - { - const char *name; - unsigned long namlen; - boolean present; - bfd_vma val; - - if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return false; - if (! present) - break; - if (! ieee_read_number (info, pp, &val)) - return false; - - /* If the length of the name is zero, then the value is - actually the size of the enum. We ignore this - information. FIXME. */ - if (namlen == 0) - continue; - - if (c + 1 >= alloc) - { - alloc += 10; - names = ((const char **) - xrealloc (names, alloc * sizeof *names)); - vals = ((bfd_signed_vma *) - xrealloc (vals, alloc * sizeof *vals)); - } - - names[c] = savestring (name, namlen); - if (names[c] == NULL) - return false; - vals[c] = (bfd_signed_vma) val; - ++c; - } - - names[c] = NULL; - - type = debug_make_enum_type (dhandle, names, vals); - tag = true; - } - break; - - case 'O': /* Small pointer. We don't distinguish small and large - pointers. FIXME. */ - case 'P': /* Large pointer. */ - { - debug_type t; - - if (! ieee_read_type_index (info, pp, &t)) - return false; - type = debug_make_pointer_type (dhandle, t); - } - break; - - case 'R': - /* Range. */ - { - bfd_vma low, high, signedp, size; - - if (! ieee_read_number (info, pp, &low) - || ! ieee_read_number (info, pp, &high) - || ! ieee_read_number (info, pp, &signedp) - || ! ieee_read_number (info, pp, &size)) - return false; - - type = debug_make_range_type (dhandle, - debug_make_int_type (dhandle, size, - ! signedp), - (bfd_signed_vma) low, - (bfd_signed_vma) high); - } - break; - - case 'S': /* Struct. */ - case 'U': /* Union. */ - { - bfd_vma size; - unsigned int alloc; - debug_field *fields; - unsigned int c; - - if (! ieee_read_number (info, pp, &size)) - return false; - - alloc = 10; - fields = (debug_field *) xmalloc (alloc * sizeof *fields); - c = 0; - while (1) - { - const char *name; - unsigned long namlen; - boolean present; - bfd_vma tindx; - bfd_vma offset; - debug_type ftype; - bfd_vma bitsize; - - if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return false; - if (! present) - break; - if (! ieee_read_number (info, pp, &tindx) - || ! ieee_read_number (info, pp, &offset)) - return false; - - if (tindx < 256) - { - ftype = ieee_builtin_type (info, ty_code_start, tindx); - bitsize = 0; - offset *= 8; - } - else - { - struct ieee_type *t; - - tindx -= 256; - if (! ieee_alloc_type (info, tindx, true)) - return false; - t = info->types.types + tindx; - ftype = t->type; - bitsize = t->bitsize; - if (bitsize == 0) - offset *= 8; - } - - if (c + 1 >= alloc) - { - alloc += 10; - fields = ((debug_field *) - xrealloc (fields, alloc * sizeof *fields)); - } - - fields[c] = debug_make_field (dhandle, savestring (name, namlen), - ftype, offset, bitsize, - DEBUG_VISIBILITY_PUBLIC); - if (fields[c] == NULL) - return false; - ++c; - } - - fields[c] = NULL; - - type = debug_make_struct_type (dhandle, tc == 'S', size, fields); - tag = true; - } - break; - - case 'T': - /* Typedef. */ - if (! ieee_read_type_index (info, pp, &type)) - return false; - typdef = true; - break; - - case 'X': - /* Procedure. FIXME: This is an extern declaration, which we - have no way of representing. */ - { - bfd_vma attr; - debug_type rtype; - bfd_vma nargs; - boolean present; - struct ieee_var *pv; - - /* FIXME: We ignore the attribute and the argument names. */ - - if (! ieee_read_number (info, pp, &attr) - || ! ieee_read_type_index (info, pp, &rtype) - || ! ieee_read_number (info, pp, &nargs)) - return false; - do - { - const char *name; - unsigned long namlen; - - if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return false; - } - while (present); - - pv = info->vars.vars + varindx; - pv->kind = IEEE_EXTERNAL; - if (pv->namlen > 0 - && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER) - { - /* Set up the return type as an indirect type pointing to - the variable slot, so that we can change it to a - reference later if appropriate. */ - pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot); - *pv->pslot = rtype; - rtype = debug_make_indirect_type (dhandle, pv->pslot, - (const char *) NULL); - } - - type = debug_make_function_type (dhandle, rtype, (debug_type *) NULL, - false); - } - break; - - case 'V': - /* Void. This is not documented, but the MRI compiler emits it. */ - type = debug_make_void_type (dhandle); - break; - - case 'Z': - /* Array with 0 lower bound. */ - { - debug_type etype; - bfd_vma high; - - if (! ieee_read_type_index (info, pp, &etype) - || ! ieee_read_number (info, pp, &high)) - return false; - - type = debug_make_array_type (dhandle, etype, - ieee_builtin_type (info, ty_code_start, - ((unsigned int) - builtin_int)), - 0, (bfd_signed_vma) high, false); - } - break; - - case 'c': /* Complex. */ - case 'd': /* Double complex. */ - { - const char *name; - unsigned long namlen; - - /* FIXME: I don't know what the name means. */ - - if (! ieee_read_id (info, pp, &name, &namlen)) - return false; - - type = debug_make_complex_type (dhandle, tc == 'c' ? 4 : 8); - } - break; - - case 'f': - /* Pascal file name. FIXME. */ - ieee_error (info, ty_code_start, "Pascal file name not supported"); - return false; - - case 'g': - /* Bitfield type. */ - { - bfd_vma signedp, bitsize, dummy; - const bfd_byte *hold; - boolean present; - - if (! ieee_read_number (info, pp, &signedp) - || ! ieee_read_number (info, pp, &bitsize)) - return false; - - /* I think the documentation says that there is a type index, - but some actual files do not have one. */ - hold = *pp; - if (! ieee_read_optional_number (info, pp, &dummy, &present)) - return false; - if (! present) - { - /* FIXME: This is just a guess. */ - type = debug_make_int_type (dhandle, 4, - signedp ? false : true); - } - else - { - *pp = hold; - if (! ieee_read_type_index (info, pp, &type)) - return false; - } - type_bitsize = bitsize; - } - break; - - case 'n': - /* Qualifier. */ - { - bfd_vma kind; - debug_type t; - - if (! ieee_read_number (info, pp, &kind) - || ! ieee_read_type_index (info, pp, &t)) - return false; - - switch (kind) - { - default: - ieee_error (info, ty_start, "unsupported qualifer"); - return false; - - case 1: - type = debug_make_const_type (dhandle, t); - break; - - case 2: - type = debug_make_volatile_type (dhandle, t); - break; - } - } - break; - - case 's': - /* Set. */ - { - bfd_vma size; - debug_type etype; - - if (! ieee_read_number (info, pp, &size) - || ! ieee_read_type_index (info, pp, &etype)) - return false; - - /* FIXME: We ignore the size. */ - - type = debug_make_set_type (dhandle, etype, false); - } - break; - - case 'x': - /* Procedure with compiler dependencies. */ - { - struct ieee_var *pv; - bfd_vma attr, frame_type, push_mask, nargs, level, father; - debug_type rtype; - debug_type *arg_types; - boolean varargs; - boolean present; - - /* FIXME: We ignore some of this information. */ - - pv = info->vars.vars + varindx; - - if (! ieee_read_number (info, pp, &attr) - || ! ieee_read_number (info, pp, &frame_type) - || ! ieee_read_number (info, pp, &push_mask) - || ! ieee_read_type_index (info, pp, &rtype) - || ! ieee_read_number (info, pp, &nargs)) - return false; - if (nargs == (bfd_vma) -1) - { - arg_types = NULL; - varargs = false; - } - else - { - unsigned int i; - - arg_types = ((debug_type *) - xmalloc ((nargs + 1) * sizeof *arg_types)); - for (i = 0; i < nargs; i++) - if (! ieee_read_type_index (info, pp, arg_types + i)) - return false; - - /* If the last type is pointer to void, this is really a - varargs function. */ - varargs = false; - if (nargs > 0) - { - debug_type last; - - last = arg_types[nargs - 1]; - if (debug_get_type_kind (dhandle, last) == DEBUG_KIND_POINTER - && (debug_get_type_kind (dhandle, - debug_get_target_type (dhandle, - last)) - == DEBUG_KIND_VOID)) - { - --nargs; - varargs = true; - } - } - - /* If there are any pointer arguments, turn them into - indirect types in case we later need to convert them to - reference types. */ - for (i = 0; i < nargs; i++) - { - if (debug_get_type_kind (dhandle, arg_types[i]) - == DEBUG_KIND_POINTER) - { - if (arg_slots == NULL) - { - arg_slots = ((debug_type *) - xmalloc (nargs * sizeof *arg_slots)); - memset (arg_slots, 0, nargs * sizeof *arg_slots); - } - arg_slots[i] = arg_types[i]; - arg_types[i] = - debug_make_indirect_type (dhandle, - arg_slots + i, - (const char *) NULL); - } - } - - arg_types[nargs] = DEBUG_TYPE_NULL; - } - if (! ieee_read_number (info, pp, &level) - || ! ieee_read_optional_number (info, pp, &father, &present)) - return false; - - /* We can't distinguish between a global function and a static - function. */ - pv->kind = IEEE_FUNCTION; - - if (pv->namlen > 0 - && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER) - { - /* Set up the return type as an indirect type pointing to - the variable slot, so that we can change it to a - reference later if appropriate. */ - pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot); - *pv->pslot = rtype; - rtype = debug_make_indirect_type (dhandle, pv->pslot, - (const char *) NULL); - } - - type = debug_make_function_type (dhandle, rtype, arg_types, varargs); - } - break; - } - - /* Record the type in the table. */ - - if (type == DEBUG_TYPE_NULL) - return false; - - info->vars.vars[varindx].type = type; - - if ((tag || typdef) - && info->vars.vars[varindx].namlen > 0) - { - const char *name; - - name = savestring (info->vars.vars[varindx].name, - info->vars.vars[varindx].namlen); - if (typdef) - type = debug_name_type (dhandle, name, type); - else if (tc == 'E' || tc == 'N') - type = debug_tag_type (dhandle, name, type); - else - { - struct ieee_tag *it; - - /* We must allocate all struct tags as indirect types, so - that if we later see a definition of the tag as a C++ - record we can update the indirect slot and automatically - change all the existing references. */ - it = (struct ieee_tag *) xmalloc (sizeof *it); - memset (it, 0, sizeof *it); - it->next = info->tags; - info->tags = it; - it->name = name; - it->slot = type; - - type = debug_make_indirect_type (dhandle, &it->slot, name); - type = debug_tag_type (dhandle, name, type); - - it->type = type; - } - if (type == NULL) - return false; - } - - info->types.types[typeindx].type = type; - info->types.types[typeindx].arg_slots = arg_slots; - info->types.types[typeindx].bitsize = type_bitsize; - - /* We may have already allocated type as an indirect type pointing - to slot. It does no harm to replace the indirect type with the - real type. Filling in slot as well handles the indirect types - which are already hanging around. */ - if (info->types.types[typeindx].pslot != NULL) - *info->types.types[typeindx].pslot = type; - - return true; -} - -/* Parse an ATN record. */ - -static boolean -parse_ieee_atn (info, pp) - struct ieee_info *info; - const bfd_byte **pp; -{ - const bfd_byte *atn_start, *atn_code_start; - bfd_vma varindx; - struct ieee_var *pvar; - debug_type type; - bfd_vma atn_code; - PTR dhandle; - bfd_vma v, v2, v3, v4, v5; - const char *name; - unsigned long namlen; - char *namcopy; - boolean present; - int blocktype; - - atn_start = *pp; - - if (! ieee_read_number (info, pp, &varindx) - || ! ieee_read_type_index (info, pp, &type)) - return false; - - atn_code_start = *pp; - - if (! ieee_read_number (info, pp, &atn_code)) - return false; - - if (varindx == 0) - { - pvar = NULL; - name = ""; - namlen = 0; - } - else if (varindx < 32) - { - ieee_error (info, atn_start, "illegal variable index"); - return false; - } - else - { - varindx -= 32; - if (varindx >= info->vars.alloc - || info->vars.vars[varindx].name == NULL) - { - /* The MRI compiler or linker sometimes omits the NN record - for a pmisc record. */ - if (atn_code == 62) - { - if (varindx >= info->vars.alloc) - { - unsigned int alloc; - - alloc = info->vars.alloc; - if (alloc == 0) - alloc = 4; - while (varindx >= alloc) - alloc *= 2; - info->vars.vars = ((struct ieee_var *) - xrealloc (info->vars.vars, - (alloc - * sizeof *info->vars.vars))); - memset (info->vars.vars + info->vars.alloc, 0, - ((alloc - info->vars.alloc) - * sizeof *info->vars.vars)); - info->vars.alloc = alloc; - } - - pvar = info->vars.vars + varindx; - pvar->name = ""; - pvar->namlen = 0; - } - else - { - ieee_error (info, atn_start, "undefined variable in ATN"); - return false; - } - } - - pvar = info->vars.vars + varindx; - - pvar->type = type; - - name = pvar->name; - namlen = pvar->namlen; - } - - dhandle = info->dhandle; - - /* If we are going to call debug_record_variable with a pointer - type, change the type to an indirect type so that we can later - change it to a reference type if we encounter a C++ pmisc 'R' - record. */ - if (pvar != NULL - && type != DEBUG_TYPE_NULL - && debug_get_type_kind (dhandle, type) == DEBUG_KIND_POINTER) - { - switch (atn_code) - { - case 1: - case 2: - case 3: - case 5: - case 8: - case 10: - pvar->pslot = (debug_type *) xmalloc (sizeof *pvar->pslot); - *pvar->pslot = type; - type = debug_make_indirect_type (dhandle, pvar->pslot, - (const char *) NULL); - pvar->type = type; - break; - } - } - - switch (atn_code) - { - default: - ieee_error (info, atn_code_start, "unknown ATN type"); - return false; - - case 1: - /* Automatic variable. */ - if (! ieee_read_number (info, pp, &v)) - return false; - namcopy = savestring (name, namlen); - if (type == NULL) - type = debug_make_void_type (dhandle); - if (pvar != NULL) - pvar->kind = IEEE_LOCAL; - return debug_record_variable (dhandle, namcopy, type, DEBUG_LOCAL, v); - - case 2: - /* Register variable. */ - if (! ieee_read_number (info, pp, &v)) - return false; - namcopy = savestring (name, namlen); - if (type == NULL) - type = debug_make_void_type (dhandle); - if (pvar != NULL) - pvar->kind = IEEE_LOCAL; - return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER, - ieee_regno_to_genreg (info->abfd, v)); - - case 3: - /* Static variable. */ - if (! ieee_require_asn (info, pp, &v)) - return false; - namcopy = savestring (name, namlen); - if (type == NULL) - type = debug_make_void_type (dhandle); - if (info->blockstack.bsp <= info->blockstack.stack) - blocktype = 0; - else - blocktype = info->blockstack.bsp[-1].kind; - if (pvar != NULL) - { - if (blocktype == 4 || blocktype == 6) - pvar->kind = IEEE_LOCAL; - else - pvar->kind = IEEE_STATIC; - } - return debug_record_variable (dhandle, namcopy, type, - (blocktype == 4 || blocktype == 6 - ? DEBUG_LOCAL_STATIC - : DEBUG_STATIC), - v); - - case 4: - /* External function. We don't currently record these. FIXME. */ - if (pvar != NULL) - pvar->kind = IEEE_EXTERNAL; - return true; - - case 5: - /* External variable. We don't currently record these. FIXME. */ - if (pvar != NULL) - pvar->kind = IEEE_EXTERNAL; - return true; - - case 7: - if (! ieee_read_number (info, pp, &v) - || ! ieee_read_number (info, pp, &v2) - || ! ieee_read_optional_number (info, pp, &v3, &present)) - return false; - if (present) - { - if (! ieee_read_optional_number (info, pp, &v4, &present)) - return false; - } - - /* We just ignore the two optional fields in v3 and v4, since - they are not defined. */ - - if (! ieee_require_asn (info, pp, &v3)) - return false; - - /* We have no way to record the column number. FIXME. */ - - return debug_record_line (dhandle, v, v3); - - case 8: - /* Global variable. */ - if (! ieee_require_asn (info, pp, &v)) - return false; - namcopy = savestring (name, namlen); - if (type == NULL) - type = debug_make_void_type (dhandle); - if (pvar != NULL) - pvar->kind = IEEE_GLOBAL; - return debug_record_variable (dhandle, namcopy, type, DEBUG_GLOBAL, v); - - case 9: - /* Variable lifetime information. */ - if (! ieee_read_number (info, pp, &v)) - return false; - - /* We have no way to record this information. FIXME. */ - return true; - - case 10: - /* Locked register. The spec says that there are two required - fields, but at least on occasion the MRI compiler only emits - one. */ - if (! ieee_read_number (info, pp, &v) - || ! ieee_read_optional_number (info, pp, &v2, &present)) - return false; - - /* I think this means a variable that is both in a register and - a frame slot. We ignore the frame slot. FIXME. */ - - namcopy = savestring (name, namlen); - if (type == NULL) - type = debug_make_void_type (dhandle); - if (pvar != NULL) - pvar->kind = IEEE_LOCAL; - return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER, v); - - case 11: - /* Reserved for FORTRAN common. */ - ieee_error (info, atn_code_start, "unsupported ATN11"); - - /* Return true to keep going. */ - return true; - - case 12: - /* Based variable. */ - v3 = 0; - v4 = 0x80; - v5 = 0; - if (! ieee_read_number (info, pp, &v) - || ! ieee_read_number (info, pp, &v2) - || ! ieee_read_optional_number (info, pp, &v3, &present)) - return false; - if (present) - { - if (! ieee_read_optional_number (info, pp, &v4, &present)) - return false; - if (present) - { - if (! ieee_read_optional_number (info, pp, &v5, &present)) - return false; - } - } - - /* We have no way to record this information. FIXME. */ - - ieee_error (info, atn_code_start, "unsupported ATN12"); - - /* Return true to keep going. */ - return true; - - case 16: - /* Constant. The description of this that I have is ambiguous, - so I'm not going to try to implement it. */ - if (! ieee_read_number (info, pp, &v) - || ! ieee_read_optional_number (info, pp, &v2, &present)) - return false; - if (present) - { - if (! ieee_read_optional_number (info, pp, &v2, &present)) - return false; - if (present) - { - if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return false; - } - } - - if ((ieee_record_enum_type) **pp == ieee_e2_first_byte_enum) - { - if (! ieee_require_asn (info, pp, &v3)) - return false; - } - - return true; - - case 19: - /* Static variable from assembler. */ - v2 = 0; - if (! ieee_read_number (info, pp, &v) - || ! ieee_read_optional_number (info, pp, &v2, &present) - || ! ieee_require_asn (info, pp, &v3)) - return false; - namcopy = savestring (name, namlen); - /* We don't really handle this correctly. FIXME. */ - return debug_record_variable (dhandle, namcopy, - debug_make_void_type (dhandle), - v2 != 0 ? DEBUG_GLOBAL : DEBUG_STATIC, - v3); - - case 62: - /* Procedure miscellaneous information. */ - case 63: - /* Variable miscellaneous information. */ - case 64: - /* Module miscellaneous information. */ - if (! ieee_read_number (info, pp, &v) - || ! ieee_read_number (info, pp, &v2) - || ! ieee_read_optional_id (info, pp, &name, &namlen, &present)) - return false; - - if (atn_code == 62 && v == 80) - { - if (present) - { - ieee_error (info, atn_code_start, - "unexpected string in C++ misc"); - return false; - } - return ieee_read_cxx_misc (info, pp, v2); - } - - /* We just ignore all of this stuff. FIXME. */ - - for (; v2 > 0; --v2) - { - switch ((ieee_record_enum_type) **pp) - { - default: - ieee_error (info, *pp, "bad misc record"); - return false; - - case ieee_at_record_enum: - if (! ieee_require_atn65 (info, pp, &name, &namlen)) - return false; - break; - - case ieee_e2_first_byte_enum: - if (! ieee_require_asn (info, pp, &v3)) - return false; - break; - } - } - - return true; - } - - /*NOTREACHED*/ -} - -/* Handle C++ debugging miscellaneous records. This is called for - procedure miscellaneous records of type 80. */ - -static boolean -ieee_read_cxx_misc (info, pp, count) - struct ieee_info *info; - const bfd_byte **pp; - unsigned long count; -{ - const bfd_byte *start; - bfd_vma category; - - start = *pp; - - /* Get the category of C++ misc record. */ - if (! ieee_require_asn (info, pp, &category)) - return false; - --count; - - switch (category) - { - default: - ieee_error (info, start, "unrecognized C++ misc record"); - return false; - - case 'T': - if (! ieee_read_cxx_class (info, pp, count)) - return false; - break; - - case 'M': - { - bfd_vma flags; - const char *name; - unsigned long namlen; - - /* The IEEE spec indicates that the 'M' record only has a - flags field. The MRI compiler also emits the name of the - function. */ - - if (! ieee_require_asn (info, pp, &flags)) - return false; - if (*pp < info->pend - && (ieee_record_enum_type) **pp == ieee_at_record_enum) - { - if (! ieee_require_atn65 (info, pp, &name, &namlen)) - return false; - } - - /* This is emitted for method functions, but I don't think we - care very much. It might help if it told us useful - information like the class with which this function is - associated, but it doesn't, so it isn't helpful. */ - } - break; - - case 'B': - if (! ieee_read_cxx_defaults (info, pp, count)) - return false; - break; - - case 'z': - { - const char *name, *mangled, *class; - unsigned long namlen, mangledlen, classlen; - bfd_vma control; - - /* Pointer to member. */ - - if (! ieee_require_atn65 (info, pp, &name, &namlen) - || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen) - || ! ieee_require_atn65 (info, pp, &class, &classlen) - || ! ieee_require_asn (info, pp, &control)) - return false; - - /* FIXME: We should now track down name and change its type. */ - } - break; - - case 'R': - if (! ieee_read_reference (info, pp)) - return false; - break; - } - - return true; -} - -/* Read a C++ class definition. This is a pmisc type 80 record of - category 'T'. */ - -static boolean -ieee_read_cxx_class (info, pp, count) - struct ieee_info *info; - const bfd_byte **pp; - unsigned long count; -{ - const bfd_byte *start; - bfd_vma class; - const char *tag; - unsigned long taglen; - struct ieee_tag *it; - PTR dhandle; - debug_field *fields; - unsigned int field_count, field_alloc; - debug_baseclass *baseclasses; - unsigned int baseclasses_count, baseclasses_alloc; - const debug_field *structfields; - struct ieee_method - { - const char *name; - unsigned long namlen; - debug_method_variant *variants; - unsigned count; - unsigned int alloc; - } *methods; - unsigned int methods_count, methods_alloc; - debug_type vptrbase; - boolean ownvptr; - debug_method *dmethods; - - start = *pp; - - if (! ieee_require_asn (info, pp, &class)) - return false; - --count; - - if (! ieee_require_atn65 (info, pp, &tag, &taglen)) - return false; - --count; - - /* Find the C struct with this name. */ - for (it = info->tags; it != NULL; it = it->next) - if (it->name[0] == tag[0] - && strncmp (it->name, tag, taglen) == 0 - && strlen (it->name) == taglen) - break; - if (it == NULL) - { - ieee_error (info, start, "undefined C++ object"); - return false; - } - - dhandle = info->dhandle; - - fields = NULL; - field_count = 0; - field_alloc = 0; - baseclasses = NULL; - baseclasses_count = 0; - baseclasses_alloc = 0; - methods = NULL; - methods_count = 0; - methods_alloc = 0; - vptrbase = DEBUG_TYPE_NULL; - ownvptr = false; - - structfields = debug_get_fields (dhandle, it->type); - - while (count > 0) - { - bfd_vma id; - const bfd_byte *spec_start; - - spec_start = *pp; - - if (! ieee_require_asn (info, pp, &id)) - return false; - --count; - - switch (id) - { - default: - ieee_error (info, spec_start, "unrecognized C++ object spec"); - return false; - - case 'b': - { - bfd_vma flags, cinline; - const char *basename, *fieldname; - unsigned long baselen, fieldlen; - char *basecopy; - debug_type basetype; - bfd_vma bitpos; - boolean virtualp; - enum debug_visibility visibility; - debug_baseclass baseclass; - - /* This represents a base or friend class. */ - - if (! ieee_require_asn (info, pp, &flags) - || ! ieee_require_atn65 (info, pp, &basename, &baselen) - || ! ieee_require_asn (info, pp, &cinline) - || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen)) - return false; - count -= 4; - - /* We have no way of recording friend information, so we - just ignore it. */ - if ((flags & BASEFLAGS_FRIEND) != 0) - break; - - /* I assume that either all of the members of the - baseclass are included in the object, starting at the - beginning of the object, or that none of them are - included. */ - - if ((fieldlen == 0) == (cinline == 0)) - { - ieee_error (info, start, "unsupported C++ object type"); - return false; - } - - basecopy = savestring (basename, baselen); - basetype = debug_find_tagged_type (dhandle, basecopy, - DEBUG_KIND_ILLEGAL); - free (basecopy); - if (basetype == DEBUG_TYPE_NULL) - { - ieee_error (info, start, "C++ base class not defined"); - return false; - } - - if (fieldlen == 0) - bitpos = 0; - else - { - const debug_field *pf; - - if (structfields == NULL) - { - ieee_error (info, start, "C++ object has no fields"); - return false; - } - - for (pf = structfields; *pf != DEBUG_FIELD_NULL; pf++) - { - const char *fname; - - fname = debug_get_field_name (dhandle, *pf); - if (fname == NULL) - return false; - if (fname[0] == fieldname[0] - && strncmp (fname, fieldname, fieldlen) == 0 - && strlen (fname) == fieldlen) - break; - } - if (*pf == DEBUG_FIELD_NULL) - { - ieee_error (info, start, - "C++ base class not found in container"); - return false; - } - - bitpos = debug_get_field_bitpos (dhandle, *pf); - } - - if ((flags & BASEFLAGS_VIRTUAL) != 0) - virtualp = true; - else - virtualp = false; - if ((flags & BASEFLAGS_PRIVATE) != 0) - visibility = DEBUG_VISIBILITY_PRIVATE; - else - visibility = DEBUG_VISIBILITY_PUBLIC; - - baseclass = debug_make_baseclass (dhandle, basetype, bitpos, - virtualp, visibility); - if (baseclass == DEBUG_BASECLASS_NULL) - return false; - - if (baseclasses_count + 1 >= baseclasses_alloc) - { - baseclasses_alloc += 10; - baseclasses = ((debug_baseclass *) - xrealloc (baseclasses, - (baseclasses_alloc - * sizeof *baseclasses))); - } - - baseclasses[baseclasses_count] = baseclass; - ++baseclasses_count; - baseclasses[baseclasses_count] = DEBUG_BASECLASS_NULL; - } - break; - - case 'd': - { - bfd_vma flags; - const char *fieldname, *mangledname; - unsigned long fieldlen, mangledlen; - char *fieldcopy; - boolean staticp; - debug_type ftype; - const debug_field *pf = NULL; - enum debug_visibility visibility; - debug_field field; - - /* This represents a data member. */ - - if (! ieee_require_asn (info, pp, &flags) - || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen) - || ! ieee_require_atn65 (info, pp, &mangledname, &mangledlen)) - return false; - count -= 3; - - fieldcopy = savestring (fieldname, fieldlen); - - staticp = (flags & CXXFLAGS_STATIC) != 0 ? true : false; - - if (staticp) - { - struct ieee_var *pv, *pvend; - - /* See if we can find a definition for this variable. */ - pv = info->vars.vars; - pvend = pv + info->vars.alloc; - for (; pv < pvend; pv++) - if (pv->namlen == mangledlen - && strncmp (pv->name, mangledname, mangledlen) == 0) - break; - if (pv < pvend) - ftype = pv->type; - else - { - /* This can happen if the variable is never used. */ - ftype = ieee_builtin_type (info, start, - (unsigned int) builtin_void); - } - } - else - { - unsigned int findx; - - if (structfields == NULL) - { - ieee_error (info, start, "C++ object has no fields"); - return false; - } - - for (pf = structfields, findx = 0; - *pf != DEBUG_FIELD_NULL; - pf++, findx++) - { - const char *fname; - - fname = debug_get_field_name (dhandle, *pf); - if (fname == NULL) - return false; - if (fname[0] == mangledname[0] - && strncmp (fname, mangledname, mangledlen) == 0 - && strlen (fname) == mangledlen) - break; - } - if (*pf == DEBUG_FIELD_NULL) - { - ieee_error (info, start, - "C++ data member not found in container"); - return false; - } - - ftype = debug_get_field_type (dhandle, *pf); - - if (debug_get_type_kind (dhandle, ftype) == DEBUG_KIND_POINTER) - { - /* We might need to convert this field into a - reference type later on, so make it an indirect - type. */ - if (it->fslots == NULL) - { - unsigned int fcnt; - const debug_field *pfcnt; - - fcnt = 0; - for (pfcnt = structfields; - *pfcnt != DEBUG_FIELD_NULL; - pfcnt++) - ++fcnt; - it->fslots = ((debug_type *) - xmalloc (fcnt * sizeof *it->fslots)); - memset (it->fslots, 0, - fcnt * sizeof *it->fslots); - } - - if (ftype == DEBUG_TYPE_NULL) - return false; - it->fslots[findx] = ftype; - ftype = debug_make_indirect_type (dhandle, - it->fslots + findx, - (const char *) NULL); - } - } - if (ftype == DEBUG_TYPE_NULL) - return false; - - switch (flags & CXXFLAGS_VISIBILITY) - { - default: - ieee_error (info, start, "unknown C++ visibility"); - return false; - - case CXXFLAGS_VISIBILITY_PUBLIC: - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - - case CXXFLAGS_VISIBILITY_PRIVATE: - visibility = DEBUG_VISIBILITY_PRIVATE; - break; - - case CXXFLAGS_VISIBILITY_PROTECTED: - visibility = DEBUG_VISIBILITY_PROTECTED; - break; - } - - if (staticp) - { - char *mangledcopy; - - mangledcopy = savestring (mangledname, mangledlen); - - field = debug_make_static_member (dhandle, fieldcopy, - ftype, mangledcopy, - visibility); - } - else - { - bfd_vma bitpos, bitsize; - - bitpos = debug_get_field_bitpos (dhandle, *pf); - bitsize = debug_get_field_bitsize (dhandle, *pf); - if (bitpos == (bfd_vma) -1 || bitsize == (bfd_vma) -1) - { - ieee_error (info, start, "bad C++ field bit pos or size"); - return false; - } - field = debug_make_field (dhandle, fieldcopy, ftype, bitpos, - bitsize, visibility); - } - - if (field == DEBUG_FIELD_NULL) - return false; - - if (field_count + 1 >= field_alloc) - { - field_alloc += 10; - fields = ((debug_field *) - xrealloc (fields, field_alloc * sizeof *fields)); - } - - fields[field_count] = field; - ++field_count; - fields[field_count] = DEBUG_FIELD_NULL; - } - break; - - case 'm': - case 'v': - { - bfd_vma flags, voffset, control; - const char *name, *mangled; - unsigned long namlen, mangledlen; - struct ieee_var *pv, *pvend; - debug_type type; - enum debug_visibility visibility; - boolean constp, volatilep; - char *mangledcopy; - debug_method_variant mv; - struct ieee_method *meth; - unsigned int im; - - if (! ieee_require_asn (info, pp, &flags) - || ! ieee_require_atn65 (info, pp, &name, &namlen) - || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen)) - return false; - count -= 3; - if (id != 'v') - voffset = 0; - else - { - if (! ieee_require_asn (info, pp, &voffset)) - return false; - --count; - } - if (! ieee_require_asn (info, pp, &control)) - return false; - --count; - - /* We just ignore the control information. */ - - /* We have no way to represent friend information, so we - just ignore it. */ - if ((flags & CXXFLAGS_FRIEND) != 0) - break; - - /* We should already have seen a type for the function. */ - pv = info->vars.vars; - pvend = pv + info->vars.alloc; - for (; pv < pvend; pv++) - if (pv->namlen == mangledlen - && strncmp (pv->name, mangled, mangledlen) == 0) - break; - - if (pv >= pvend) - { - /* We won't have type information for this function if - it is not included in this file. We don't try to - handle this case. FIXME. */ - type = (debug_make_function_type - (dhandle, - ieee_builtin_type (info, start, - (unsigned int) builtin_void), - (debug_type *) NULL, - false)); - } - else - { - debug_type return_type; - const debug_type *arg_types; - boolean varargs; - - if (debug_get_type_kind (dhandle, pv->type) - != DEBUG_KIND_FUNCTION) - { - ieee_error (info, start, - "bad type for C++ method function"); - return false; - } - - return_type = debug_get_return_type (dhandle, pv->type); - arg_types = debug_get_parameter_types (dhandle, pv->type, - &varargs); - if (return_type == DEBUG_TYPE_NULL || arg_types == NULL) - { - ieee_error (info, start, - "no type information for C++ method function"); - return false; - } - - type = debug_make_method_type (dhandle, return_type, it->type, - (debug_type *) arg_types, - varargs); - } - if (type == DEBUG_TYPE_NULL) - return false; - - switch (flags & CXXFLAGS_VISIBILITY) - { - default: - ieee_error (info, start, "unknown C++ visibility"); - return false; - - case CXXFLAGS_VISIBILITY_PUBLIC: - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - - case CXXFLAGS_VISIBILITY_PRIVATE: - visibility = DEBUG_VISIBILITY_PRIVATE; - break; - - case CXXFLAGS_VISIBILITY_PROTECTED: - visibility = DEBUG_VISIBILITY_PROTECTED; - break; - } - - constp = (flags & CXXFLAGS_CONST) != 0 ? true : false; - volatilep = (flags & CXXFLAGS_VOLATILE) != 0 ? true : false; - - mangledcopy = savestring (mangled, mangledlen); - - if ((flags & CXXFLAGS_STATIC) != 0) - { - if (id == 'v') - { - ieee_error (info, start, "C++ static virtual method"); - return false; - } - mv = debug_make_static_method_variant (dhandle, mangledcopy, - type, visibility, - constp, volatilep); - } - else - { - debug_type vcontext; - - if (id != 'v') - vcontext = DEBUG_TYPE_NULL; - else - { - /* FIXME: How can we calculate this correctly? */ - vcontext = it->type; - } - mv = debug_make_method_variant (dhandle, mangledcopy, type, - visibility, constp, - volatilep, voffset, - vcontext); - } - if (mv == DEBUG_METHOD_VARIANT_NULL) - return false; - - for (meth = methods, im = 0; im < methods_count; meth++, im++) - if (meth->namlen == namlen - && strncmp (meth->name, name, namlen) == 0) - break; - if (im >= methods_count) - { - if (methods_count >= methods_alloc) - { - methods_alloc += 10; - methods = ((struct ieee_method *) - xrealloc (methods, - methods_alloc * sizeof *methods)); - } - methods[methods_count].name = name; - methods[methods_count].namlen = namlen; - methods[methods_count].variants = NULL; - methods[methods_count].count = 0; - methods[methods_count].alloc = 0; - meth = methods + methods_count; - ++methods_count; - } - - if (meth->count + 1 >= meth->alloc) - { - meth->alloc += 10; - meth->variants = ((debug_method_variant *) - xrealloc (meth->variants, - (meth->alloc - * sizeof *meth->variants))); - } - - meth->variants[meth->count] = mv; - ++meth->count; - meth->variants[meth->count] = DEBUG_METHOD_VARIANT_NULL; - } - break; - - case 'o': - { - bfd_vma spec; - - /* We have no way to store this information, so we just - ignore it. */ - if (! ieee_require_asn (info, pp, &spec)) - return false; - --count; - if ((spec & 4) != 0) - { - const char *filename; - unsigned long filenamlen; - bfd_vma lineno; - - if (! ieee_require_atn65 (info, pp, &filename, &filenamlen) - || ! ieee_require_asn (info, pp, &lineno)) - return false; - count -= 2; - } - else if ((spec & 8) != 0) - { - const char *mangled; - unsigned long mangledlen; - - if (! ieee_require_atn65 (info, pp, &mangled, &mangledlen)) - return false; - --count; - } - else - { - ieee_error (info, start, - "unrecognized C++ object overhead spec"); - return false; - } - } - break; - - case 'z': - { - const char *vname, *basename; - unsigned long vnamelen, baselen; - bfd_vma vsize, control; - - /* A virtual table pointer. */ - - if (! ieee_require_atn65 (info, pp, &vname, &vnamelen) - || ! ieee_require_asn (info, pp, &vsize) - || ! ieee_require_atn65 (info, pp, &basename, &baselen) - || ! ieee_require_asn (info, pp, &control)) - return false; - count -= 4; - - /* We just ignore the control number. We don't care what - the virtual table name is. We have no way to store the - virtual table size, and I don't think we care anyhow. */ - - /* FIXME: We can't handle multiple virtual table pointers. */ - - if (baselen == 0) - ownvptr = true; - else - { - char *basecopy; - - basecopy = savestring (basename, baselen); - vptrbase = debug_find_tagged_type (dhandle, basecopy, - DEBUG_KIND_ILLEGAL); - free (basecopy); - if (vptrbase == DEBUG_TYPE_NULL) - { - ieee_error (info, start, "undefined C++ vtable"); - return false; - } - } - } - break; - } - } - - /* Now that we have seen all the method variants, we can call - debug_make_method for each one. */ - - if (methods_count == 0) - dmethods = NULL; - else - { - unsigned int i; - - dmethods = ((debug_method *) - xmalloc ((methods_count + 1) * sizeof *dmethods)); - for (i = 0; i < methods_count; i++) - { - char *namcopy; - - namcopy = savestring (methods[i].name, methods[i].namlen); - dmethods[i] = debug_make_method (dhandle, namcopy, - methods[i].variants); - if (dmethods[i] == DEBUG_METHOD_NULL) - return false; - } - dmethods[i] = DEBUG_METHOD_NULL; - free (methods); - } - - /* The struct type was created as an indirect type pointing at - it->slot. We update it->slot to automatically update all - references to this struct. */ - it->slot = debug_make_object_type (dhandle, - class != 'u', - debug_get_type_size (dhandle, - it->slot), - fields, baseclasses, dmethods, - vptrbase, ownvptr); - if (it->slot == DEBUG_TYPE_NULL) - return false; - - return true; -} - -/* Read C++ default argument value and reference type information. */ - -static boolean -ieee_read_cxx_defaults (info, pp, count) - struct ieee_info *info; - const bfd_byte **pp; - unsigned long count; -{ - const bfd_byte *start; - const char *fnname; - unsigned long fnlen; - bfd_vma defcount; - - start = *pp; - - /* Giving the function name before the argument count is an addendum - to the spec. The function name is demangled, though, so this - record must always refer to the current function. */ - - if (info->blockstack.bsp <= info->blockstack.stack - || info->blockstack.bsp[-1].fnindx == (unsigned int) -1) - { - ieee_error (info, start, "C++ default values not in a function"); - return false; - } - - if (! ieee_require_atn65 (info, pp, &fnname, &fnlen) - || ! ieee_require_asn (info, pp, &defcount)) - return false; - count -= 2; - - while (defcount-- > 0) - { - bfd_vma type, val; - const char *strval; - unsigned long strvallen; - - if (! ieee_require_asn (info, pp, &type)) - return false; - --count; - - switch (type) - { - case 0: - case 4: - break; - - case 1: - case 2: - if (! ieee_require_asn (info, pp, &val)) - return false; - --count; - break; - - case 3: - case 7: - if (! ieee_require_atn65 (info, pp, &strval, &strvallen)) - return false; - --count; - break; - - default: - ieee_error (info, start, "unrecognized C++ default type"); - return false; - } - - /* We have no way to record the default argument values, so we - just ignore them. FIXME. */ - } - - /* Any remaining arguments are indices of parameters that are really - reference type. */ - if (count > 0) - { - PTR dhandle; - debug_type *arg_slots; - - dhandle = info->dhandle; - arg_slots = info->types.types[info->blockstack.bsp[-1].fnindx].arg_slots; - while (count-- > 0) - { - bfd_vma indx; - debug_type target; - - if (! ieee_require_asn (info, pp, &indx)) - return false; - /* The index is 1 based. */ - --indx; - if (arg_slots == NULL - || arg_slots[indx] == DEBUG_TYPE_NULL - || (debug_get_type_kind (dhandle, arg_slots[indx]) - != DEBUG_KIND_POINTER)) - { - ieee_error (info, start, "reference parameter is not a pointer"); - return false; - } - - target = debug_get_target_type (dhandle, arg_slots[indx]); - arg_slots[indx] = debug_make_reference_type (dhandle, target); - if (arg_slots[indx] == DEBUG_TYPE_NULL) - return false; - } - } - - return true; -} - -/* Read a C++ reference definition. */ - -static boolean -ieee_read_reference (info, pp) - struct ieee_info *info; - const bfd_byte **pp; -{ - const bfd_byte *start; - bfd_vma flags; - const char *class, *name; - unsigned long classlen, namlen; - debug_type *pslot; - debug_type target; - - start = *pp; - - if (! ieee_require_asn (info, pp, &flags)) - return false; - - /* Giving the class name before the member name is in an addendum to - the spec. */ - if (flags == 3) - { - if (! ieee_require_atn65 (info, pp, &class, &classlen)) - return false; - } - - if (! ieee_require_atn65 (info, pp, &name, &namlen)) - return false; - - pslot = NULL; - if (flags != 3) - { - int pass; - - /* We search from the last variable indices to the first in - hopes of finding local variables correctly. We search the - local variables on the first pass, and the global variables - on the second. FIXME: This probably won't work in all cases. - On the other hand, I don't know what will. */ - for (pass = 0; pass < 2; pass++) - { - struct ieee_vars *vars; - int i; - struct ieee_var *pv = NULL; - - if (pass == 0) - vars = &info->vars; - else - { - vars = info->global_vars; - if (vars == NULL) - break; - } - - for (i = (int) vars->alloc - 1; i >= 0; i--) - { - boolean found; - - pv = vars->vars + i; - - if (pv->pslot == NULL - || pv->namlen != namlen - || strncmp (pv->name, name, namlen) != 0) - continue; - - found = false; - switch (flags) - { - default: - ieee_error (info, start, - "unrecognized C++ reference type"); - return false; - - case 0: - /* Global variable or function. */ - if (pv->kind == IEEE_GLOBAL - || pv->kind == IEEE_EXTERNAL - || pv->kind == IEEE_FUNCTION) - found = true; - break; - - case 1: - /* Global static variable or function. */ - if (pv->kind == IEEE_STATIC - || pv->kind == IEEE_FUNCTION) - found = true; - break; - - case 2: - /* Local variable. */ - if (pv->kind == IEEE_LOCAL) - found = true; - break; - } - - if (found) - break; - } - - if (i >= 0) - { - pslot = pv->pslot; - break; - } - } - } - else - { - struct ieee_tag *it; - - for (it = info->tags; it != NULL; it = it->next) - { - if (it->name[0] == class[0] - && strncmp (it->name, class, classlen) == 0 - && strlen (it->name) == classlen) - { - if (it->fslots != NULL) - { - const debug_field *pf; - unsigned int findx; - - pf = debug_get_fields (info->dhandle, it->type); - if (pf == NULL) - { - ieee_error (info, start, - "C++ reference in class with no fields"); - return false; - } - - for (findx = 0; *pf != DEBUG_FIELD_NULL; pf++, findx++) - { - const char *fname; - - fname = debug_get_field_name (info->dhandle, *pf); - if (fname == NULL) - return false; - if (strncmp (fname, name, namlen) == 0 - && strlen (fname) == namlen) - { - pslot = it->fslots + findx; - break; - } - } - } - - break; - } - } - } - - if (pslot == NULL) - { - ieee_error (info, start, "C++ reference not found"); - return false; - } - - /* We allocated the type of the object as an indirect type pointing - to *pslot, which we can now update to be a reference type. */ - if (debug_get_type_kind (info->dhandle, *pslot) != DEBUG_KIND_POINTER) - { - ieee_error (info, start, "C++ reference is not pointer"); - return false; - } - - target = debug_get_target_type (info->dhandle, *pslot); - *pslot = debug_make_reference_type (info->dhandle, target); - if (*pslot == DEBUG_TYPE_NULL) - return false; - - return true; -} - -/* Require an ASN record. */ - -static boolean -ieee_require_asn (info, pp, pv) - struct ieee_info *info; - const bfd_byte **pp; - bfd_vma *pv; -{ - const bfd_byte *start; - ieee_record_enum_type c; - bfd_vma varindx; - - start = *pp; - - c = (ieee_record_enum_type) **pp; - if (c != ieee_e2_first_byte_enum) - { - ieee_error (info, start, "missing required ASN"); - return false; - } - ++*pp; - - c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp); - if (c != ieee_asn_record_enum) - { - ieee_error (info, start, "missing required ASN"); - return false; - } - ++*pp; - - /* Just ignore the variable index. */ - if (! ieee_read_number (info, pp, &varindx)) - return false; - - return ieee_read_expression (info, pp, pv); -} - -/* Require an ATN65 record. */ - -static boolean -ieee_require_atn65 (info, pp, pname, pnamlen) - struct ieee_info *info; - const bfd_byte **pp; - const char **pname; - unsigned long *pnamlen; -{ - const bfd_byte *start; - ieee_record_enum_type c; - bfd_vma name_indx, type_indx, atn_code; - - start = *pp; - - c = (ieee_record_enum_type) **pp; - if (c != ieee_at_record_enum) - { - ieee_error (info, start, "missing required ATN65"); - return false; - } - ++*pp; - - c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp); - if (c != ieee_atn_record_enum) - { - ieee_error (info, start, "missing required ATN65"); - return false; - } - ++*pp; - - if (! ieee_read_number (info, pp, &name_indx) - || ! ieee_read_number (info, pp, &type_indx) - || ! ieee_read_number (info, pp, &atn_code)) - return false; - - /* Just ignore name_indx. */ - - if (type_indx != 0 || atn_code != 65) - { - ieee_error (info, start, "bad ATN65 record"); - return false; - } - - return ieee_read_id (info, pp, pname, pnamlen); -} - -/* Convert a register number in IEEE debugging information into a - generic register number. */ - -static int -ieee_regno_to_genreg (abfd, r) - bfd *abfd; - int r; -{ - switch (bfd_get_arch (abfd)) - { - case bfd_arch_m68k: - /* For some reasons stabs adds 2 to the floating point register - numbers. */ - if (r >= 16) - r += 2; - break; - - case bfd_arch_i960: - /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and - 32 to 35 for fp0 to fp3. */ - --r; - break; - - default: - break; - } - - return r; -} - -/* Convert a generic register number to an IEEE specific one. */ - -static int -ieee_genreg_to_regno (abfd, r) - bfd *abfd; - int r; -{ - switch (bfd_get_arch (abfd)) - { - case bfd_arch_m68k: - /* For some reason stabs add 2 to the floating point register - numbers. */ - if (r >= 18) - r -= 2; - break; - - case bfd_arch_i960: - /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and - 32 to 35 for fp0 to fp3. */ - ++r; - break; - - default: - break; - } - - return r; -} - -/* These routines build IEEE debugging information out of the generic - debugging information. */ - -/* We build the IEEE debugging information byte by byte. Rather than - waste time copying data around, we use a linked list of buffers to - hold the data. */ - -#define IEEE_BUFSIZE (490) - -struct ieee_buf -{ - /* Next buffer. */ - struct ieee_buf *next; - /* Number of data bytes in this buffer. */ - unsigned int c; - /* Bytes. */ - bfd_byte buf[IEEE_BUFSIZE]; -}; - -/* A list of buffers. */ - -struct ieee_buflist -{ - /* Head of list. */ - struct ieee_buf *head; - /* Tail--last buffer on list. */ - struct ieee_buf *tail; -}; - -/* In order to generate the BB11 blocks required by the HP emulator, - we keep track of ranges of addresses which correspond to a given - compilation unit. */ - -struct ieee_range -{ - /* Next range. */ - struct ieee_range *next; - /* Low address. */ - bfd_vma low; - /* High address. */ - bfd_vma high; -}; - -/* This structure holds information for a class on the type stack. */ - -struct ieee_type_class -{ - /* The name index in the debugging information. */ - unsigned int indx; - /* The pmisc records for the class. */ - struct ieee_buflist pmiscbuf; - /* The number of pmisc records. */ - unsigned int pmisccount; - /* The name of the class holding the virtual table, if not this - class. */ - const char *vclass; - /* Whether this class holds its own virtual table. */ - boolean ownvptr; - /* The largest virtual table offset seen so far. */ - bfd_vma voffset; - /* The current method. */ - const char *method; - /* Additional pmisc records used to record fields of reference type. */ - struct ieee_buflist refs; -}; - -/* This is how we store types for the writing routines. Most types - are simply represented by a type index. */ - -struct ieee_write_type -{ - /* Type index. */ - unsigned int indx; - /* The size of the type, if known. */ - unsigned int size; - /* The name of the type, if any. */ - const char *name; - /* If this is a function or method type, we build the type here, and - only add it to the output buffers if we need it. */ - struct ieee_buflist fndef; - /* If this is a struct, this is where the struct definition is - built. */ - struct ieee_buflist strdef; - /* If this is a class, this is where the class information is built. */ - struct ieee_type_class *classdef; - /* Whether the type is unsigned. */ - unsigned int unsignedp : 1; - /* Whether this is a reference type. */ - unsigned int referencep : 1; - /* Whether this is in the local type block. */ - unsigned int localp : 1; - /* Whether this is a duplicate struct definition which we are - ignoring. */ - unsigned int ignorep : 1; -}; - -/* This is the type stack used by the debug writing routines. FIXME: - We could generate more efficient output if we remembered when we - have output a particular type before. */ - -struct ieee_type_stack -{ - /* Next entry on stack. */ - struct ieee_type_stack *next; - /* Type information. */ - struct ieee_write_type type; -}; - -/* This is a list of associations between a name and some types. - These are used for typedefs and tags. */ - -struct ieee_name_type -{ - /* Next type for this name. */ - struct ieee_name_type *next; - /* ID number. For a typedef, this is the index of the type to which - this name is typedefed. */ - unsigned int id; - /* Type. */ - struct ieee_write_type type; - /* If this is a tag which has not yet been defined, this is the - kind. If the tag has been defined, this is DEBUG_KIND_ILLEGAL. */ - enum debug_type_kind kind; -}; - -/* We use a hash table to associate names and types. */ - -struct ieee_name_type_hash_table -{ - struct bfd_hash_table root; -}; - -struct ieee_name_type_hash_entry -{ - struct bfd_hash_entry root; - /* Information for this name. */ - struct ieee_name_type *types; -}; - -/* This is a list of enums. */ - -struct ieee_defined_enum -{ - /* Next enum. */ - struct ieee_defined_enum *next; - /* Type index. */ - unsigned int indx; - /* Whether this enum has been defined. */ - boolean defined; - /* Tag. */ - const char *tag; - /* Names. */ - const char **names; - /* Values. */ - bfd_signed_vma *vals; -}; - -/* We keep a list of modified versions of types, so that we don't - output them more than once. */ - -struct ieee_modified_type -{ - /* Pointer to this type. */ - unsigned int pointer; - /* Function with unknown arguments returning this type. */ - unsigned int function; - /* Const version of this type. */ - unsigned int const_qualified; - /* Volatile version of this type. */ - unsigned int volatile_qualified; - /* List of arrays of this type of various bounds. */ - struct ieee_modified_array_type *arrays; -}; - -/* A list of arrays bounds. */ - -struct ieee_modified_array_type -{ - /* Next array bounds. */ - struct ieee_modified_array_type *next; - /* Type index with these bounds. */ - unsigned int indx; - /* Low bound. */ - bfd_signed_vma low; - /* High bound. */ - bfd_signed_vma high; -}; - -/* This is a list of pending function parameter information. We don't - output them until we see the first block. */ - -struct ieee_pending_parm -{ - /* Next pending parameter. */ - struct ieee_pending_parm *next; - /* Name. */ - const char *name; - /* Type index. */ - unsigned int type; - /* Whether the type is a reference. */ - boolean referencep; - /* Kind. */ - enum debug_parm_kind kind; - /* Value. */ - bfd_vma val; -}; - -/* This is the handle passed down by debug_write. */ - -struct ieee_handle -{ - /* BFD we are writing to. */ - bfd *abfd; - /* Whether we got an error in a subroutine called via traverse or - map_over_sections. */ - boolean error; - /* Current data buffer list. */ - struct ieee_buflist *current; - /* Current data buffer. */ - struct ieee_buf *curbuf; - /* Filename of current compilation unit. */ - const char *filename; - /* Module name of current compilation unit. */ - const char *modname; - /* List of buffer for global types. */ - struct ieee_buflist global_types; - /* List of finished data buffers. */ - struct ieee_buflist data; - /* List of buffers for typedefs in the current compilation unit. */ - struct ieee_buflist types; - /* List of buffers for variables and functions in the current - compilation unit. */ - struct ieee_buflist vars; - /* List of buffers for C++ class definitions in the current - compilation unit. */ - struct ieee_buflist cxx; - /* List of buffers for line numbers in the current compilation unit. */ - struct ieee_buflist linenos; - /* Ranges for the current compilation unit. */ - struct ieee_range *ranges; - /* Ranges for all debugging information. */ - struct ieee_range *global_ranges; - /* Nested pending ranges. */ - struct ieee_range *pending_ranges; - /* Type stack. */ - struct ieee_type_stack *type_stack; - /* Next unallocated type index. */ - unsigned int type_indx; - /* Next unallocated name index. */ - unsigned int name_indx; - /* Typedefs. */ - struct ieee_name_type_hash_table typedefs; - /* Tags. */ - struct ieee_name_type_hash_table tags; - /* Enums. */ - struct ieee_defined_enum *enums; - /* Modified versions of types. */ - struct ieee_modified_type *modified; - /* Number of entries allocated in modified. */ - unsigned int modified_alloc; - /* 4 byte complex type. */ - unsigned int complex_float_index; - /* 8 byte complex type. */ - unsigned int complex_double_index; - /* The depth of block nesting. This is 0 outside a function, and 1 - just after start_function is called. */ - unsigned int block_depth; - /* The name of the current function. */ - const char *fnname; - /* List of buffers for the type of the function we are currently - writing out. */ - struct ieee_buflist fntype; - /* List of buffers for the parameters of the function we are - currently writing out. */ - struct ieee_buflist fnargs; - /* Number of arguments written to fnargs. */ - unsigned int fnargcount; - /* Pending function parameters. */ - struct ieee_pending_parm *pending_parms; - /* Current line number filename. */ - const char *lineno_filename; - /* Line number name index. */ - unsigned int lineno_name_indx; - /* Filename of pending line number. */ - const char *pending_lineno_filename; - /* Pending line number. */ - unsigned long pending_lineno; - /* Address of pending line number. */ - bfd_vma pending_lineno_addr; - /* Highest address seen at end of procedure. */ - bfd_vma highaddr; -}; - -static boolean ieee_init_buffer - PARAMS ((struct ieee_handle *, struct ieee_buflist *)); -static boolean ieee_change_buffer - PARAMS ((struct ieee_handle *, struct ieee_buflist *)); -static boolean ieee_append_buffer - PARAMS ((struct ieee_handle *, struct ieee_buflist *, - struct ieee_buflist *)); -static boolean ieee_real_write_byte PARAMS ((struct ieee_handle *, int)); -static boolean ieee_write_2bytes PARAMS ((struct ieee_handle *, int)); -static boolean ieee_write_number PARAMS ((struct ieee_handle *, bfd_vma)); -static boolean ieee_write_id PARAMS ((struct ieee_handle *, const char *)); -static boolean ieee_write_asn - PARAMS ((struct ieee_handle *, unsigned int, bfd_vma)); -static boolean ieee_write_atn65 - PARAMS ((struct ieee_handle *, unsigned int, const char *)); -static boolean ieee_push_type - PARAMS ((struct ieee_handle *, unsigned int, unsigned int, boolean, - boolean)); -static unsigned int ieee_pop_type PARAMS ((struct ieee_handle *)); -static void ieee_pop_unused_type PARAMS ((struct ieee_handle *)); -static unsigned int ieee_pop_type_used - PARAMS ((struct ieee_handle *, boolean)); -static boolean ieee_add_range - PARAMS ((struct ieee_handle *, boolean, bfd_vma, bfd_vma)); -static boolean ieee_start_range PARAMS ((struct ieee_handle *, bfd_vma)); -static boolean ieee_end_range PARAMS ((struct ieee_handle *, bfd_vma)); -static boolean ieee_define_type - PARAMS ((struct ieee_handle *, unsigned int, boolean, boolean)); -static boolean ieee_define_named_type - PARAMS ((struct ieee_handle *, const char *, unsigned int, unsigned int, - boolean, boolean, struct ieee_buflist *)); -static struct ieee_modified_type *ieee_get_modified_info - PARAMS ((struct ieee_handle *, unsigned int)); -static struct bfd_hash_entry *ieee_name_type_newfunc - PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); -static boolean ieee_write_undefined_tag - PARAMS ((struct ieee_name_type_hash_entry *, PTR)); -static boolean ieee_finish_compilation_unit PARAMS ((struct ieee_handle *)); -static void ieee_add_bb11_blocks PARAMS ((bfd *, asection *, PTR)); -static boolean ieee_add_bb11 - PARAMS ((struct ieee_handle *, asection *, bfd_vma, bfd_vma)); -static boolean ieee_output_pending_parms PARAMS ((struct ieee_handle *)); -static unsigned int ieee_vis_to_flags PARAMS ((enum debug_visibility)); -static boolean ieee_class_method_var - PARAMS ((struct ieee_handle *, const char *, enum debug_visibility, boolean, - boolean, boolean, bfd_vma, boolean)); - -static boolean ieee_start_compilation_unit PARAMS ((PTR, const char *)); -static boolean ieee_start_source PARAMS ((PTR, const char *)); -static boolean ieee_empty_type PARAMS ((PTR)); -static boolean ieee_void_type PARAMS ((PTR)); -static boolean ieee_int_type PARAMS ((PTR, unsigned int, boolean)); -static boolean ieee_float_type PARAMS ((PTR, unsigned int)); -static boolean ieee_complex_type PARAMS ((PTR, unsigned int)); -static boolean ieee_bool_type PARAMS ((PTR, unsigned int)); -static boolean ieee_enum_type - PARAMS ((PTR, const char *, const char **, bfd_signed_vma *)); -static boolean ieee_pointer_type PARAMS ((PTR)); -static boolean ieee_function_type PARAMS ((PTR, int, boolean)); -static boolean ieee_reference_type PARAMS ((PTR)); -static boolean ieee_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma)); -static boolean ieee_array_type - PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean)); -static boolean ieee_set_type PARAMS ((PTR, boolean)); -static boolean ieee_offset_type PARAMS ((PTR)); -static boolean ieee_method_type PARAMS ((PTR, boolean, int, boolean)); -static boolean ieee_const_type PARAMS ((PTR)); -static boolean ieee_volatile_type PARAMS ((PTR)); -static boolean ieee_start_struct_type - PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int)); -static boolean ieee_struct_field - PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility)); -static boolean ieee_end_struct_type PARAMS ((PTR)); -static boolean ieee_start_class_type - PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean, - boolean)); -static boolean ieee_class_static_member - PARAMS ((PTR, const char *, const char *, enum debug_visibility)); -static boolean ieee_class_baseclass - PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility)); -static boolean ieee_class_start_method PARAMS ((PTR, const char *)); -static boolean ieee_class_method_variant - PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean, - bfd_vma, boolean)); -static boolean ieee_class_static_method_variant - PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean)); -static boolean ieee_class_end_method PARAMS ((PTR)); -static boolean ieee_end_class_type PARAMS ((PTR)); -static boolean ieee_typedef_type PARAMS ((PTR, const char *)); -static boolean ieee_tag_type - PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind)); -static boolean ieee_typdef PARAMS ((PTR, const char *)); -static boolean ieee_tag PARAMS ((PTR, const char *)); -static boolean ieee_int_constant PARAMS ((PTR, const char *, bfd_vma)); -static boolean ieee_float_constant PARAMS ((PTR, const char *, double)); -static boolean ieee_typed_constant PARAMS ((PTR, const char *, bfd_vma)); -static boolean ieee_variable - PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma)); -static boolean ieee_start_function PARAMS ((PTR, const char *, boolean)); -static boolean ieee_function_parameter - PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma)); -static boolean ieee_start_block PARAMS ((PTR, bfd_vma)); -static boolean ieee_end_block PARAMS ((PTR, bfd_vma)); -static boolean ieee_end_function PARAMS ((PTR)); -static boolean ieee_lineno - PARAMS ((PTR, const char *, unsigned long, bfd_vma)); - -static const struct debug_write_fns ieee_fns = -{ - ieee_start_compilation_unit, - ieee_start_source, - ieee_empty_type, - ieee_void_type, - ieee_int_type, - ieee_float_type, - ieee_complex_type, - ieee_bool_type, - ieee_enum_type, - ieee_pointer_type, - ieee_function_type, - ieee_reference_type, - ieee_range_type, - ieee_array_type, - ieee_set_type, - ieee_offset_type, - ieee_method_type, - ieee_const_type, - ieee_volatile_type, - ieee_start_struct_type, - ieee_struct_field, - ieee_end_struct_type, - ieee_start_class_type, - ieee_class_static_member, - ieee_class_baseclass, - ieee_class_start_method, - ieee_class_method_variant, - ieee_class_static_method_variant, - ieee_class_end_method, - ieee_end_class_type, - ieee_typedef_type, - ieee_tag_type, - ieee_typdef, - ieee_tag, - ieee_int_constant, - ieee_float_constant, - ieee_typed_constant, - ieee_variable, - ieee_start_function, - ieee_function_parameter, - ieee_start_block, - ieee_end_block, - ieee_end_function, - ieee_lineno -}; - -/* Initialize a buffer to be empty. */ - -/*ARGSUSED*/ -static boolean -ieee_init_buffer (info, buflist) - struct ieee_handle *info; - struct ieee_buflist *buflist; -{ - buflist->head = NULL; - buflist->tail = NULL; - return true; -} - -/* See whether a buffer list has any data. */ - -#define ieee_buffer_emptyp(buflist) ((buflist)->head == NULL) - -/* Change the current buffer to a specified buffer chain. */ - -static boolean -ieee_change_buffer (info, buflist) - struct ieee_handle *info; - struct ieee_buflist *buflist; -{ - if (buflist->head == NULL) - { - struct ieee_buf *buf; - - buf = (struct ieee_buf *) xmalloc (sizeof *buf); - buf->next = NULL; - buf->c = 0; - buflist->head = buf; - buflist->tail = buf; - } - - info->current = buflist; - info->curbuf = buflist->tail; - - return true; -} - -/* Append a buffer chain. */ - -/*ARGSUSED*/ -static boolean -ieee_append_buffer (info, mainbuf, newbuf) - struct ieee_handle *info; - struct ieee_buflist *mainbuf; - struct ieee_buflist *newbuf; -{ - if (newbuf->head != NULL) - { - if (mainbuf->head == NULL) - mainbuf->head = newbuf->head; - else - mainbuf->tail->next = newbuf->head; - mainbuf->tail = newbuf->tail; - } - return true; -} - -/* Write a byte into the buffer. We use a macro for speed and a - function for the complex cases. */ - -#define ieee_write_byte(info, b) \ - ((info)->curbuf->c < IEEE_BUFSIZE \ - ? ((info)->curbuf->buf[(info)->curbuf->c++] = (b), true) \ - : ieee_real_write_byte ((info), (b))) - -static boolean -ieee_real_write_byte (info, b) - struct ieee_handle *info; - int b; -{ - if (info->curbuf->c >= IEEE_BUFSIZE) - { - struct ieee_buf *n; - - n = (struct ieee_buf *) xmalloc (sizeof *n); - n->next = NULL; - n->c = 0; - if (info->current->head == NULL) - info->current->head = n; - else - info->current->tail->next = n; - info->current->tail = n; - info->curbuf = n; - } - - info->curbuf->buf[info->curbuf->c] = b; - ++info->curbuf->c; - - return true; -} - -/* Write out two bytes. */ - -static boolean -ieee_write_2bytes (info, i) - struct ieee_handle *info; - int i; -{ - return (ieee_write_byte (info, i >> 8) - && ieee_write_byte (info, i & 0xff)); -} - -/* Write out an integer. */ - -static boolean -ieee_write_number (info, v) - struct ieee_handle *info; - bfd_vma v; -{ - bfd_vma t; - bfd_byte ab[20]; - bfd_byte *p; - unsigned int c; - - if (v <= (bfd_vma) ieee_number_end_enum) - return ieee_write_byte (info, (int) v); - - t = v; - p = ab + sizeof ab; - while (t != 0) - { - *--p = t & 0xff; - t >>= 8; - } - c = (ab + 20) - p; - - if (c > (unsigned int) (ieee_number_repeat_end_enum - - ieee_number_repeat_start_enum)) - { - fprintf (stderr, "IEEE numeric overflow: 0x"); - fprintf_vma (stderr, v); - fprintf (stderr, "\n"); - return false; - } - - if (! ieee_write_byte (info, (int) ieee_number_repeat_start_enum + c)) - return false; - for (; c > 0; --c, ++p) - { - if (! ieee_write_byte (info, *p)) - return false; - } - - return true; -} - -/* Write out a string. */ - -static boolean -ieee_write_id (info, s) - struct ieee_handle *info; - const char *s; -{ - unsigned int len; - - len = strlen (s); - if (len <= 0x7f) - { - if (! ieee_write_byte (info, len)) - return false; - } - else if (len <= 0xff) - { - if (! ieee_write_byte (info, (int) ieee_extension_length_1_enum) - || ! ieee_write_byte (info, len)) - return false; - } - else if (len <= 0xffff) - { - if (! ieee_write_byte (info, (int) ieee_extension_length_2_enum) - || ! ieee_write_2bytes (info, len)) - return false; - } - else - { - fprintf (stderr, "IEEE string length overflow: %u\n", len); - return false; - } - - for (; *s != '\0'; s++) - if (! ieee_write_byte (info, *s)) - return false; - - return true; -} - -/* Write out an ASN record. */ - -static boolean -ieee_write_asn (info, indx, val) - struct ieee_handle *info; - unsigned int indx; - bfd_vma val; -{ - return (ieee_write_2bytes (info, (int) ieee_asn_record_enum) - && ieee_write_number (info, indx) - && ieee_write_number (info, val)); -} - -/* Write out an ATN65 record. */ - -static boolean -ieee_write_atn65 (info, indx, s) - struct ieee_handle *info; - unsigned int indx; - const char *s; -{ - return (ieee_write_2bytes (info, (int) ieee_atn_record_enum) - && ieee_write_number (info, indx) - && ieee_write_number (info, 0) - && ieee_write_number (info, 65) - && ieee_write_id (info, s)); -} - -/* Push a type index onto the type stack. */ - -static boolean -ieee_push_type (info, indx, size, unsignedp, localp) - struct ieee_handle *info; - unsigned int indx; - unsigned int size; - boolean unsignedp; - boolean localp; -{ - struct ieee_type_stack *ts; - - ts = (struct ieee_type_stack *) xmalloc (sizeof *ts); - memset (ts, 0, sizeof *ts); - - ts->type.indx = indx; - ts->type.size = size; - ts->type.unsignedp = unsignedp; - ts->type.localp = localp; - - ts->next = info->type_stack; - info->type_stack = ts; - - return true; -} - -/* Pop a type index off the type stack. */ - -static unsigned int -ieee_pop_type (info) - struct ieee_handle *info; -{ - return ieee_pop_type_used (info, true); -} - -/* Pop an unused type index off the type stack. */ - -static void -ieee_pop_unused_type (info) - struct ieee_handle *info; -{ - (void) ieee_pop_type_used (info, false); -} - -/* Pop a used or unused type index off the type stack. */ - -static unsigned int -ieee_pop_type_used (info, used) - struct ieee_handle *info; - boolean used; -{ - struct ieee_type_stack *ts; - unsigned int ret; - - ts = info->type_stack; - assert (ts != NULL); - - /* If this is a function type, and we need it, we need to append the - actual definition to the typedef block now. */ - if (used && ! ieee_buffer_emptyp (&ts->type.fndef)) - { - struct ieee_buflist *buflist; - - if (ts->type.localp) - { - /* Make sure we have started the types block. */ - if (ieee_buffer_emptyp (&info->types)) - { - if (! ieee_change_buffer (info, &info->types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 1) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname)) - return false; - } - buflist = &info->types; - } - else - { - /* Make sure we started the global type block. */ - if (ieee_buffer_emptyp (&info->global_types)) - { - if (! ieee_change_buffer (info, &info->global_types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 2) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "")) - return false; - } - buflist = &info->global_types; - } - - if (! ieee_append_buffer (info, buflist, &ts->type.fndef)) - return false; - } - - ret = ts->type.indx; - info->type_stack = ts->next; - free (ts); - return ret; -} - -/* Add a range of bytes included in the current compilation unit. */ - -static boolean -ieee_add_range (info, global, low, high) - struct ieee_handle *info; - boolean global; - bfd_vma low; - bfd_vma high; -{ - struct ieee_range **plist, *r, **pr; - - if (low == (bfd_vma) -1 || high == (bfd_vma) -1 || low == high) - return true; - - if (global) - plist = &info->global_ranges; - else - plist = &info->ranges; - - for (r = *plist; r != NULL; r = r->next) - { - if (high >= r->low && low <= r->high) - { - /* The new range overlaps r. */ - if (low < r->low) - r->low = low; - if (high > r->high) - r->high = high; - pr = &r->next; - while (*pr != NULL && (*pr)->low <= r->high) - { - struct ieee_range *n; - - if ((*pr)->high > r->high) - r->high = (*pr)->high; - n = (*pr)->next; - free (*pr); - *pr = n; - } - return true; - } - } - - r = (struct ieee_range *) xmalloc (sizeof *r); - memset (r, 0, sizeof *r); - - r->low = low; - r->high = high; - - /* Store the ranges sorted by address. */ - for (pr = plist; *pr != NULL; pr = &(*pr)->next) - if ((*pr)->low > high) - break; - r->next = *pr; - *pr = r; - - return true; -} - -/* Start a new range for which we only have the low address. */ - -static boolean -ieee_start_range (info, low) - struct ieee_handle *info; - bfd_vma low; -{ - struct ieee_range *r; - - r = (struct ieee_range *) xmalloc (sizeof *r); - memset (r, 0, sizeof *r); - r->low = low; - r->next = info->pending_ranges; - info->pending_ranges = r; - return true; -} - -/* Finish a range started by ieee_start_range. */ - -static boolean -ieee_end_range (info, high) - struct ieee_handle *info; - bfd_vma high; -{ - struct ieee_range *r; - bfd_vma low; - - assert (info->pending_ranges != NULL); - r = info->pending_ranges; - low = r->low; - info->pending_ranges = r->next; - free (r); - return ieee_add_range (info, false, low, high); -} - -/* Start defining a type. */ - -static boolean -ieee_define_type (info, size, unsignedp, localp) - struct ieee_handle *info; - unsigned int size; - boolean unsignedp; - boolean localp; -{ - return ieee_define_named_type (info, (const char *) NULL, - (unsigned int) -1, size, unsignedp, - localp, (struct ieee_buflist *) NULL); -} - -/* Start defining a named type. */ - -static boolean -ieee_define_named_type (info, name, indx, size, unsignedp, localp, buflist) - struct ieee_handle *info; - const char *name; - unsigned int indx; - unsigned int size; - boolean unsignedp; - boolean localp; - struct ieee_buflist *buflist; -{ - unsigned int type_indx; - unsigned int name_indx; - - if (indx != (unsigned int) -1) - type_indx = indx; - else - { - type_indx = info->type_indx; - ++info->type_indx; - } - - name_indx = info->name_indx; - ++info->name_indx; - - if (name == NULL) - name = ""; - - /* If we were given a buffer, use it; otherwise, use either the - local or the global type information, and make sure that the type - block is started. */ - if (buflist != NULL) - { - if (! ieee_change_buffer (info, buflist)) - return false; - } - else if (localp) - { - if (! ieee_buffer_emptyp (&info->types)) - { - if (! ieee_change_buffer (info, &info->types)) - return false; - } - else - { - if (! ieee_change_buffer (info, &info->types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 1) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname)) - return false; - } - } - else - { - if (! ieee_buffer_emptyp (&info->global_types)) - { - if (! ieee_change_buffer (info, &info->global_types)) - return false; - } - else - { - if (! ieee_change_buffer (info, &info->global_types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 2) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "")) - return false; - } - } - - /* Push the new type on the type stack, write out an NN record, and - write out the start of a TY record. The caller will then finish - the TY record. */ - if (! ieee_push_type (info, type_indx, size, unsignedp, localp)) - return false; - - return (ieee_write_byte (info, (int) ieee_nn_record) - && ieee_write_number (info, name_indx) - && ieee_write_id (info, name) - && ieee_write_byte (info, (int) ieee_ty_record_enum) - && ieee_write_number (info, type_indx) - && ieee_write_byte (info, 0xce) - && ieee_write_number (info, name_indx)); -} - -/* Get an entry to the list of modified versions of a type. */ - -static struct ieee_modified_type * -ieee_get_modified_info (info, indx) - struct ieee_handle *info; - unsigned int indx; -{ - if (indx >= info->modified_alloc) - { - unsigned int nalloc; - - nalloc = info->modified_alloc; - if (nalloc == 0) - nalloc = 16; - while (indx >= nalloc) - nalloc *= 2; - info->modified = ((struct ieee_modified_type *) - xrealloc (info->modified, - nalloc * sizeof *info->modified)); - memset (info->modified + info->modified_alloc, 0, - (nalloc - info->modified_alloc) * sizeof *info->modified); - info->modified_alloc = nalloc; - } - - return info->modified + indx; -} - -/* Routines for the hash table mapping names to types. */ - -/* Initialize an entry in the hash table. */ - -static struct bfd_hash_entry * -ieee_name_type_newfunc (entry, table, string) - struct bfd_hash_entry *entry; - struct bfd_hash_table *table; - const char *string; -{ - struct ieee_name_type_hash_entry *ret = - (struct ieee_name_type_hash_entry *) entry; - - /* Allocate the structure if it has not already been allocated by a - subclass. */ - if (ret == NULL) - ret = ((struct ieee_name_type_hash_entry *) - bfd_hash_allocate (table, sizeof *ret)); - if (ret == NULL) - return NULL; - - /* Call the allocation method of the superclass. */ - ret = ((struct ieee_name_type_hash_entry *) - bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); - if (ret) - { - /* Set local fields. */ - ret->types = NULL; - } - - return (struct bfd_hash_entry *) ret; -} - -/* Look up an entry in the hash table. */ - -#define ieee_name_type_hash_lookup(table, string, create, copy) \ - ((struct ieee_name_type_hash_entry *) \ - bfd_hash_lookup (&(table)->root, (string), (create), (copy))) - -/* Traverse the hash table. */ - -#define ieee_name_type_hash_traverse(table, func, info) \ - (bfd_hash_traverse \ - (&(table)->root, \ - (boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \ - (info))) - -/* The general routine to write out IEEE debugging information. */ - -boolean -write_ieee_debugging_info (abfd, dhandle) - bfd *abfd; - PTR dhandle; -{ - struct ieee_handle info; - asection *s; - const char *err; - struct ieee_buf *b; - - memset (&info, 0, sizeof info); - info.abfd = abfd; - info.type_indx = 256; - info.name_indx = 32; - - if (! bfd_hash_table_init (&info.typedefs.root, ieee_name_type_newfunc) - || ! bfd_hash_table_init (&info.tags.root, ieee_name_type_newfunc)) - return false; - - if (! ieee_init_buffer (&info, &info.global_types) - || ! ieee_init_buffer (&info, &info.data) - || ! ieee_init_buffer (&info, &info.types) - || ! ieee_init_buffer (&info, &info.vars) - || ! ieee_init_buffer (&info, &info.cxx) - || ! ieee_init_buffer (&info, &info.linenos) - || ! ieee_init_buffer (&info, &info.fntype) - || ! ieee_init_buffer (&info, &info.fnargs)) - return false; - - if (! debug_write (dhandle, &ieee_fns, (PTR) &info)) - return false; - - if (info.filename != NULL) - { - if (! ieee_finish_compilation_unit (&info)) - return false; - } - - /* Put any undefined tags in the global typedef information. */ - info.error = false; - ieee_name_type_hash_traverse (&info.tags, - ieee_write_undefined_tag, - (PTR) &info); - if (info.error) - return false; - - /* Prepend the global typedef information to the other data. */ - if (! ieee_buffer_emptyp (&info.global_types)) - { - /* The HP debugger seems to have a bug in which it ignores the - last entry in the global types, so we add a dummy entry. */ - if (! ieee_change_buffer (&info, &info.global_types) - || ! ieee_write_byte (&info, (int) ieee_nn_record) - || ! ieee_write_number (&info, info.name_indx) - || ! ieee_write_id (&info, "") - || ! ieee_write_byte (&info, (int) ieee_ty_record_enum) - || ! ieee_write_number (&info, info.type_indx) - || ! ieee_write_byte (&info, 0xce) - || ! ieee_write_number (&info, info.name_indx) - || ! ieee_write_number (&info, 'P') - || ! ieee_write_number (&info, (int) builtin_void + 32) - || ! ieee_write_byte (&info, (int) ieee_be_record_enum)) - return false; - - if (! ieee_append_buffer (&info, &info.global_types, &info.data)) - return false; - info.data = info.global_types; - } - - /* Make sure that we have declare BB11 blocks for each range in the - file. They are added to info->vars. */ - info.error = false; - if (! ieee_init_buffer (&info, &info.vars)) - return false; - bfd_map_over_sections (abfd, ieee_add_bb11_blocks, (PTR) &info); - if (info.error) - return false; - if (! ieee_buffer_emptyp (&info.vars)) - { - if (! ieee_change_buffer (&info, &info.vars) - || ! ieee_write_byte (&info, (int) ieee_be_record_enum)) - return false; - - if (! ieee_append_buffer (&info, &info.data, &info.vars)) - return false; - } - - /* Now all the data is in info.data. Write it out to the BFD. We - normally would need to worry about whether all the other sections - are set up yet, but the IEEE backend will handle this particular - case correctly regardless. */ - if (ieee_buffer_emptyp (&info.data)) - { - /* There is no debugging information. */ - return true; - } - err = NULL; - s = bfd_make_section (abfd, ".debug"); - if (s == NULL) - err = "bfd_make_section"; - if (err == NULL) - { - if (! bfd_set_section_flags (abfd, s, SEC_DEBUGGING | SEC_HAS_CONTENTS)) - err = "bfd_set_section_flags"; - } - if (err == NULL) - { - bfd_size_type size; - - size = 0; - for (b = info.data.head; b != NULL; b = b->next) - size += b->c; - if (! bfd_set_section_size (abfd, s, size)) - err = "bfd_set_section_size"; - } - if (err == NULL) - { - file_ptr offset; - - offset = 0; - for (b = info.data.head; b != NULL; b = b->next) - { - if (! bfd_set_section_contents (abfd, s, b->buf, offset, b->c)) - { - err = "bfd_set_section_contents"; - break; - } - offset += b->c; - } - } - - if (err != NULL) - { - fprintf (stderr, "%s: %s: %s\n", bfd_get_filename (abfd), err, - bfd_errmsg (bfd_get_error ())); - return false; - } - - bfd_hash_table_free (&info.typedefs.root); - bfd_hash_table_free (&info.tags.root); - - return true; -} - -/* Write out information for an undefined tag. This is called via - ieee_name_type_hash_traverse. */ - -static boolean -ieee_write_undefined_tag (h, p) - struct ieee_name_type_hash_entry *h; - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - struct ieee_name_type *nt; - - for (nt = h->types; nt != NULL; nt = nt->next) - { - unsigned int name_indx; - char code; - - if (nt->kind == DEBUG_KIND_ILLEGAL) - continue; - - if (ieee_buffer_emptyp (&info->global_types)) - { - if (! ieee_change_buffer (info, &info->global_types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 2) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "")) - { - info->error = true; - return false; - } - } - else - { - if (! ieee_change_buffer (info, &info->global_types)) - { - info->error = true; - return false; - } - } - - name_indx = info->name_indx; - ++info->name_indx; - if (! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, name_indx) - || ! ieee_write_id (info, nt->type.name) - || ! ieee_write_byte (info, (int) ieee_ty_record_enum) - || ! ieee_write_number (info, nt->type.indx) - || ! ieee_write_byte (info, 0xce) - || ! ieee_write_number (info, name_indx)) - { - info->error = true; - return false; - } - - switch (nt->kind) - { - default: - abort (); - info->error = true; - return false; - case DEBUG_KIND_STRUCT: - case DEBUG_KIND_CLASS: - code = 'S'; - break; - case DEBUG_KIND_UNION: - case DEBUG_KIND_UNION_CLASS: - code = 'U'; - break; - case DEBUG_KIND_ENUM: - code = 'E'; - break; - } - if (! ieee_write_number (info, code) - || ! ieee_write_number (info, 0)) - { - info->error = true; - return false; - } - } - - return true; -} - -/* Start writing out information for a compilation unit. */ - -static boolean -ieee_start_compilation_unit (p, filename) - PTR p; - const char *filename; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - const char *modname; - char *c, *s; - unsigned int nindx; - - if (info->filename != NULL) - { - if (! ieee_finish_compilation_unit (info)) - return false; - } - - info->filename = filename; - modname = strrchr (filename, '/'); - if (modname != NULL) - ++modname; - else - { - modname = strrchr (filename, '\\'); - if (modname != NULL) - ++modname; - else - modname = filename; - } - c = xstrdup (modname); - s = strrchr (c, '.'); - if (s != NULL) - *s = '\0'; - info->modname = c; - - if (! ieee_init_buffer (info, &info->types) - || ! ieee_init_buffer (info, &info->vars) - || ! ieee_init_buffer (info, &info->cxx) - || ! ieee_init_buffer (info, &info->linenos)) - return false; - info->ranges = NULL; - - /* Always include a BB1 and a BB3 block. That is what the output of - the MRI linker seems to look like. */ - if (! ieee_change_buffer (info, &info->types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 1) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname)) - return false; - - nindx = info->name_indx; - ++info->name_indx; - if (! ieee_change_buffer (info, &info->vars) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 3) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname)) - return false; - - return true; -} - -/* Finish up a compilation unit. */ - -static boolean -ieee_finish_compilation_unit (info) - struct ieee_handle *info; -{ - struct ieee_range *r; - - if (! ieee_buffer_emptyp (&info->types)) - { - if (! ieee_change_buffer (info, &info->types) - || ! ieee_write_byte (info, (int) ieee_be_record_enum)) - return false; - } - - if (! ieee_buffer_emptyp (&info->cxx)) - { - /* Append any C++ information to the global function and - variable information. */ - assert (! ieee_buffer_emptyp (&info->vars)); - if (! ieee_change_buffer (info, &info->vars)) - return false; - - /* We put the pmisc records in a dummy procedure, just as the - MRI compiler does. */ - if (! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 6) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "__XRYCPP") - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, info->highaddr - 1) - || ! ieee_append_buffer (info, &info->vars, &info->cxx) - || ! ieee_change_buffer (info, &info->vars) - || ! ieee_write_byte (info, (int) ieee_be_record_enum) - || ! ieee_write_number (info, info->highaddr - 1)) - return false; - } - - if (! ieee_buffer_emptyp (&info->vars)) - { - if (! ieee_change_buffer (info, &info->vars) - || ! ieee_write_byte (info, (int) ieee_be_record_enum)) - return false; - } - - if (info->pending_lineno_filename != NULL) - { - /* Force out the pending line number. */ - if (! ieee_lineno ((PTR) info, (const char *) NULL, 0, (bfd_vma) -1)) - return false; - } - if (! ieee_buffer_emptyp (&info->linenos)) - { - if (! ieee_change_buffer (info, &info->linenos) - || ! ieee_write_byte (info, (int) ieee_be_record_enum)) - return false; - if (strcmp (info->filename, info->lineno_filename) != 0) - { - /* We were not in the main file. We just closed the - included line number block, and now we must close the - main line number block. */ - if (! ieee_write_byte (info, (int) ieee_be_record_enum)) - return false; - } - } - - if (! ieee_append_buffer (info, &info->data, &info->types) - || ! ieee_append_buffer (info, &info->data, &info->vars) - || ! ieee_append_buffer (info, &info->data, &info->linenos)) - return false; - - /* Build BB10/BB11 blocks based on the ranges we recorded. */ - if (! ieee_change_buffer (info, &info->data)) - return false; - - if (! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 10) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname) - || ! ieee_write_id (info, "") - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "GNU objcopy")) - return false; - - for (r = info->ranges; r != NULL; r = r->next) - { - bfd_vma low, high; - asection *s; - int kind; - - low = r->low; - high = r->high; - - /* Find the section corresponding to this range. */ - for (s = info->abfd->sections; s != NULL; s = s->next) - { - if (bfd_get_section_vma (info->abfd, s) <= low - && high <= (bfd_get_section_vma (info->abfd, s) - + bfd_section_size (info->abfd, s))) - break; - } - - if (s == NULL) - { - /* Just ignore this range. */ - continue; - } - - /* Coalesce ranges if it seems reasonable. */ - while (r->next != NULL - && high + 0x1000 >= r->next->low - && (r->next->high - <= (bfd_get_section_vma (info->abfd, s) - + bfd_section_size (info->abfd, s)))) - { - r = r->next; - high = r->high; - } - - if ((s->flags & SEC_CODE) != 0) - kind = 1; - else if ((s->flags & SEC_READONLY) != 0) - kind = 3; - else - kind = 2; - - if (! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 11) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "") - || ! ieee_write_number (info, kind) - || ! ieee_write_number (info, s->index + IEEE_SECTION_NUMBER_BASE) - || ! ieee_write_number (info, low) - || ! ieee_write_byte (info, (int) ieee_be_record_enum) - || ! ieee_write_number (info, high - low)) - return false; - - /* Add this range to the list of global ranges. */ - if (! ieee_add_range (info, true, low, high)) - return false; - } - - if (! ieee_write_byte (info, (int) ieee_be_record_enum)) - return false; - - return true; -} - -/* Add BB11 blocks describing each range that we have not already - described. */ - -static void -ieee_add_bb11_blocks (abfd, sec, data) - bfd *abfd; - asection *sec; - PTR data; -{ - struct ieee_handle *info = (struct ieee_handle *) data; - bfd_vma low, high; - struct ieee_range *r; - - low = bfd_get_section_vma (abfd, sec); - high = low + bfd_section_size (abfd, sec); - - /* Find the first range at or after this section. The ranges are - sorted by address. */ - for (r = info->global_ranges; r != NULL; r = r->next) - if (r->high > low) - break; - - while (low < high) - { - if (r == NULL || r->low >= high) - { - if (! ieee_add_bb11 (info, sec, low, high)) - info->error = true; - return; - } - - if (low < r->low - && r->low - low > 0x100) - { - if (! ieee_add_bb11 (info, sec, low, r->low)) - { - info->error = true; - return; - } - } - low = r->high; - - r = r->next; - } -} - -/* Add a single BB11 block for a range. We add it to info->vars. */ - -static boolean -ieee_add_bb11 (info, sec, low, high) - struct ieee_handle *info; - asection *sec; - bfd_vma low; - bfd_vma high; -{ - int kind; - - if (! ieee_buffer_emptyp (&info->vars)) - { - if (! ieee_change_buffer (info, &info->vars)) - return false; - } - else - { - const char *filename, *modname; - char *c, *s; - - /* Start the enclosing BB10 block. */ - filename = bfd_get_filename (info->abfd); - modname = strrchr (filename, '/'); - if (modname != NULL) - ++modname; - else - { - modname = strrchr (filename, '\\'); - if (modname != NULL) - ++modname; - else - modname = filename; - } - c = xstrdup (modname); - s = strrchr (c, '.'); - if (s != NULL) - *s = '\0'; - - if (! ieee_change_buffer (info, &info->vars) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 10) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, c) - || ! ieee_write_id (info, "") - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "GNU objcopy")) - return false; - - free (c); - } - - if ((sec->flags & SEC_CODE) != 0) - kind = 1; - else if ((sec->flags & SEC_READONLY) != 0) - kind = 3; - else - kind = 2; - - if (! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 11) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "") - || ! ieee_write_number (info, kind) - || ! ieee_write_number (info, sec->index + IEEE_SECTION_NUMBER_BASE) - || ! ieee_write_number (info, low) - || ! ieee_write_byte (info, (int) ieee_be_record_enum) - || ! ieee_write_number (info, high - low)) - return false; - - return true; -} - -/* Start recording information from a particular source file. This is - used to record which file defined which types, variables, etc. It - is not used for line numbers, since the lineno entry point passes - down the file name anyhow. IEEE debugging information doesn't seem - to store this information anywhere. */ - -/*ARGSUSED*/ -static boolean -ieee_start_source (p, filename) - PTR p; - const char *filename; -{ - return true; -} - -/* Make an empty type. */ - -static boolean -ieee_empty_type (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - return ieee_push_type (info, (int) builtin_unknown, 0, false, false); -} - -/* Make a void type. */ - -static boolean -ieee_void_type (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - return ieee_push_type (info, (int) builtin_void, 0, false, false); -} - -/* Make an integer type. */ - -static boolean -ieee_int_type (p, size, unsignedp) - PTR p; - unsigned int size; - boolean unsignedp; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int indx; - - switch (size) - { - case 1: - indx = (int) builtin_signed_char; - break; - case 2: - indx = (int) builtin_signed_short_int; - break; - case 4: - indx = (int) builtin_signed_long; - break; - case 8: - indx = (int) builtin_signed_long_long; - break; - default: - fprintf (stderr, "IEEE unsupported integer type size %u\n", size); - return false; - } - - if (unsignedp) - ++indx; - - return ieee_push_type (info, indx, size, unsignedp, false); -} - -/* Make a floating point type. */ - -static boolean -ieee_float_type (p, size) - PTR p; - unsigned int size; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int indx; - - switch (size) - { - case 4: - indx = (int) builtin_float; - break; - case 8: - indx = (int) builtin_double; - break; - case 12: - /* FIXME: This size really depends upon the processor. */ - indx = (int) builtin_long_double; - break; - case 16: - indx = (int) builtin_long_long_double; - break; - default: - fprintf (stderr, "IEEE unsupported float type size %u\n", size); - return false; - } - - return ieee_push_type (info, indx, size, false, false); -} - -/* Make a complex type. */ - -static boolean -ieee_complex_type (p, size) - PTR p; - unsigned int size; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - char code; - - switch (size) - { - case 4: - if (info->complex_float_index != 0) - return ieee_push_type (info, info->complex_float_index, size * 2, - false, false); - code = 'c'; - break; - case 12: - case 16: - /* These cases can be output by gcc -gstabs. Outputting the - wrong type is better than crashing. */ - case 8: - if (info->complex_double_index != 0) - return ieee_push_type (info, info->complex_double_index, size * 2, - false, false); - code = 'd'; - break; - default: - fprintf (stderr, "IEEE unsupported complex type size %u\n", size); - return false; - } - - /* FIXME: I don't know what the string is for. */ - if (! ieee_define_type (info, size * 2, false, false) - || ! ieee_write_number (info, code) - || ! ieee_write_id (info, "")) - return false; - - if (size == 4) - info->complex_float_index = info->type_stack->type.indx; - else - info->complex_double_index = info->type_stack->type.indx; - - return true; -} - -/* Make a boolean type. IEEE doesn't support these, so we just make - an integer type instead. */ - -static boolean -ieee_bool_type (p, size) - PTR p; - unsigned int size; -{ - return ieee_int_type (p, size, true); -} - -/* Make an enumeration. */ - -static boolean -ieee_enum_type (p, tag, names, vals) - PTR p; - const char *tag; - const char **names; - bfd_signed_vma *vals; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - struct ieee_defined_enum *e; - boolean localp, simple; - unsigned int indx; - int i = 0; - - localp = false; - indx = (unsigned int) -1; - for (e = info->enums; e != NULL; e = e->next) - { - if (tag == NULL) - { - if (e->tag != NULL) - continue; - } - else - { - if (e->tag == NULL - || tag[0] != e->tag[0] - || strcmp (tag, e->tag) != 0) - continue; - } - - if (! e->defined) - { - /* This enum tag has been seen but not defined. */ - indx = e->indx; - break; - } - - if (names != NULL && e->names != NULL) - { - for (i = 0; names[i] != NULL && e->names[i] != NULL; i++) - { - if (names[i][0] != e->names[i][0] - || vals[i] != e->vals[i] - || strcmp (names[i], e->names[i]) != 0) - break; - } - } - - if ((names == NULL && e->names == NULL) - || (names != NULL - && e->names != NULL - && names[i] == NULL - && e->names[i] == NULL)) - { - /* We've seen this enum before. */ - return ieee_push_type (info, e->indx, 0, true, false); - } - - if (tag != NULL) - { - /* We've already seen an enum of the same name, so we must make - sure to output this one locally. */ - localp = true; - break; - } - } - - /* If this is a simple enumeration, in which the values start at 0 - and always increment by 1, we can use type E. Otherwise we must - use type N. */ - - simple = true; - if (names != NULL) - { - for (i = 0; names[i] != NULL; i++) - { - if (vals[i] != i) - { - simple = false; - break; - } - } - } - - if (! ieee_define_named_type (info, tag, indx, 0, true, localp, - (struct ieee_buflist *) NULL) - || ! ieee_write_number (info, simple ? 'E' : 'N')) - return false; - if (simple) - { - /* FIXME: This is supposed to be the enumeration size, but we - don't store that. */ - if (! ieee_write_number (info, 4)) - return false; - } - if (names != NULL) - { - for (i = 0; names[i] != NULL; i++) - { - if (! ieee_write_id (info, names[i])) - return false; - if (! simple) - { - if (! ieee_write_number (info, vals[i])) - return false; - } - } - } - - if (! localp) - { - if (indx == (unsigned int) -1) - { - e = (struct ieee_defined_enum *) xmalloc (sizeof *e); - memset (e, 0, sizeof *e); - e->indx = info->type_stack->type.indx; - e->tag = tag; - - e->next = info->enums; - info->enums = e; - } - - e->names = names; - e->vals = vals; - e->defined = true; - } - - return true; -} - -/* Make a pointer type. */ - -static boolean -ieee_pointer_type (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - boolean localp; - unsigned int indx; - struct ieee_modified_type *m = NULL; - - localp = info->type_stack->type.localp; - indx = ieee_pop_type (info); - - /* A pointer to a simple builtin type can be obtained by adding 32. - FIXME: Will this be a short pointer, and will that matter? */ - if (indx < 32) - return ieee_push_type (info, indx + 32, 0, true, false); - - if (! localp) - { - m = ieee_get_modified_info (p, indx); - if (m == NULL) - return false; - - /* FIXME: The size should depend upon the architecture. */ - if (m->pointer > 0) - return ieee_push_type (info, m->pointer, 4, true, false); - } - - if (! ieee_define_type (info, 4, true, localp) - || ! ieee_write_number (info, 'P') - || ! ieee_write_number (info, indx)) - return false; - - if (! localp) - m->pointer = info->type_stack->type.indx; - - return true; -} - -/* Make a function type. This will be called for a method, but we - don't want to actually add it to the type table in that case. We - handle this by defining the type in a private buffer, and only - adding that buffer to the typedef block if we are going to use it. */ - -static boolean -ieee_function_type (p, argcount, varargs) - PTR p; - int argcount; - boolean varargs; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - boolean localp; - unsigned int *args = NULL; - int i; - unsigned int retindx; - struct ieee_buflist fndef; - struct ieee_modified_type *m; - - localp = false; - - if (argcount > 0) - { - args = (unsigned int *) xmalloc (argcount * sizeof *args); - for (i = argcount - 1; i >= 0; i--) - { - if (info->type_stack->type.localp) - localp = true; - args[i] = ieee_pop_type (info); - } - } - else if (argcount < 0) - varargs = false; - - if (info->type_stack->type.localp) - localp = true; - retindx = ieee_pop_type (info); - - m = NULL; - if (argcount < 0 && ! localp) - { - m = ieee_get_modified_info (p, retindx); - if (m == NULL) - return false; - - if (m->function > 0) - return ieee_push_type (info, m->function, 0, true, false); - } - - /* An attribute of 0x41 means that the frame and push mask are - unknown. */ - if (! ieee_init_buffer (info, &fndef) - || ! ieee_define_named_type (info, (const char *) NULL, - (unsigned int) -1, 0, true, localp, - &fndef) - || ! ieee_write_number (info, 'x') - || ! ieee_write_number (info, 0x41) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, retindx) - || ! ieee_write_number (info, (bfd_vma) argcount + (varargs ? 1 : 0))) - return false; - if (argcount > 0) - { - for (i = 0; i < argcount; i++) - if (! ieee_write_number (info, args[i])) - return false; - free (args); - } - if (varargs) - { - /* A varargs function is represented by writing out the last - argument as type void *, although this makes little sense. */ - if (! ieee_write_number (info, (bfd_vma) builtin_void + 32)) - return false; - } - - if (! ieee_write_number (info, 0)) - return false; - - /* We wrote the information into fndef, in case we don't need it. - It will be appended to info->types by ieee_pop_type. */ - info->type_stack->type.fndef = fndef; - - if (m != NULL) - m->function = info->type_stack->type.indx; - - return true; -} - -/* Make a reference type. */ - -static boolean -ieee_reference_type (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - /* IEEE appears to record a normal pointer type, and then use a - pmisc record to indicate that it is really a reference. */ - - if (! ieee_pointer_type (p)) - return false; - info->type_stack->type.referencep = true; - return true; -} - -/* Make a range type. */ - -static boolean -ieee_range_type (p, low, high) - PTR p; - bfd_signed_vma low; - bfd_signed_vma high; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int size; - boolean unsignedp, localp; - - size = info->type_stack->type.size; - unsignedp = info->type_stack->type.unsignedp; - localp = info->type_stack->type.localp; - ieee_pop_unused_type (info); - return (ieee_define_type (info, size, unsignedp, localp) - && ieee_write_number (info, 'R') - && ieee_write_number (info, (bfd_vma) low) - && ieee_write_number (info, (bfd_vma) high) - && ieee_write_number (info, unsignedp ? 0 : 1) - && ieee_write_number (info, size)); -} - -/* Make an array type. */ - -/*ARGSUSED*/ -static boolean -ieee_array_type (p, low, high, stringp) - PTR p; - bfd_signed_vma low; - bfd_signed_vma high; - boolean stringp; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int eleindx; - boolean localp; - unsigned int size; - struct ieee_modified_type *m = NULL; - struct ieee_modified_array_type *a; - - /* IEEE does not store the range, so we just ignore it. */ - ieee_pop_unused_type (info); - localp = info->type_stack->type.localp; - size = info->type_stack->type.size; - eleindx = ieee_pop_type (info); - - /* If we don't know the range, treat the size as exactly one - element. */ - if (low < high) - size *= (high - low) + 1; - - if (! localp) - { - m = ieee_get_modified_info (info, eleindx); - if (m == NULL) - return false; - - for (a = m->arrays; a != NULL; a = a->next) - { - if (a->low == low && a->high == high) - return ieee_push_type (info, a->indx, size, false, false); - } - } - - if (! ieee_define_type (info, size, false, localp) - || ! ieee_write_number (info, low == 0 ? 'Z' : 'C') - || ! ieee_write_number (info, eleindx)) - return false; - if (low != 0) - { - if (! ieee_write_number (info, low)) - return false; - } - - if (! ieee_write_number (info, high + 1)) - return false; - - if (! localp) - { - a = (struct ieee_modified_array_type *) xmalloc (sizeof *a); - memset (a, 0, sizeof *a); - - a->indx = info->type_stack->type.indx; - a->low = low; - a->high = high; - - a->next = m->arrays; - m->arrays = a; - } - - return true; -} - -/* Make a set type. */ - -static boolean -ieee_set_type (p, bitstringp) - PTR p; - boolean bitstringp; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - boolean localp; - unsigned int eleindx; - - localp = info->type_stack->type.localp; - eleindx = ieee_pop_type (info); - - /* FIXME: We don't know the size, so we just use 4. */ - - return (ieee_define_type (info, 0, true, localp) - && ieee_write_number (info, 's') - && ieee_write_number (info, 4) - && ieee_write_number (info, eleindx)); -} - -/* Make an offset type. */ - -static boolean -ieee_offset_type (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int targetindx, baseindx; - - targetindx = ieee_pop_type (info); - baseindx = ieee_pop_type (info); - - /* FIXME: The MRI C++ compiler does not appear to generate any - useful type information about an offset type. It just records a - pointer to member as an integer. The MRI/HP IEEE spec does - describe a pmisc record which can be used for a pointer to - member. Unfortunately, it does not describe the target type, - which seems pretty important. I'm going to punt this for now. */ - - return ieee_int_type (p, 4, true); -} - -/* Make a method type. */ - -static boolean -ieee_method_type (p, domain, argcount, varargs) - PTR p; - boolean domain; - int argcount; - boolean varargs; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - /* FIXME: The MRI/HP IEEE spec defines a pmisc record to use for a - method, but the definition is incomplete. We just output an 'x' - type. */ - - if (domain) - ieee_pop_unused_type (info); - - return ieee_function_type (p, argcount, varargs); -} - -/* Make a const qualified type. */ - -static boolean -ieee_const_type (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int size; - boolean unsignedp, localp; - unsigned int indx; - struct ieee_modified_type *m = NULL; - - size = info->type_stack->type.size; - unsignedp = info->type_stack->type.unsignedp; - localp = info->type_stack->type.localp; - indx = ieee_pop_type (info); - - if (! localp) - { - m = ieee_get_modified_info (info, indx); - if (m == NULL) - return false; - - if (m->const_qualified > 0) - return ieee_push_type (info, m->const_qualified, size, unsignedp, - false); - } - - if (! ieee_define_type (info, size, unsignedp, localp) - || ! ieee_write_number (info, 'n') - || ! ieee_write_number (info, 1) - || ! ieee_write_number (info, indx)) - return false; - - if (! localp) - m->const_qualified = info->type_stack->type.indx; - - return true; -} - -/* Make a volatile qualified type. */ - -static boolean -ieee_volatile_type (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int size; - boolean unsignedp, localp; - unsigned int indx; - struct ieee_modified_type *m = NULL; - - size = info->type_stack->type.size; - unsignedp = info->type_stack->type.unsignedp; - localp = info->type_stack->type.localp; - indx = ieee_pop_type (info); - - if (! localp) - { - m = ieee_get_modified_info (info, indx); - if (m == NULL) - return false; - - if (m->volatile_qualified > 0) - return ieee_push_type (info, m->volatile_qualified, size, unsignedp, - false); - } - - if (! ieee_define_type (info, size, unsignedp, localp) - || ! ieee_write_number (info, 'n') - || ! ieee_write_number (info, 2) - || ! ieee_write_number (info, indx)) - return false; - - if (! localp) - m->volatile_qualified = info->type_stack->type.indx; - - return true; -} - -/* Convert an enum debug_visibility into a CXXFLAGS value. */ - -static unsigned int -ieee_vis_to_flags (visibility) - enum debug_visibility visibility; -{ - switch (visibility) - { - default: - abort (); - case DEBUG_VISIBILITY_PUBLIC: - return CXXFLAGS_VISIBILITY_PUBLIC; - case DEBUG_VISIBILITY_PRIVATE: - return CXXFLAGS_VISIBILITY_PRIVATE; - case DEBUG_VISIBILITY_PROTECTED: - return CXXFLAGS_VISIBILITY_PROTECTED; - } - /*NOTREACHED*/ -} - -/* Start defining a struct type. We build it in the strdef field on - the stack, to avoid confusing type definitions required by the - fields with the struct type itself. */ - -static boolean -ieee_start_struct_type (p, tag, id, structp, size) - PTR p; - const char *tag; - unsigned int id; - boolean structp; - unsigned int size; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - boolean localp, ignorep; - boolean copy; - char ab[20]; - const char *look; - struct ieee_name_type_hash_entry *h; - struct ieee_name_type *nt, *ntlook; - struct ieee_buflist strdef; - - localp = false; - ignorep = false; - - /* We need to create a tag for internal use even if we don't want - one for external use. This will let us refer to an anonymous - struct. */ - if (tag != NULL) - { - look = tag; - copy = false; - } - else - { - sprintf (ab, "__anon%u", id); - look = ab; - copy = true; - } - - /* If we already have references to the tag, we must use the - existing type index. */ - h = ieee_name_type_hash_lookup (&info->tags, look, true, copy); - if (h == NULL) - return false; - - nt = NULL; - for (ntlook = h->types; ntlook != NULL; ntlook = ntlook->next) - { - if (ntlook->id == id) - nt = ntlook; - else if (! ntlook->type.localp) - { - /* We are creating a duplicate definition of a globally - defined tag. Force it to be local to avoid - confusion. */ - localp = true; - } - } - - if (nt != NULL) - { - assert (localp == nt->type.localp); - if (nt->kind == DEBUG_KIND_ILLEGAL && ! localp) - { - /* We've already seen a global definition of the type. - Ignore this new definition. */ - ignorep = true; - } - } - else - { - nt = (struct ieee_name_type *) xmalloc (sizeof *nt); - memset (nt, 0, sizeof *nt); - nt->id = id; - nt->type.name = h->root.string; - nt->next = h->types; - h->types = nt; - nt->type.indx = info->type_indx; - ++info->type_indx; - } - - nt->kind = DEBUG_KIND_ILLEGAL; - - if (! ieee_init_buffer (info, &strdef) - || ! ieee_define_named_type (info, tag, nt->type.indx, size, true, - localp, &strdef) - || ! ieee_write_number (info, structp ? 'S' : 'U') - || ! ieee_write_number (info, size)) - return false; - - if (! ignorep) - { - const char *hold; - - /* We never want nt->type.name to be NULL. We want the rest of - the type to be the object set up on the type stack; it will - have a NULL name if tag is NULL. */ - hold = nt->type.name; - nt->type = info->type_stack->type; - nt->type.name = hold; - } - - info->type_stack->type.name = tag; - info->type_stack->type.strdef = strdef; - info->type_stack->type.ignorep = ignorep; - - return true; -} - -/* Add a field to a struct. */ - -static boolean -ieee_struct_field (p, name, bitpos, bitsize, visibility) - PTR p; - const char *name; - bfd_vma bitpos; - bfd_vma bitsize; - enum debug_visibility visibility; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int size; - boolean unsignedp; - boolean referencep; - boolean localp; - unsigned int indx; - bfd_vma offset; - - assert (info->type_stack != NULL - && info->type_stack->next != NULL - && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef)); - - /* If we are ignoring this struct definition, just pop and ignore - the type. */ - if (info->type_stack->next->type.ignorep) - { - ieee_pop_unused_type (info); - return true; - } - - size = info->type_stack->type.size; - unsignedp = info->type_stack->type.unsignedp; - referencep = info->type_stack->type.referencep; - localp = info->type_stack->type.localp; - indx = ieee_pop_type (info); - - if (localp) - info->type_stack->type.localp = true; - - if (info->type_stack->type.classdef != NULL) - { - unsigned int flags; - unsigned int nindx; - - /* This is a class. We must add a description of this field to - the class records we are building. */ - - flags = ieee_vis_to_flags (visibility); - nindx = info->type_stack->type.classdef->indx; - if (! ieee_change_buffer (info, - &info->type_stack->type.classdef->pmiscbuf) - || ! ieee_write_asn (info, nindx, 'd') - || ! ieee_write_asn (info, nindx, flags) - || ! ieee_write_atn65 (info, nindx, name) - || ! ieee_write_atn65 (info, nindx, name)) - return false; - info->type_stack->type.classdef->pmisccount += 4; - - if (referencep) - { - unsigned int nindx; - - /* We need to output a record recording that this field is - really of reference type. We put this on the refs field - of classdef, so that it can be appended to the C++ - records after the class is defined. */ - - nindx = info->name_indx; - ++info->name_indx; - - if (! ieee_change_buffer (info, - &info->type_stack->type.classdef->refs) - || ! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, nindx) - || ! ieee_write_id (info, "") - || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, nindx) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 62) - || ! ieee_write_number (info, 80) - || ! ieee_write_number (info, 4) - || ! ieee_write_asn (info, nindx, 'R') - || ! ieee_write_asn (info, nindx, 3) - || ! ieee_write_atn65 (info, nindx, info->type_stack->type.name) - || ! ieee_write_atn65 (info, nindx, name)) - return false; - } - } - - /* If the bitsize doesn't match the expected size, we need to output - a bitfield type. */ - if (size == 0 || bitsize == 0 || bitsize == size * 8) - offset = bitpos / 8; - else - { - if (! ieee_define_type (info, 0, unsignedp, - info->type_stack->type.localp) - || ! ieee_write_number (info, 'g') - || ! ieee_write_number (info, unsignedp ? 0 : 1) - || ! ieee_write_number (info, bitsize) - || ! ieee_write_number (info, indx)) - return false; - indx = ieee_pop_type (info); - offset = bitpos; - } - - /* Switch to the struct we are building in order to output this - field definition. */ - return (ieee_change_buffer (info, &info->type_stack->type.strdef) - && ieee_write_id (info, name) - && ieee_write_number (info, indx) - && ieee_write_number (info, offset)); -} - -/* Finish up a struct type. */ - -static boolean -ieee_end_struct_type (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - struct ieee_buflist *pb; - - assert (info->type_stack != NULL - && ! ieee_buffer_emptyp (&info->type_stack->type.strdef)); - - /* If we were ignoring this struct definition because it was a - duplicate defintion, just through away whatever bytes we have - accumulated. Leave the type on the stack. */ - if (info->type_stack->type.ignorep) - return true; - - /* If this is not a duplicate definition of this tag, then localp - will be false, and we can put it in the global type block. - FIXME: We should avoid outputting duplicate definitions which are - the same. */ - if (! info->type_stack->type.localp) - { - /* Make sure we have started the global type block. */ - if (ieee_buffer_emptyp (&info->global_types)) - { - if (! ieee_change_buffer (info, &info->global_types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 2) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "")) - return false; - } - pb = &info->global_types; - } - else - { - /* Make sure we have started the types block. */ - if (ieee_buffer_emptyp (&info->types)) - { - if (! ieee_change_buffer (info, &info->types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 1) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname)) - return false; - } - pb = &info->types; - } - - /* Append the struct definition to the types. */ - if (! ieee_append_buffer (info, pb, &info->type_stack->type.strdef) - || ! ieee_init_buffer (info, &info->type_stack->type.strdef)) - return false; - - /* Leave the struct on the type stack. */ - - return true; -} - -/* Start a class type. */ - -static boolean -ieee_start_class_type (p, tag, id, structp, size, vptr, ownvptr) - PTR p; - const char *tag; - unsigned int id; - boolean structp; - unsigned int size; - boolean vptr; - boolean ownvptr; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - const char *vclass; - struct ieee_buflist pmiscbuf; - unsigned int indx; - struct ieee_type_class *classdef; - - /* A C++ class is output as a C++ struct along with a set of pmisc - records describing the class. */ - - /* We need to have a name so that we can associate the struct and - the class. */ - if (tag == NULL) - { - char *t; - - t = (char *) xmalloc (20); - sprintf (t, "__anon%u", id); - tag = t; - } - - /* We can't write out the virtual table information until we have - finished the class, because we don't know the virtual table size. - We get the size from the largest voffset we see. */ - vclass = NULL; - if (vptr && ! ownvptr) - { - vclass = info->type_stack->type.name; - assert (vclass != NULL); - /* We don't call ieee_pop_unused_type, since the class should - get defined. */ - (void) ieee_pop_type (info); - } - - if (! ieee_start_struct_type (p, tag, id, structp, size)) - return false; - - indx = info->name_indx; - ++info->name_indx; - - /* We write out pmisc records into the classdef field. We will - write out the pmisc start after we know the number of records we - need. */ - if (! ieee_init_buffer (info, &pmiscbuf) - || ! ieee_change_buffer (info, &pmiscbuf) - || ! ieee_write_asn (info, indx, 'T') - || ! ieee_write_asn (info, indx, structp ? 'o' : 'u') - || ! ieee_write_atn65 (info, indx, tag)) - return false; - - classdef = (struct ieee_type_class *) xmalloc (sizeof *classdef); - memset (classdef, 0, sizeof *classdef); - - classdef->indx = indx; - classdef->pmiscbuf = pmiscbuf; - classdef->pmisccount = 3; - classdef->vclass = vclass; - classdef->ownvptr = ownvptr; - - info->type_stack->type.classdef = classdef; - - return true; -} - -/* Add a static member to a class. */ - -static boolean -ieee_class_static_member (p, name, physname, visibility) - PTR p; - const char *name; - const char *physname; - enum debug_visibility visibility; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int flags; - unsigned int nindx; - - /* We don't care about the type. Hopefully there will be a call to - ieee_variable declaring the physical name and the type, since - that is where an IEEE consumer must get the type. */ - ieee_pop_unused_type (info); - - assert (info->type_stack != NULL - && info->type_stack->type.classdef != NULL); - - flags = ieee_vis_to_flags (visibility); - flags |= CXXFLAGS_STATIC; - - nindx = info->type_stack->type.classdef->indx; - - if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf) - || ! ieee_write_asn (info, nindx, 'd') - || ! ieee_write_asn (info, nindx, flags) - || ! ieee_write_atn65 (info, nindx, name) - || ! ieee_write_atn65 (info, nindx, physname)) - return false; - info->type_stack->type.classdef->pmisccount += 4; - - return true; -} - -/* Add a base class to a class. */ - -static boolean -ieee_class_baseclass (p, bitpos, virtual, visibility) - PTR p; - bfd_vma bitpos; - boolean virtual; - enum debug_visibility visibility; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - const char *bname; - boolean localp; - unsigned int bindx; - char *fname; - unsigned int flags; - unsigned int nindx; - - assert (info->type_stack != NULL - && info->type_stack->type.name != NULL - && info->type_stack->next != NULL - && info->type_stack->next->type.classdef != NULL - && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef)); - - bname = info->type_stack->type.name; - localp = info->type_stack->type.localp; - bindx = ieee_pop_type (info); - - /* We are currently defining both a struct and a class. We must - write out a field definition in the struct which holds the base - class. The stabs debugging reader will create a field named - _vb$CLASS for a virtual base class, so we just use that. FIXME: - we should not depend upon a detail of stabs debugging. */ - if (virtual) - { - fname = (char *) xmalloc (strlen (bname) + sizeof "_vb$"); - sprintf (fname, "_vb$%s", bname); - flags = BASEFLAGS_VIRTUAL; - } - else - { - if (localp) - info->type_stack->type.localp = true; - - fname = (char *) xmalloc (strlen (bname) + sizeof "_b$"); - sprintf (fname, "_b$%s", bname); - - if (! ieee_change_buffer (info, &info->type_stack->type.strdef) - || ! ieee_write_id (info, fname) - || ! ieee_write_number (info, bindx) - || ! ieee_write_number (info, bitpos / 8)) - return false; - flags = 0; - } - - if (visibility == DEBUG_VISIBILITY_PRIVATE) - flags |= BASEFLAGS_PRIVATE; - - nindx = info->type_stack->type.classdef->indx; - - if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf) - || ! ieee_write_asn (info, nindx, 'b') - || ! ieee_write_asn (info, nindx, flags) - || ! ieee_write_atn65 (info, nindx, bname) - || ! ieee_write_asn (info, nindx, 0) - || ! ieee_write_atn65 (info, nindx, fname)) - return false; - info->type_stack->type.classdef->pmisccount += 5; - - free (fname); - - return true; -} - -/* Start building a method for a class. */ - -static boolean -ieee_class_start_method (p, name) - PTR p; - const char *name; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - assert (info->type_stack != NULL - && info->type_stack->type.classdef != NULL - && info->type_stack->type.classdef->method == NULL); - - info->type_stack->type.classdef->method = name; - - return true; -} - -/* Define a new method variant, either static or not. */ - -static boolean -ieee_class_method_var (info, physname, visibility, staticp, constp, - volatilep, voffset, context) - struct ieee_handle *info; - const char *physname; - enum debug_visibility visibility; - boolean staticp; - boolean constp; - boolean volatilep; - bfd_vma voffset; - boolean context; -{ - unsigned int flags; - unsigned int nindx; - boolean virtual; - - /* We don't need the type of the method. An IEEE consumer which - wants the type must track down the function by the physical name - and get the type from that. */ - ieee_pop_unused_type (info); - - /* We don't use the context. FIXME: We probably ought to use it to - adjust the voffset somehow, but I don't really know how. */ - if (context) - ieee_pop_unused_type (info); - - assert (info->type_stack != NULL - && info->type_stack->type.classdef != NULL - && info->type_stack->type.classdef->method != NULL); - - flags = ieee_vis_to_flags (visibility); - - /* FIXME: We never set CXXFLAGS_OVERRIDE, CXXFLAGS_OPERATOR, - CXXFLAGS_CTORDTOR, CXXFLAGS_CTOR, or CXXFLAGS_INLINE. */ - - if (staticp) - flags |= CXXFLAGS_STATIC; - if (constp) - flags |= CXXFLAGS_CONST; - if (volatilep) - flags |= CXXFLAGS_VOLATILE; - - nindx = info->type_stack->type.classdef->indx; - - virtual = context || voffset > 0; - - if (! ieee_change_buffer (info, - &info->type_stack->type.classdef->pmiscbuf) - || ! ieee_write_asn (info, nindx, virtual ? 'v' : 'm') - || ! ieee_write_asn (info, nindx, flags) - || ! ieee_write_atn65 (info, nindx, - info->type_stack->type.classdef->method) - || ! ieee_write_atn65 (info, nindx, physname)) - return false; - - if (virtual) - { - if (voffset > info->type_stack->type.classdef->voffset) - info->type_stack->type.classdef->voffset = voffset; - if (! ieee_write_asn (info, nindx, voffset)) - return false; - ++info->type_stack->type.classdef->pmisccount; - } - - if (! ieee_write_asn (info, nindx, 0)) - return false; - - info->type_stack->type.classdef->pmisccount += 5; - - return true; -} - -/* Define a new method variant. */ - -static boolean -ieee_class_method_variant (p, physname, visibility, constp, volatilep, - voffset, context) - PTR p; - const char *physname; - enum debug_visibility visibility; - boolean constp; - boolean volatilep; - bfd_vma voffset; - boolean context; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - return ieee_class_method_var (info, physname, visibility, false, constp, - volatilep, voffset, context); -} - -/* Define a new static method variant. */ - -static boolean -ieee_class_static_method_variant (p, physname, visibility, constp, volatilep) - PTR p; - const char *physname; - enum debug_visibility visibility; - boolean constp; - boolean volatilep; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - return ieee_class_method_var (info, physname, visibility, true, constp, - volatilep, 0, false); -} - -/* Finish up a method. */ - -static boolean -ieee_class_end_method (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - assert (info->type_stack != NULL - && info->type_stack->type.classdef != NULL - && info->type_stack->type.classdef->method != NULL); - - info->type_stack->type.classdef->method = NULL; - - return true; -} - -/* Finish up a class. */ - -static boolean -ieee_end_class_type (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int nindx; - - assert (info->type_stack != NULL - && info->type_stack->type.classdef != NULL); - - /* If we were ignoring this class definition because it was a - duplicate definition, just through away whatever bytes we have - accumulated. Leave the type on the stack. */ - if (info->type_stack->type.ignorep) - return true; - - nindx = info->type_stack->type.classdef->indx; - - /* If we have a virtual table, we can write out the information now. */ - if (info->type_stack->type.classdef->vclass != NULL - || info->type_stack->type.classdef->ownvptr) - { - if (! ieee_change_buffer (info, - &info->type_stack->type.classdef->pmiscbuf) - || ! ieee_write_asn (info, nindx, 'z') - || ! ieee_write_atn65 (info, nindx, "") - || ! ieee_write_asn (info, nindx, - info->type_stack->type.classdef->voffset)) - return false; - if (info->type_stack->type.classdef->ownvptr) - { - if (! ieee_write_atn65 (info, nindx, "")) - return false; - } - else - { - if (! ieee_write_atn65 (info, nindx, - info->type_stack->type.classdef->vclass)) - return false; - } - if (! ieee_write_asn (info, nindx, 0)) - return false; - info->type_stack->type.classdef->pmisccount += 5; - } - - /* Now that we know the number of pmisc records, we can write out - the atn62 which starts the pmisc records, and append them to the - C++ buffers. */ - - if (! ieee_change_buffer (info, &info->cxx) - || ! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, nindx) - || ! ieee_write_id (info, "") - || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, nindx) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 62) - || ! ieee_write_number (info, 80) - || ! ieee_write_number (info, - info->type_stack->type.classdef->pmisccount)) - return false; - - if (! ieee_append_buffer (info, &info->cxx, - &info->type_stack->type.classdef->pmiscbuf)) - return false; - if (! ieee_buffer_emptyp (&info->type_stack->type.classdef->refs)) - { - if (! ieee_append_buffer (info, &info->cxx, - &info->type_stack->type.classdef->refs)) - return false; - } - - return ieee_end_struct_type (p); -} - -/* Push a previously seen typedef onto the type stack. */ - -static boolean -ieee_typedef_type (p, name) - PTR p; - const char *name; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - struct ieee_name_type_hash_entry *h; - struct ieee_name_type *nt; - - h = ieee_name_type_hash_lookup (&info->typedefs, name, false, false); - - /* h should never be NULL, since that would imply that the generic - debugging code has asked for a typedef which it has not yet - defined. */ - assert (h != NULL); - - /* We always use the most recently defined type for this name, which - will be the first one on the list. */ - - nt = h->types; - if (! ieee_push_type (info, nt->type.indx, nt->type.size, - nt->type.unsignedp, nt->type.localp)) - return false; - - /* Copy over any other type information we may have. */ - info->type_stack->type = nt->type; - - return true; -} - -/* Push a tagged type onto the type stack. */ - -static boolean -ieee_tag_type (p, name, id, kind) - PTR p; - const char *name; - unsigned int id; - enum debug_type_kind kind; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - boolean localp; - boolean copy; - char ab[20]; - struct ieee_name_type_hash_entry *h; - struct ieee_name_type *nt; - - if (kind == DEBUG_KIND_ENUM) - { - struct ieee_defined_enum *e; - - if (name == NULL) - abort (); - for (e = info->enums; e != NULL; e = e->next) - if (e->tag != NULL && strcmp (e->tag, name) == 0) - return ieee_push_type (info, e->indx, 0, true, false); - - e = (struct ieee_defined_enum *) xmalloc (sizeof *e); - memset (e, 0, sizeof *e); - - e->indx = info->type_indx; - ++info->type_indx; - e->tag = name; - e->defined = false; - - e->next = info->enums; - info->enums = e; - - return ieee_push_type (info, e->indx, 0, true, false); - } - - localp = false; - - copy = false; - if (name == NULL) - { - sprintf (ab, "__anon%u", id); - name = ab; - copy = true; - } - - h = ieee_name_type_hash_lookup (&info->tags, name, true, copy); - if (h == NULL) - return false; - - for (nt = h->types; nt != NULL; nt = nt->next) - { - if (nt->id == id) - { - if (! ieee_push_type (info, nt->type.indx, nt->type.size, - nt->type.unsignedp, nt->type.localp)) - return false; - /* Copy over any other type information we may have. */ - info->type_stack->type = nt->type; - return true; - } - - if (! nt->type.localp) - { - /* This is a duplicate of a global type, so it must be - local. */ - localp = true; - } - } - - nt = (struct ieee_name_type *) xmalloc (sizeof *nt); - memset (nt, 0, sizeof *nt); - - nt->id = id; - nt->type.name = h->root.string; - nt->type.indx = info->type_indx; - nt->type.localp = localp; - ++info->type_indx; - nt->kind = kind; - - nt->next = h->types; - h->types = nt; - - if (! ieee_push_type (info, nt->type.indx, 0, false, localp)) - return false; - - info->type_stack->type.name = h->root.string; - - return true; -} - -/* Output a typedef. */ - -static boolean -ieee_typdef (p, name) - PTR p; - const char *name; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - struct ieee_write_type type; - unsigned int indx; - boolean found; - boolean localp; - struct ieee_name_type_hash_entry *h; - struct ieee_name_type *nt; - - type = info->type_stack->type; - indx = type.indx; - - /* If this is a simple builtin type using a builtin name, we don't - want to output the typedef itself. We also want to change the - type index to correspond to the name being used. We recognize - names used in stabs debugging output even if they don't exactly - correspond to the names used for the IEEE builtin types. */ - found = false; - if (indx <= (unsigned int) builtin_bcd_float) - { - switch ((enum builtin_types) indx) - { - default: - break; - - case builtin_void: - if (strcmp (name, "void") == 0) - found = true; - break; - - case builtin_signed_char: - case builtin_char: - if (strcmp (name, "signed char") == 0) - { - indx = (unsigned int) builtin_signed_char; - found = true; - } - else if (strcmp (name, "char") == 0) - { - indx = (unsigned int) builtin_char; - found = true; - } - break; - - case builtin_unsigned_char: - if (strcmp (name, "unsigned char") == 0) - found = true; - break; - - case builtin_signed_short_int: - case builtin_short: - case builtin_short_int: - case builtin_signed_short: - if (strcmp (name, "signed short int") == 0) - { - indx = (unsigned int) builtin_signed_short_int; - found = true; - } - else if (strcmp (name, "short") == 0) - { - indx = (unsigned int) builtin_short; - found = true; - } - else if (strcmp (name, "short int") == 0) - { - indx = (unsigned int) builtin_short_int; - found = true; - } - else if (strcmp (name, "signed short") == 0) - { - indx = (unsigned int) builtin_signed_short; - found = true; - } - break; - - case builtin_unsigned_short_int: - case builtin_unsigned_short: - if (strcmp (name, "unsigned short int") == 0 - || strcmp (name, "short unsigned int") == 0) - { - indx = builtin_unsigned_short_int; - found = true; - } - else if (strcmp (name, "unsigned short") == 0) - { - indx = builtin_unsigned_short; - found = true; - } - break; - - case builtin_signed_long: - case builtin_int: /* FIXME: Size depends upon architecture. */ - case builtin_long: - if (strcmp (name, "signed long") == 0) - { - indx = builtin_signed_long; - found = true; - } - else if (strcmp (name, "int") == 0) - { - indx = builtin_int; - found = true; - } - else if (strcmp (name, "long") == 0 - || strcmp (name, "long int") == 0) - { - indx = builtin_long; - found = true; - } - break; - - case builtin_unsigned_long: - case builtin_unsigned: /* FIXME: Size depends upon architecture. */ - case builtin_unsigned_int: /* FIXME: Like builtin_unsigned. */ - if (strcmp (name, "unsigned long") == 0 - || strcmp (name, "long unsigned int") == 0) - { - indx = builtin_unsigned_long; - found = true; - } - else if (strcmp (name, "unsigned") == 0) - { - indx = builtin_unsigned; - found = true; - } - else if (strcmp (name, "unsigned int") == 0) - { - indx = builtin_unsigned_int; - found = true; - } - break; - - case builtin_signed_long_long: - if (strcmp (name, "signed long long") == 0 - || strcmp (name, "long long int") == 0) - found = true; - break; - - case builtin_unsigned_long_long: - if (strcmp (name, "unsigned long long") == 0 - || strcmp (name, "long long unsigned int") == 0) - found = true; - break; - - case builtin_float: - if (strcmp (name, "float") == 0) - found = true; - break; - - case builtin_double: - if (strcmp (name, "double") == 0) - found = true; - break; - - case builtin_long_double: - if (strcmp (name, "long double") == 0) - found = true; - break; - - case builtin_long_long_double: - if (strcmp (name, "long long double") == 0) - found = true; - break; - } - - if (found) - type.indx = indx; - } - - h = ieee_name_type_hash_lookup (&info->typedefs, name, true, false); - if (h == NULL) - return false; - - /* See if we have already defined this type with this name. */ - localp = type.localp; - for (nt = h->types; nt != NULL; nt = nt->next) - { - if (nt->id == indx) - { - /* If this is a global definition, then we don't need to - do anything here. */ - if (! nt->type.localp) - { - ieee_pop_unused_type (info); - return true; - } - } - else - { - /* This is a duplicate definition, so make this one local. */ - localp = true; - } - } - - /* We need to add a new typedef for this type. */ - - nt = (struct ieee_name_type *) xmalloc (sizeof *nt); - memset (nt, 0, sizeof *nt); - nt->id = indx; - nt->type = type; - nt->type.name = name; - nt->type.localp = localp; - nt->kind = DEBUG_KIND_ILLEGAL; - - nt->next = h->types; - h->types = nt; - - if (found) - { - /* This is one of the builtin typedefs, so we don't need to - actually define it. */ - ieee_pop_unused_type (info); - return true; - } - - indx = ieee_pop_type (info); - - if (! ieee_define_named_type (info, name, (unsigned int) -1, type.size, - type.unsignedp, localp, - (struct ieee_buflist *) NULL) - || ! ieee_write_number (info, 'T') - || ! ieee_write_number (info, indx)) - return false; - - /* Remove the type we just added to the type stack. This should not - be ieee_pop_unused_type, since the type is used, we just don't - need it now. */ - (void) ieee_pop_type (info); - - return true; -} - -/* Output a tag for a type. We don't have to do anything here. */ - -static boolean -ieee_tag (p, name) - PTR p; - const char *name; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - /* This should not be ieee_pop_unused_type, since we want the type - to be defined. */ - (void) ieee_pop_type (info); - return true; -} - -/* Output an integer constant. */ - -static boolean -ieee_int_constant (p, name, val) - PTR p; - const char *name; - bfd_vma val; -{ - /* FIXME. */ - return true; -} - -/* Output a floating point constant. */ - -static boolean -ieee_float_constant (p, name, val) - PTR p; - const char *name; - double val; -{ - /* FIXME. */ - return true; -} - -/* Output a typed constant. */ - -static boolean -ieee_typed_constant (p, name, val) - PTR p; - const char *name; - bfd_vma val; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - /* FIXME. */ - ieee_pop_unused_type (info); - return true; -} - -/* Output a variable. */ - -static boolean -ieee_variable (p, name, kind, val) - PTR p; - const char *name; - enum debug_var_kind kind; - bfd_vma val; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - unsigned int name_indx; - unsigned int size; - boolean referencep; - unsigned int type_indx; - boolean asn; - int refflag; - - size = info->type_stack->type.size; - referencep = info->type_stack->type.referencep; - type_indx = ieee_pop_type (info); - - assert (! ieee_buffer_emptyp (&info->vars)); - if (! ieee_change_buffer (info, &info->vars)) - return false; - - name_indx = info->name_indx; - ++info->name_indx; - - /* Write out an NN and an ATN record for this variable. */ - if (! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, name_indx) - || ! ieee_write_id (info, name) - || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, name_indx) - || ! ieee_write_number (info, type_indx)) - return false; - switch (kind) - { - default: - abort (); - return false; - case DEBUG_GLOBAL: - if (! ieee_write_number (info, 8) - || ! ieee_add_range (info, false, val, val + size)) - return false; - refflag = 0; - asn = true; - break; - case DEBUG_STATIC: - if (! ieee_write_number (info, 3) - || ! ieee_add_range (info, false, val, val + size)) - return false; - refflag = 1; - asn = true; - break; - case DEBUG_LOCAL_STATIC: - if (! ieee_write_number (info, 3) - || ! ieee_add_range (info, false, val, val + size)) - return false; - refflag = 2; - asn = true; - break; - case DEBUG_LOCAL: - if (! ieee_write_number (info, 1) - || ! ieee_write_number (info, val)) - return false; - refflag = 2; - asn = false; - break; - case DEBUG_REGISTER: - if (! ieee_write_number (info, 2) - || ! ieee_write_number (info, - ieee_genreg_to_regno (info->abfd, val))) - return false; - refflag = 2; - asn = false; - break; - } - - if (asn) - { - if (! ieee_write_asn (info, name_indx, val)) - return false; - } - - /* If this is really a reference type, then we just output it with - pointer type, and must now output a C++ record indicating that it - is really reference type. */ - if (referencep) - { - unsigned int nindx; - - nindx = info->name_indx; - ++info->name_indx; - - /* If this is a global variable, we want to output the misc - record in the C++ misc record block. Otherwise, we want to - output it just after the variable definition, which is where - the current buffer is. */ - if (refflag != 2) - { - if (! ieee_change_buffer (info, &info->cxx)) - return false; - } - - if (! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, nindx) - || ! ieee_write_id (info, "") - || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, nindx) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 62) - || ! ieee_write_number (info, 80) - || ! ieee_write_number (info, 3) - || ! ieee_write_asn (info, nindx, 'R') - || ! ieee_write_asn (info, nindx, refflag) - || ! ieee_write_atn65 (info, nindx, name)) - return false; - } - - return true; -} - -/* Start outputting information for a function. */ - -static boolean -ieee_start_function (p, name, global) - PTR p; - const char *name; - boolean global; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - boolean referencep; - unsigned int retindx, typeindx; - - referencep = info->type_stack->type.referencep; - retindx = ieee_pop_type (info); - - /* Besides recording a BB4 or BB6 block, we record the type of the - function in the BB1 typedef block. We can't write out the full - type until we have seen all the parameters, so we accumulate it - in info->fntype and info->fnargs. */ - if (! ieee_buffer_emptyp (&info->fntype)) - { - /* FIXME: This might happen someday if we support nested - functions. */ - abort (); - } - - info->fnname = name; - - /* An attribute of 0x40 means that the push mask is unknown. */ - if (! ieee_define_named_type (info, name, (unsigned int) -1, 0, false, true, - &info->fntype) - || ! ieee_write_number (info, 'x') - || ! ieee_write_number (info, 0x40) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, retindx)) - return false; - - typeindx = ieee_pop_type (info); - - if (! ieee_init_buffer (info, &info->fnargs)) - return false; - info->fnargcount = 0; - - /* If the function return value is actually a reference type, we - must add a record indicating that. */ - if (referencep) - { - unsigned int nindx; - - nindx = info->name_indx; - ++info->name_indx; - if (! ieee_change_buffer (info, &info->cxx) - || ! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, nindx) - || ! ieee_write_id (info, "") - || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, nindx) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 62) - || ! ieee_write_number (info, 80) - || ! ieee_write_number (info, 3) - || ! ieee_write_asn (info, nindx, 'R') - || ! ieee_write_asn (info, nindx, global ? 0 : 1) - || ! ieee_write_atn65 (info, nindx, name)) - return false; - } - - assert (! ieee_buffer_emptyp (&info->vars)); - if (! ieee_change_buffer (info, &info->vars)) - return false; - - /* The address is written out as the first block. */ - - ++info->block_depth; - - return (ieee_write_byte (info, (int) ieee_bb_record_enum) - && ieee_write_byte (info, global ? 4 : 6) - && ieee_write_number (info, 0) - && ieee_write_id (info, name) - && ieee_write_number (info, 0) - && ieee_write_number (info, typeindx)); -} - -/* Add a function parameter. This will normally be called before the - first block, so we postpone them until we see the block. */ - -static boolean -ieee_function_parameter (p, name, kind, val) - PTR p; - const char *name; - enum debug_parm_kind kind; - bfd_vma val; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - struct ieee_pending_parm *m, **pm; - - assert (info->block_depth == 1); - - m = (struct ieee_pending_parm *) xmalloc (sizeof *m); - memset (m, 0, sizeof *m); - - m->next = NULL; - m->name = name; - m->referencep = info->type_stack->type.referencep; - m->type = ieee_pop_type (info); - m->kind = kind; - m->val = val; - - for (pm = &info->pending_parms; *pm != NULL; pm = &(*pm)->next) - ; - *pm = m; - - /* Add the type to the fnargs list. */ - if (! ieee_change_buffer (info, &info->fnargs) - || ! ieee_write_number (info, m->type)) - return false; - ++info->fnargcount; - - return true; -} - -/* Output pending function parameters. */ - -static boolean -ieee_output_pending_parms (info) - struct ieee_handle *info; -{ - struct ieee_pending_parm *m; - unsigned int refcount; - - refcount = 0; - for (m = info->pending_parms; m != NULL; m = m->next) - { - enum debug_var_kind vkind; - - switch (m->kind) - { - default: - abort (); - return false; - case DEBUG_PARM_STACK: - case DEBUG_PARM_REFERENCE: - vkind = DEBUG_LOCAL; - break; - case DEBUG_PARM_REG: - case DEBUG_PARM_REF_REG: - vkind = DEBUG_REGISTER; - break; - } - - if (! ieee_push_type (info, m->type, 0, false, false)) - return false; - info->type_stack->type.referencep = m->referencep; - if (m->referencep) - ++refcount; - if (! ieee_variable ((PTR) info, m->name, vkind, m->val)) - return false; - } - - /* If there are any reference parameters, we need to output a - miscellaneous record indicating them. */ - if (refcount > 0) - { - unsigned int nindx, varindx; - - /* FIXME: The MRI compiler outputs the demangled function name - here, but we are outputting the mangled name. */ - nindx = info->name_indx; - ++info->name_indx; - if (! ieee_change_buffer (info, &info->vars) - || ! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, nindx) - || ! ieee_write_id (info, "") - || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, nindx) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 62) - || ! ieee_write_number (info, 80) - || ! ieee_write_number (info, refcount + 3) - || ! ieee_write_asn (info, nindx, 'B') - || ! ieee_write_atn65 (info, nindx, info->fnname) - || ! ieee_write_asn (info, nindx, 0)) - return false; - for (m = info->pending_parms, varindx = 1; - m != NULL; - m = m->next, varindx++) - { - if (m->referencep) - { - if (! ieee_write_asn (info, nindx, varindx)) - return false; - } - } - } - - m = info->pending_parms; - while (m != NULL) - { - struct ieee_pending_parm *next; - - next = m->next; - free (m); - m = next; - } - - info->pending_parms = NULL; - - return true; -} - -/* Start a block. If this is the first block, we output the address - to finish the BB4 or BB6, and then output the function parameters. */ - -static boolean -ieee_start_block (p, addr) - PTR p; - bfd_vma addr; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - if (! ieee_change_buffer (info, &info->vars)) - return false; - - if (info->block_depth == 1) - { - if (! ieee_write_number (info, addr) - || ! ieee_output_pending_parms (info)) - return false; - } - else - { - if (! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 6) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, "") - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, addr)) - return false; - } - - if (! ieee_start_range (info, addr)) - return false; - - ++info->block_depth; - - return true; -} - -/* End a block. */ - -static boolean -ieee_end_block (p, addr) - PTR p; - bfd_vma addr; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - /* The address we are given is the end of the block, but IEEE seems - to want to the address of the last byte in the block, so we - subtract one. */ - if (! ieee_change_buffer (info, &info->vars) - || ! ieee_write_byte (info, (int) ieee_be_record_enum) - || ! ieee_write_number (info, addr - 1)) - return false; - - if (! ieee_end_range (info, addr)) - return false; - - --info->block_depth; - - if (addr > info->highaddr) - info->highaddr = addr; - - return true; -} - -/* End a function. */ - -static boolean -ieee_end_function (p) - PTR p; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - assert (info->block_depth == 1); - - --info->block_depth; - - /* Now we can finish up fntype, and add it to the typdef section. - At this point, fntype is the 'x' type up to the argument count, - and fnargs is the argument types. We must add the argument - count, and we must add the level. FIXME: We don't record varargs - functions correctly. In fact, stabs debugging does not give us - enough information to do so. */ - if (! ieee_change_buffer (info, &info->fntype) - || ! ieee_write_number (info, info->fnargcount) - || ! ieee_change_buffer (info, &info->fnargs) - || ! ieee_write_number (info, 0)) - return false; - - /* Make sure the typdef block has been started. */ - if (ieee_buffer_emptyp (&info->types)) - { - if (! ieee_change_buffer (info, &info->types) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 1) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->modname)) - return false; - } - - if (! ieee_append_buffer (info, &info->types, &info->fntype) - || ! ieee_append_buffer (info, &info->types, &info->fnargs)) - return false; - - info->fnname = NULL; - if (! ieee_init_buffer (info, &info->fntype) - || ! ieee_init_buffer (info, &info->fnargs)) - return false; - info->fnargcount = 0; - - return true; -} - -/* Record line number information. */ - -static boolean -ieee_lineno (p, filename, lineno, addr) - PTR p; - const char *filename; - unsigned long lineno; - bfd_vma addr; -{ - struct ieee_handle *info = (struct ieee_handle *) p; - - assert (info->filename != NULL); - - /* The HP simulator seems to get confused when more than one line is - listed for the same address, at least if they are in different - files. We handle this by always listing the last line for a - given address, since that seems to be the one that gdb uses. */ - if (info->pending_lineno_filename != NULL - && addr != info->pending_lineno_addr) - { - /* Make sure we have a line number block. */ - if (! ieee_buffer_emptyp (&info->linenos)) - { - if (! ieee_change_buffer (info, &info->linenos)) - return false; - } - else - { - info->lineno_name_indx = info->name_indx; - ++info->name_indx; - if (! ieee_change_buffer (info, &info->linenos) - || ! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 5) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->filename) - || ! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, info->lineno_name_indx) - || ! ieee_write_id (info, "")) - return false; - info->lineno_filename = info->filename; - } - - if (strcmp (info->pending_lineno_filename, info->lineno_filename) != 0) - { - if (strcmp (info->filename, info->lineno_filename) != 0) - { - /* We were not in the main file. Close the block for the - included file. */ - if (! ieee_write_byte (info, (int) ieee_be_record_enum)) - return false; - if (strcmp (info->filename, info->pending_lineno_filename) == 0) - { - /* We need a new NN record, and we aren't about to - output one. */ - info->lineno_name_indx = info->name_indx; - ++info->name_indx; - if (! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, info->lineno_name_indx) - || ! ieee_write_id (info, "")) - return false; - } - } - if (strcmp (info->filename, info->pending_lineno_filename) != 0) - { - /* We are not changing to the main file. Open a block for - the new included file. */ - info->lineno_name_indx = info->name_indx; - ++info->name_indx; - if (! ieee_write_byte (info, (int) ieee_bb_record_enum) - || ! ieee_write_byte (info, 5) - || ! ieee_write_number (info, 0) - || ! ieee_write_id (info, info->pending_lineno_filename) - || ! ieee_write_byte (info, (int) ieee_nn_record) - || ! ieee_write_number (info, info->lineno_name_indx) - || ! ieee_write_id (info, "")) - return false; - } - info->lineno_filename = info->pending_lineno_filename; - } - - if (! ieee_write_2bytes (info, (int) ieee_atn_record_enum) - || ! ieee_write_number (info, info->lineno_name_indx) - || ! ieee_write_number (info, 0) - || ! ieee_write_number (info, 7) - || ! ieee_write_number (info, info->pending_lineno) - || ! ieee_write_number (info, 0) - || ! ieee_write_asn (info, info->lineno_name_indx, - info->pending_lineno_addr)) - return false; - } - - info->pending_lineno_filename = filename; - info->pending_lineno = lineno; - info->pending_lineno_addr = addr; - - return true; -} diff --git a/pstack/ieee.h b/pstack/ieee.h deleted file mode 100644 index 56634b2819a..00000000000 --- a/pstack/ieee.h +++ /dev/null @@ -1,138 +0,0 @@ -/* IEEE Standard 695-1980 "Universal Format for Object Modules" header file - Contributed by Cygnus Support. */ - -#define N_W_VARIABLES 8 -#define Module_Beginning 0xe0 - -typedef struct ieee_module { - char *processor; - char *module_name; -} ieee_module_begin_type; - -#define Address_Descriptor 0xec -typedef struct ieee_address { -bfd_vma number_of_bits_mau; - bfd_vma number_of_maus_in_address; - - unsigned char byte_order; -#define IEEE_LITTLE 0xcc -#define IEEE_BIG 0xcd -} ieee_address_descriptor_type; - -typedef union ieee_w_variable { - file_ptr offset[N_W_VARIABLES]; - struct { - file_ptr extension_record; - file_ptr environmental_record; - file_ptr section_part; - file_ptr external_part; - file_ptr debug_information_part; - file_ptr data_part; - file_ptr trailer_part; - file_ptr me_record; - } r; -} ieee_w_variable_type; - - - - - -typedef enum ieee_record -{ - ieee_number_start_enum = 0x00, - ieee_number_end_enum=0x7f, - ieee_number_repeat_start_enum = 0x80, - ieee_number_repeat_end_enum = 0x88, - ieee_number_repeat_4_enum = 0x84, - ieee_number_repeat_3_enum = 0x83, - ieee_number_repeat_2_enum = 0x82, - ieee_number_repeat_1_enum = 0x81, - ieee_module_beginning_enum = 0xe0, - ieee_module_end_enum = 0xe1, - ieee_extension_length_1_enum = 0xde, - ieee_extension_length_2_enum = 0xdf, - ieee_section_type_enum = 0xe6, - ieee_section_alignment_enum = 0xe7, - ieee_external_symbol_enum = 0xe8, - ieee_comma = 0x90, - ieee_external_reference_enum = 0xe9, - ieee_set_current_section_enum = 0xe5, - ieee_address_descriptor_enum = 0xec, - ieee_load_constant_bytes_enum = 0xed, - ieee_load_with_relocation_enum = 0xe4, - - ieee_variable_A_enum = 0xc1, - ieee_variable_B_enum = 0xc2, - ieee_variable_C_enum = 0xc3, - ieee_variable_D_enum = 0xc4, - ieee_variable_E_enum = 0xc5, - ieee_variable_F_enum = 0xc6, - ieee_variable_G_enum = 0xc7, - ieee_variable_H_enum = 0xc8, - ieee_variable_I_enum = 0xc9, - ieee_variable_J_enum = 0xca, - ieee_variable_K_enum = 0xcb, - ieee_variable_L_enum = 0xcc, - ieee_variable_M_enum = 0xcd, - ieee_variable_N_enum = 0xce, - ieee_variable_O_enum = 0xcf, - ieee_variable_P_enum = 0xd0, - ieee_variable_Q_enum = 0xd1, - ieee_variable_R_enum = 0xd2, - ieee_variable_S_enum = 0xd3, - ieee_variable_T_enum = 0xd4, - ieee_variable_U_enum = 0xd5, - ieee_variable_V_enum = 0xd6, - ieee_variable_W_enum = 0xd7, - ieee_variable_X_enum = 0xd8, - ieee_variable_Y_enum = 0xd9, - ieee_variable_Z_enum = 0xda, - ieee_function_plus_enum = 0xa5, - ieee_function_minus_enum = 0xa6, - ieee_function_signed_open_b_enum = 0xba, - ieee_function_signed_close_b_enum = 0xbb, - - ieee_function_unsigned_open_b_enum = 0xbc, - ieee_function_unsigned_close_b_enum = 0xbd, - - ieee_function_either_open_b_enum = 0xbe, - ieee_function_either_close_b_enum = 0xbf, - ieee_record_seperator_enum = 0xdb, - - ieee_e2_first_byte_enum = 0xe2, - ieee_section_size_enum = 0xe2d3, - ieee_physical_region_size_enum = 0xe2c1, - ieee_region_base_address_enum = 0xe2c2, - ieee_mau_size_enum = 0xe2c6, - ieee_m_value_enum = 0xe2cd, - ieee_section_base_address_enum = 0xe2cc, - ieee_asn_record_enum = 0xe2ce, - ieee_section_offset_enum = 0xe2d2, - ieee_value_starting_address_enum = 0xe2c7, - ieee_assign_value_to_variable_enum = 0xe2d7, - ieee_set_current_pc_enum = 0xe2d0, - ieee_value_record_enum = 0xe2c9, - ieee_nn_record = 0xf0, - ieee_at_record_enum = 0xf1, - ieee_ty_record_enum = 0xf2, - ieee_attribute_record_enum = 0xf1c9, - ieee_atn_record_enum = 0xf1ce, - ieee_external_reference_info_record_enum = 0xf1d8, - ieee_weak_external_reference_enum= 0xf4, - ieee_repeat_data_enum = 0xf7, - ieee_bb_record_enum = 0xf8, - ieee_be_record_enum = 0xf9 -} ieee_record_enum_type; - - -typedef struct ieee_section { - unsigned int section_index; - unsigned int section_type; - char *section_name; - unsigned int parent_section_index; - unsigned int sibling_section_index; - unsigned int context_index; -} ieee_section_type; -#define IEEE_REFERENCE_BASE 11 -#define IEEE_PUBLIC_BASE 32 -#define IEEE_SECTION_NUMBER_BASE 1 diff --git a/pstack/libiberty.h b/pstack/libiberty.h deleted file mode 100644 index ca0043d31c6..00000000000 --- a/pstack/libiberty.h +++ /dev/null @@ -1,180 +0,0 @@ -/* Function declarations for libiberty. - Written by Cygnus Support, 1994. - - The libiberty library provides a number of functions which are - missing on some operating systems. We do not declare those here, - to avoid conflicts with the system header files on operating - systems that do support those functions. In this file we only - declare those functions which are specific to libiberty. */ - -#ifndef LIBIBERTY_H -#define LIBIBERTY_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "ansidecl.h" - -/* Build an argument vector from a string. Allocates memory using - malloc. Use freeargv to free the vector. */ - -extern char **buildargv PARAMS ((char *)); - -/* Free a vector returned by buildargv. */ - -extern void freeargv PARAMS ((char **)); - -/* Duplicate an argument vector. Allocates memory using malloc. Use - freeargv to free the vector. */ - -extern char **dupargv PARAMS ((char **)); - - -/* Return the last component of a path name. Note that we can't use a - prototype here because the parameter is declared inconsistently - across different systems, sometimes as "char *" and sometimes as - "const char *" */ - -#if defined (__GNU_LIBRARY__ ) || defined (__linux__) || defined (__FreeBSD__) -extern char *basename PARAMS ((const char *)); -#else -extern char *basename (); -#endif - -/* Concatenate an arbitrary number of strings, up to (char *) NULL. - Allocates memory using xmalloc. */ - -extern char *concat PARAMS ((const char *, ...)); - -/* Check whether two file descriptors refer to the same file. */ - -extern int fdmatch PARAMS ((int fd1, int fd2)); - -/* Get the amount of time the process has run, in microseconds. */ - -extern long get_run_time PARAMS ((void)); - -/* Choose a temporary directory to use for scratch files. */ - -extern char *choose_temp_base PARAMS ((void)); - -/* Allocate memory filled with spaces. Allocates using malloc. */ - -extern const char *spaces PARAMS ((int count)); - -/* Return the maximum error number for which strerror will return a - string. */ - -extern int errno_max PARAMS ((void)); - -/* Return the name of an errno value (e.g., strerrno (EINVAL) returns - "EINVAL"). */ - -extern const char *strerrno PARAMS ((int)); - -/* Given the name of an errno value, return the value. */ - -extern int strtoerrno PARAMS ((const char *)); - -/* ANSI's strerror(), but more robust. */ - -extern char *xstrerror PARAMS ((int)); - -/* Return the maximum signal number for which strsignal will return a - string. */ - -extern int signo_max PARAMS ((void)); - -/* Return a signal message string for a signal number - (e.g., strsignal (SIGHUP) returns something like "Hangup"). */ -/* This is commented out as it can conflict with one in system headers. - We still document its existence though. */ - -/*extern const char *strsignal PARAMS ((int));*/ - -/* Return the name of a signal number (e.g., strsigno (SIGHUP) returns - "SIGHUP"). */ - -extern const char *strsigno PARAMS ((int)); - -/* Given the name of a signal, return its number. */ - -extern int strtosigno PARAMS ((const char *)); - -/* Register a function to be run by xexit. Returns 0 on success. */ - -extern int xatexit PARAMS ((void (*fn) (void))); - -/* Exit, calling all the functions registered with xatexit. */ - -#ifndef __GNUC__ -extern void xexit PARAMS ((int status)); -#else -void xexit PARAMS ((int status)) __attribute__ ((noreturn)); -#endif - -/* Set the program name used by xmalloc. */ - -extern void xmalloc_set_program_name PARAMS ((const char *)); - -/* Allocate memory without fail. If malloc fails, this will print a - message to stderr (using the name set by xmalloc_set_program_name, - if any) and then call xexit. */ - -#ifdef ANSI_PROTOTYPES -/* Get a definition for size_t. */ -#include -#endif -extern PTR xmalloc PARAMS ((size_t)); - -/* Reallocate memory without fail. This works like xmalloc. - - FIXME: We do not declare the parameter types for the same reason as - xmalloc. */ - -extern PTR xrealloc PARAMS ((PTR, size_t)); - -/* Allocate memory without fail and set it to zero. This works like - xmalloc. */ - -extern PTR xcalloc PARAMS ((size_t, size_t)); - -/* Copy a string into a memory buffer without fail. */ - -extern char *xstrdup PARAMS ((const char *)); - -/* hex character manipulation routines */ - -#define _hex_array_size 256 -#define _hex_bad 99 -extern char _hex_value[_hex_array_size]; -extern void hex_init PARAMS ((void)); -#define hex_p(c) (hex_value (c) != _hex_bad) -/* If you change this, note well: Some code relies on side effects in - the argument being performed exactly once. */ -#define hex_value(c) (_hex_value[(unsigned char) (c)]) - -/* Definitions used by the pexecute routine. */ - -#define PEXECUTE_FIRST 1 -#define PEXECUTE_LAST 2 -#define PEXECUTE_ONE (PEXECUTE_FIRST + PEXECUTE_LAST) -#define PEXECUTE_SEARCH 4 -#define PEXECUTE_VERBOSE 8 - -/* Execute a program. */ - -extern int pexecute PARAMS ((const char *, char * const *, const char *, - const char *, char **, char **, int)); - -/* Wait for pexecute to finish. */ - -extern int pwait PARAMS ((int, int *, int)); - -#ifdef __cplusplus -} -#endif - - -#endif /* ! defined (LIBIBERTY_H) */ diff --git a/pstack/linuxthreads.c b/pstack/linuxthreads.c deleted file mode 100644 index 8624bd21782..00000000000 --- a/pstack/linuxthreads.c +++ /dev/null @@ -1,90 +0,0 @@ -/* $Header$ */ - -/* - * LinuxThreads specific stuff. - */ - -#include - -#include -#include /* PTHREAD_THREADS_MAX */ -#include -#include -#include -#include -#include - -#include "linuxthreads.h" - -#define AT_INT(intval) *((int32_t*)(intval)) - -/* - * Internal LinuxThreads variables. - * Official interface exposed to GDB. - */ -#if 1 -extern volatile int __pthread_threads_debug; -extern volatile char __pthread_handles; -extern char __pthread_initial_thread; -/*extern volatile Elf32_Sym* __pthread_manager_thread;*/ -extern const int __pthread_sizeof_handle; -extern const int __pthread_offsetof_descr; -extern const int __pthread_offsetof_pid; -extern volatile int __pthread_handles_num; -#endif /* 0 */ - -/* - * Notify others. - */ -int -linuxthreads_notify_others( const int signotify) -{ - const pid_t mypid = getpid(); - //const pthread_t mytid = pthread_self(); - int i; - int threadcount = 0; - int threads[PTHREAD_THREADS_MAX]; - int pid; - - TRACE_FPRINTF((stderr, "theadcount:%d\n", __pthread_handles_num)); - if (__pthread_handles_num==2) { - /* no threads beside the initial thread */ - return 0; - } - /*assert(maxthreads>=3); - assert(maxthreads>=__pthread_handles_num+2);*/ - - // take the initial thread with us - pid = AT_INT(&__pthread_initial_thread + __pthread_offsetof_pid); - if (pid!=mypid && pid!=0) - threads[threadcount++] = pid; - // don't know why, but always handles[0]==handles[1] - for (i=1; i<__pthread_handles_num; ++i) { - const int descr = AT_INT(&__pthread_handles+i*__pthread_sizeof_handle+__pthread_offsetof_descr); - assert(descr!=0); - pid = AT_INT(descr+__pthread_offsetof_pid); - if (pid!=mypid && pid!=0) - threads[threadcount++] = pid; - } - /* TRACE_FPRINTF((stderr, "Stopping threads...")); */ - //for (i=0; i -#include "pstacktrace.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Tell other threads to dump stacks... - */ -int -linuxthreads_notify_others( const int signotify); - -#ifdef __cplusplus -} -#endif - -#endif /* pstack_linuxthreads_h_ */ - diff --git a/pstack/pstack.c b/pstack/pstack.c deleted file mode 100644 index 4cdd80d68b5..00000000000 --- a/pstack/pstack.c +++ /dev/null @@ -1,2746 +0,0 @@ -/* - pstack.c -- asynchronous stack trace of a running process - Copyright (c) 1999 Ross Thompson - Author: Ross Thompson - Critical bug fix: Tim Waugh -*/ - -/* - This file is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -/* RESTRICTIONS: - - pstack currently works only on Linux, only on an x86 machine running - 32 bit ELF binaries (64 bit not supported). Also, for symbolic - information, you need to use a GNU compiler to generate your - program, and you can't strip symbols from the binaries. For thread - information to be dumped, you have to use the debug-aware version - of libpthread.so. (To check, run 'nm' on your libpthread.so, and - make sure that the symbol "__pthread_threads_debug" is defined.) - - The details of pulling stuff out of ELF files and running through - program images is very platform specific, and I don't want to - try to support modes or machine types I can't test in or on. - If someone wants to generalize this to other architectures, I would - be happy to help and coordinate the activity. Please send me whatever - changes you make to support these machines, so that I can own the - central font of all truth (at least as regards this program). - - Thanks -*/ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* PTHREAD_THREADS_MAX */ - - -#include - -#include "libiberty.h" - -#include "pstack.h" /* just one function */ -#include "budbg.h" /* binutils stuff related to debugging symbols. */ -#include "bucomm.h" /* some common stuff */ -#include "debug.h" /* and more binutils stuff... */ -#include "budbg.h" -#include "linuxthreads.h" /* LinuxThreads specific stuff... */ - - -/* - * fprintf for file descriptors :) NOTE: we have to use fixed-size buffer :)( - * due to malloc's unavalaibility. - */ -int -fdprintf( int fd, - const char* fmt,...) -{ - char xbuf[2048];// FIXME: enough? - va_list ap; - int r; - if (fd<0) - return -1; - va_start(ap, fmt); - r = vsnprintf(xbuf, sizeof(xbuf), fmt, ap); - va_end(ap); - return write(fd, xbuf, r); -} - -int -fdputc( char c, - int fd) -{ - if (fd<0) - return -1; - return write(fd, &c, sizeof(c)); -} - -int -fdputs( const char* s, - int fd) -{ - if (fd<0) - return -1; - return write(fd, s, strlen(s)); -} - -/* - * Use this function to open log file. - * Flags: truncate on opening. - */ -static const char* path_format = "stack-trace-on-segv-%d.txt"; -static int -open_log_file( const pthread_t tid, - const pid_t pid) -{ - char fname[PATH_MAX]; - int r; - snprintf(fname, sizeof(fname), path_format, tid, pid); - r = open(fname, O_WRONLY|O_CREAT|O_TRUNC, - S_IRUSR|S_IWUSR); - if (r<0) - perror("open"); - return r; -} -/* - * Add additional debugging information for functions. - */ - -/* - * Lineno - */ -typedef struct { - int lineno; - bfd_vma addr; -} debug_lineno_t; - -/* - * Block - a {} pair. - */ -typedef struct debug_block_st { - bfd_vma begin_addr; /* where did it start */ - bfd_vma end_addr; /* where did it end */ - struct debug_block_st* parent; - struct debug_block_st* childs; - int childs_count; -} debug_block_t; - -/* - * Function parameter. - */ -typedef struct { - bfd_vma offset; /* Offset in the stack */ - const char* name; /* And name. */ -} debug_parameter_t; - -/* - * Extra information about functions. - */ -typedef struct { - asymbol* symbol; /* mangled function name, addr */ - debug_lineno_t* lines; - int lines_count; - int max_lines_count; - const char* name; - const char* filename;/* a file name it occured in... */ - debug_block_t* block; /* each function has a block, or not, you know */ - debug_parameter_t* argv; /* argument types. */ - int argc; - int max_argc; -} debug_function_t; - -/* This is the structure we use as a handle for these routines. */ -struct pr_handle -{ - /* File to print information to. */ - FILE *f; - /* Current indentation level. */ - unsigned int indent; - /* Type stack. */ - struct pr_stack *stack; - /* Parameter number we are about to output. */ - int parameter; - debug_block_t* block; /* current block */ - debug_function_t* function; /* current function */ - debug_function_t* functions; /* all functions */ - int functions_size; /* current size */ - int functions_maxsize; /* maximum size */ -}; - -/* The type stack. */ - -struct pr_stack -{ - /* Next element on the stack. */ - struct pr_stack *next; - /* This element. */ - char *type; - /* Current visibility of fields if this is a class. */ - enum debug_visibility visibility; - /* Name of the current method we are handling. */ - const char *method; -}; - -static void indent PARAMS ((struct pr_handle *)); -static boolean push_type PARAMS ((struct pr_handle *, const char *)); -static boolean prepend_type PARAMS ((struct pr_handle *, const char *)); -static boolean append_type PARAMS ((struct pr_handle *, const char *)); -static boolean substitute_type PARAMS ((struct pr_handle *, const char *)); -static boolean indent_type PARAMS ((struct pr_handle *)); -static char *pop_type PARAMS ((struct pr_handle *)); -static void print_vma PARAMS ((bfd_vma, char *, boolean, boolean)); -static boolean pr_fix_visibility - PARAMS ((struct pr_handle *, enum debug_visibility)); - -static boolean pr_start_compilation_unit PARAMS ((PTR, const char *)); -static boolean pr_start_source PARAMS ((PTR, const char *)); -static boolean pr_empty_type PARAMS ((PTR)); -static boolean pr_void_type PARAMS ((PTR)); -static boolean pr_int_type PARAMS ((PTR, unsigned int, boolean)); -static boolean pr_float_type PARAMS ((PTR, unsigned int)); -static boolean pr_complex_type PARAMS ((PTR, unsigned int)); -static boolean pr_bool_type PARAMS ((PTR, unsigned int)); -static boolean pr_enum_type - PARAMS ((PTR, const char *, const char **, bfd_signed_vma *)); -static boolean pr_pointer_type PARAMS ((PTR)); -static boolean pr_function_type PARAMS ((PTR, int, boolean)); -static boolean pr_reference_type PARAMS ((PTR)); -static boolean pr_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma)); -static boolean pr_array_type - PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean)); -static boolean pr_set_type PARAMS ((PTR, boolean)); -static boolean pr_offset_type PARAMS ((PTR)); -static boolean pr_method_type PARAMS ((PTR, boolean, int, boolean)); -static boolean pr_const_type PARAMS ((PTR)); -static boolean pr_volatile_type PARAMS ((PTR)); -static boolean pr_start_struct_type - PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int)); -static boolean pr_struct_field - PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility)); -static boolean pr_end_struct_type PARAMS ((PTR)); -static boolean pr_start_class_type - PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean, - boolean)); -static boolean pr_class_static_member - PARAMS ((PTR, const char *, const char *, enum debug_visibility)); -static boolean pr_class_baseclass - PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility)); -static boolean pr_class_start_method PARAMS ((PTR, const char *)); -static boolean pr_class_method_variant - PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean, - bfd_vma, boolean)); -static boolean pr_class_static_method_variant - PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean)); -static boolean pr_class_end_method PARAMS ((PTR)); -static boolean pr_end_class_type PARAMS ((PTR)); -static boolean pr_typedef_type PARAMS ((PTR, const char *)); -static boolean pr_tag_type - PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind)); -static boolean pr_typdef PARAMS ((PTR, const char *)); -static boolean pr_tag PARAMS ((PTR, const char *)); -static boolean pr_int_constant PARAMS ((PTR, const char *, bfd_vma)); -static boolean pr_float_constant PARAMS ((PTR, const char *, double)); -static boolean pr_typed_constant PARAMS ((PTR, const char *, bfd_vma)); -static boolean pr_variable - PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma)); -static boolean pr_start_function PARAMS ((PTR, const char *, boolean)); -static boolean pr_function_parameter - PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma)); -static boolean pr_start_block PARAMS ((PTR, bfd_vma)); -static boolean pr_end_block PARAMS ((PTR, bfd_vma)); -static boolean pr_end_function PARAMS ((PTR)); -static boolean pr_lineno PARAMS ((PTR, const char *, unsigned long, bfd_vma)); - -static const struct debug_write_fns pr_fns = -{ - pr_start_compilation_unit, - pr_start_source, - pr_empty_type, - pr_void_type, - pr_int_type, - pr_float_type, - pr_complex_type, - pr_bool_type, - pr_enum_type, - pr_pointer_type, - pr_function_type, - pr_reference_type, - pr_range_type, - pr_array_type, - pr_set_type, - pr_offset_type, - pr_method_type, - pr_const_type, - pr_volatile_type, - pr_start_struct_type, - pr_struct_field, - pr_end_struct_type, - pr_start_class_type, - pr_class_static_member, - pr_class_baseclass, - pr_class_start_method, - pr_class_method_variant, - pr_class_static_method_variant, - pr_class_end_method, - pr_end_class_type, - pr_typedef_type, - pr_tag_type, - pr_typdef, - pr_tag, - pr_int_constant, - pr_float_constant, - pr_typed_constant, - pr_variable, - pr_start_function, - pr_function_parameter, - pr_start_block, - pr_end_block, - pr_end_function, - pr_lineno -}; - - -/* Indent to the current indentation level. */ - -static void -indent (info) - struct pr_handle *info; -{ - unsigned int i; - - for (i = 0; i < info->indent; i++) - TRACE_PUTC ((' ', info->f)); -} - -/* Push a type on the type stack. */ - -static boolean -push_type (info, type) - struct pr_handle *info; - const char *type; -{ - struct pr_stack *n; - - if (type == NULL) - return false; - - n = (struct pr_stack *) xmalloc (sizeof *n); - memset (n, 0, sizeof *n); - - n->type = xstrdup (type); - n->visibility = DEBUG_VISIBILITY_IGNORE; - n->method = NULL; - n->next = info->stack; - info->stack = n; - - return true; -} - -/* Prepend a string onto the type on the top of the type stack. */ - -static boolean -prepend_type (info, s) - struct pr_handle *info; - const char *s; -{ - char *n; - - assert (info->stack != NULL); - - n = (char *) xmalloc (strlen (s) + strlen (info->stack->type) + 1); - sprintf (n, "%s%s", s, info->stack->type); - free (info->stack->type); - info->stack->type = n; - - return true; -} - -/* Append a string to the type on the top of the type stack. */ - -static boolean -append_type (info, s) - struct pr_handle *info; - const char *s; -{ - unsigned int len; - - if (s == NULL) - return false; - - assert (info->stack != NULL); - - len = strlen (info->stack->type); - info->stack->type = (char *) xrealloc (info->stack->type, - len + strlen (s) + 1); - strcpy (info->stack->type + len, s); - - return true; -} - -/* We use an underscore to indicate where the name should go in a type - string. This function substitutes a string for the underscore. If - there is no underscore, the name follows the type. */ - -static boolean -substitute_type (info, s) - struct pr_handle *info; - const char *s; -{ - char *u; - - assert (info->stack != NULL); - - u = strchr (info->stack->type, '|'); - if (u != NULL) - { - char *n; - - n = (char *) xmalloc (strlen (info->stack->type) + strlen (s)); - - memcpy (n, info->stack->type, u - info->stack->type); - strcpy (n + (u - info->stack->type), s); - strcat (n, u + 1); - - free (info->stack->type); - info->stack->type = n; - - return true; - } - - if (strchr (s, '|') != NULL - && (strchr (info->stack->type, '{') != NULL - || strchr (info->stack->type, '(') != NULL)) - { - if (! prepend_type (info, "(") - || ! append_type (info, ")")) - return false; - } - - if (*s == '\0') - return true; - - return (append_type (info, " ") - && append_type (info, s)); -} - -/* Indent the type at the top of the stack by appending spaces. */ - -static boolean -indent_type (info) - struct pr_handle *info; -{ - unsigned int i; - - for (i = 0; i < info->indent; i++) - { - if (! append_type (info, " ")) - return false; - } - - return true; -} - -/* Pop a type from the type stack. */ - -static char * -pop_type (info) - struct pr_handle *info; -{ - struct pr_stack *o; - char *ret; - - assert (info->stack != NULL); - - o = info->stack; - info->stack = o->next; - ret = o->type; - free (o); - - return ret; -} - -/* Print a VMA value into a string. */ - -static void -print_vma (vma, buf, unsignedp, hexp) - bfd_vma vma; - char *buf; - boolean unsignedp; - boolean hexp; -{ - if (sizeof (vma) <= sizeof (unsigned long)) - { - if (hexp) - sprintf (buf, "0x%lx", (unsigned long) vma); - else if (unsignedp) - sprintf (buf, "%lu", (unsigned long) vma); - else - sprintf (buf, "%ld", (long) vma); - } - else - { - buf[0] = '0'; - buf[1] = 'x'; - sprintf_vma (buf + 2, vma); - } -} - -/* Start a new compilation unit. */ - -static boolean -pr_start_compilation_unit (p, filename) - PTR p; - const char *filename; -{ - struct pr_handle *info = (struct pr_handle *) p; - - assert (info->indent == 0); -/* - TRACE_FPRINTF( (info->f, "%s:\n", filename)); -*/ - return true; -} - -/* Start a source file within a compilation unit. */ - -static boolean -pr_start_source (p, filename) - PTR p; - const char *filename; -{ - struct pr_handle *info = (struct pr_handle *) p; - - assert (info->indent == 0); -/* - TRACE_FPRINTF( (info->f, " %s:\n", filename)); -*/ - return true; -} - -/* Push an empty type onto the type stack. */ - -static boolean -pr_empty_type (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - - return push_type (info, ""); -} - -/* Push a void type onto the type stack. */ - -static boolean -pr_void_type (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - - return push_type (info, "void"); -} - -/* Push an integer type onto the type stack. */ - -static boolean -pr_int_type (p, size, unsignedp) - PTR p; - unsigned int size; - boolean unsignedp; -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[10]; - - sprintf (ab, "%sint%d", unsignedp ? "u" : "", size * 8); - return push_type (info, ab); -} - -/* Push a floating type onto the type stack. */ - -static boolean -pr_float_type (p, size) - PTR p; - unsigned int size; -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[10]; - - if (size == 4) - return push_type (info, "float"); - else if (size == 8) - return push_type (info, "double"); - - sprintf (ab, "float%d", size * 8); - return push_type (info, ab); -} - -/* Push a complex type onto the type stack. */ - -static boolean -pr_complex_type (p, size) - PTR p; - unsigned int size; -{ - struct pr_handle *info = (struct pr_handle *) p; - - if (! pr_float_type (p, size)) - return false; - - return prepend_type (info, "complex "); -} - -/* Push a boolean type onto the type stack. */ - -static boolean -pr_bool_type (p, size) - PTR p; - unsigned int size; -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[10]; - - sprintf (ab, "bool%d", size * 8); - - return push_type (info, ab); -} - -/* Push an enum type onto the type stack. */ - -static boolean -pr_enum_type (p, tag, names, values) - PTR p; - const char *tag; - const char **names; - bfd_signed_vma *values; -{ - struct pr_handle *info = (struct pr_handle *) p; - unsigned int i; - bfd_signed_vma val; - - if (! push_type (info, "enum ")) - return false; - if (tag != NULL) - { - if (! append_type (info, tag) - || ! append_type (info, " ")) - return false; - } - if (! append_type (info, "{ ")) - return false; - - if (names == NULL) - { - if (! append_type (info, "/* undefined */")) - return false; - } - else - { - val = 0; - for (i = 0; names[i] != NULL; i++) - { - if (i > 0) - { - if (! append_type (info, ", ")) - return false; - } - - if (! append_type (info, names[i])) - return false; - - if (values[i] != val) - { - char ab[20]; - - print_vma (values[i], ab, false, false); - if (! append_type (info, " = ") - || ! append_type (info, ab)) - return false; - val = values[i]; - } - - ++val; - } - } - - return append_type (info, " }"); -} - -/* Turn the top type on the stack into a pointer. */ - -static boolean -pr_pointer_type (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *s; - - assert (info->stack != NULL); - - s = strchr (info->stack->type, '|'); - if (s != NULL && s[1] == '[') - return substitute_type (info, "(*|)"); - return substitute_type (info, "*|"); -} - -/* Turn the top type on the stack into a function returning that type. */ - -static boolean -pr_function_type (p, argcount, varargs) - PTR p; - int argcount; - boolean varargs; -{ - struct pr_handle *info = (struct pr_handle *) p; - char **arg_types; - unsigned int len; - char *s; - - assert (info->stack != NULL); - - len = 10; - - if (argcount <= 0) - { - arg_types = NULL; - len += 15; - } - else - { - int i; - - arg_types = (char **) xmalloc (argcount * sizeof *arg_types); - for (i = argcount - 1; i >= 0; i--) - { - if (! substitute_type (info, "")) - return false; - arg_types[i] = pop_type (info); - if (arg_types[i] == NULL) - return false; - len += strlen (arg_types[i]) + 2; - } - if (varargs) - len += 5; - } - - /* Now the return type is on the top of the stack. */ - - s = (char *) xmalloc (len); - strcpy (s, "(|) ("); - - if (argcount < 0) - { -#if 0 - /* Turn off unknown arguments. */ - strcat (s, "/* unknown */"); -#endif - } - else - { - int i; - - for (i = 0; i < argcount; i++) - { - if (i > 0) - strcat (s, ", "); - strcat (s, arg_types[i]); - } - if (varargs) - { - if (i > 0) - strcat (s, ", "); - strcat (s, "..."); - } - if (argcount > 0) - free (arg_types); - } - - strcat (s, ")"); - - if (! substitute_type (info, s)) - return false; - - free (s); - - return true; -} - -/* Turn the top type on the stack into a reference to that type. */ - -static boolean -pr_reference_type (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - - assert (info->stack != NULL); - - return substitute_type (info, "&|"); -} - -/* Make a range type. */ - -static boolean -pr_range_type (p, lower, upper) - PTR p; - bfd_signed_vma lower; - bfd_signed_vma upper; -{ - struct pr_handle *info = (struct pr_handle *) p; - char abl[20], abu[20]; - - assert (info->stack != NULL); - - if (! substitute_type (info, "")) - return false; - - print_vma (lower, abl, false, false); - print_vma (upper, abu, false, false); - - return (prepend_type (info, "range (") - && append_type (info, "):") - && append_type (info, abl) - && append_type (info, ":") - && append_type (info, abu)); -} - -/* Make an array type. */ - -/*ARGSUSED*/ -static boolean -pr_array_type (p, lower, upper, stringp) - PTR p; - bfd_signed_vma lower; - bfd_signed_vma upper; - boolean stringp; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *range_type; - char abl[20], abu[20], ab[50]; - - range_type = pop_type (info); - if (range_type == NULL) - return false; - - if (lower == 0) - { - if (upper == -1) - sprintf (ab, "|[]"); - else - { - print_vma (upper + 1, abu, false, false); - sprintf (ab, "|[%s]", abu); - } - } - else - { - print_vma (lower, abl, false, false); - print_vma (upper, abu, false, false); - sprintf (ab, "|[%s:%s]", abl, abu); - } - - if (! substitute_type (info, ab)) - return false; - - if (strcmp (range_type, "int") != 0) - { - if (! append_type (info, ":") - || ! append_type (info, range_type)) - return false; - } - - if (stringp) - { - if (! append_type (info, " /* string */")) - return false; - } - - return true; -} - -/* Make a set type. */ - -/*ARGSUSED*/ -static boolean -pr_set_type (p, bitstringp) - PTR p; - boolean bitstringp; -{ - struct pr_handle *info = (struct pr_handle *) p; - - if (! substitute_type (info, "")) - return false; - - if (! prepend_type (info, "set { ") - || ! append_type (info, " }")) - return false; - - if (bitstringp) - { - if (! append_type (info, "/* bitstring */")) - return false; - } - - return true; -} - -/* Make an offset type. */ - -static boolean -pr_offset_type (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - - if (! substitute_type (info, "")) - return false; - - t = pop_type (info); - if (t == NULL) - return false; - - return (substitute_type (info, "") - && prepend_type (info, " ") - && prepend_type (info, t) - && append_type (info, "::|")); -} - -/* Make a method type. */ - -static boolean -pr_method_type (p, domain, argcount, varargs) - PTR p; - boolean domain; - int argcount; - boolean varargs; -{ - struct pr_handle *info = (struct pr_handle *) p; - unsigned int len; - char *domain_type; - char **arg_types; - char *s; - - len = 10; - - if (! domain) - domain_type = NULL; - else - { - if (! substitute_type (info, "")) - return false; - domain_type = pop_type (info); - if (domain_type == NULL) - return false; - if (strncmp (domain_type, "class ", sizeof "class " - 1) == 0 - && strchr (domain_type + sizeof "class " - 1, ' ') == NULL) - domain_type += sizeof "class " - 1; - else if (strncmp (domain_type, "union class ", - sizeof "union class ") == 0 - && (strchr (domain_type + sizeof "union class " - 1, ' ') - == NULL)) - domain_type += sizeof "union class " - 1; - len += strlen (domain_type); - } - - if (argcount <= 0) - { - arg_types = NULL; - len += 15; - } - else - { - int i; - - arg_types = (char **) xmalloc (argcount * sizeof *arg_types); - for (i = argcount - 1; i >= 0; i--) - { - if (! substitute_type (info, "")) - return false; - arg_types[i] = pop_type (info); - if (arg_types[i] == NULL) - return false; - len += strlen (arg_types[i]) + 2; - } - if (varargs) - len += 5; - } - - /* Now the return type is on the top of the stack. */ - - s = (char *) xmalloc (len); - if (! domain) - *s = '\0'; - else - strcpy (s, domain_type); - strcat (s, "::| ("); - - if (argcount < 0) - strcat (s, "/* unknown */"); - else - { - int i; - - for (i = 0; i < argcount; i++) - { - if (i > 0) - strcat (s, ", "); - strcat (s, arg_types[i]); - } - if (varargs) - { - if (i > 0) - strcat (s, ", "); - strcat (s, "..."); - } - if (argcount > 0) - free (arg_types); - } - - strcat (s, ")"); - - if (! substitute_type (info, s)) - return false; - - free (s); - - return true; -} - -/* Make a const qualified type. */ - -static boolean -pr_const_type (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - - return substitute_type (info, "const |"); -} - -/* Make a volatile qualified type. */ - -static boolean -pr_volatile_type (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - - return substitute_type (info, "volatile |"); -} - -/* Start accumulating a struct type. */ - -static boolean -pr_start_struct_type (p, tag, id, structp, size) - PTR p; - const char *tag; - unsigned int id; - boolean structp; - unsigned int size; -{ - struct pr_handle *info = (struct pr_handle *) p; - - info->indent += 2; - - if (! push_type (info, structp ? "struct " : "union ")) - return false; - if (tag != NULL) - { - if (! append_type (info, tag)) - return false; - } - else - { - char idbuf[20]; - - sprintf (idbuf, "%%anon%u", id); - if (! append_type (info, idbuf)) - return false; - } - - if (! append_type (info, " {")) - return false; - if (size != 0 || tag != NULL) - { - char ab[30]; - - if (! append_type (info, " /*")) - return false; - - if (size != 0) - { - sprintf (ab, " size %u", size); - if (! append_type (info, ab)) - return false; - } - if (tag != NULL) - { - sprintf (ab, " id %u", id); - if (! append_type (info, ab)) - return false; - } - if (! append_type (info, " */")) - return false; - } - if (! append_type (info, "\n")) - return false; - - info->stack->visibility = DEBUG_VISIBILITY_PUBLIC; - - return indent_type (info); -} - -/* Output the visibility of a field in a struct. */ - -static boolean -pr_fix_visibility (info, visibility) - struct pr_handle *info; - enum debug_visibility visibility; -{ - const char *s; - char *t; - unsigned int len; - - assert (info->stack != NULL); - - if (info->stack->visibility == visibility) - return true; - - assert (info->stack->visibility != DEBUG_VISIBILITY_IGNORE); - - switch (visibility) - { - case DEBUG_VISIBILITY_PUBLIC: - s = "public"; - break; - case DEBUG_VISIBILITY_PRIVATE: - s = "private"; - break; - case DEBUG_VISIBILITY_PROTECTED: - s = "protected"; - break; - case DEBUG_VISIBILITY_IGNORE: - s = "/* ignore */"; - break; - default: - abort (); - return false; - } - - /* Trim off a trailing space in the struct string, to make the - output look a bit better, then stick on the visibility string. */ - - t = info->stack->type; - len = strlen (t); - assert (t[len - 1] == ' '); - t[len - 1] = '\0'; - - if (! append_type (info, s) - || ! append_type (info, ":\n") - || ! indent_type (info)) - return false; - - info->stack->visibility = visibility; - - return true; -} - -/* Add a field to a struct type. */ - -static boolean -pr_struct_field (p, name, bitpos, bitsize, visibility) - PTR p; - const char *name; - bfd_vma bitpos; - bfd_vma bitsize; - enum debug_visibility visibility; -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[20]; - char *t; - - if (! substitute_type (info, name)) - return false; - - if (! append_type (info, "; /* ")) - return false; - - if (bitsize != 0) - { - print_vma (bitsize, ab, true, false); - if (! append_type (info, "bitsize ") - || ! append_type (info, ab) - || ! append_type (info, ", ")) - return false; - } - - print_vma (bitpos, ab, true, false); - if (! append_type (info, "bitpos ") - || ! append_type (info, ab) - || ! append_type (info, " */\n") - || ! indent_type (info)) - return false; - - t = pop_type (info); - if (t == NULL) - return false; - - if (! pr_fix_visibility (info, visibility)) - return false; - - return append_type (info, t); -} - -/* Finish a struct type. */ - -static boolean -pr_end_struct_type (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *s; - - assert (info->stack != NULL); - assert (info->indent >= 2); - - info->indent -= 2; - - /* Change the trailing indentation to have a close brace. */ - s = info->stack->type + strlen (info->stack->type) - 2; - assert (s[0] == ' ' && s[1] == ' ' && s[2] == '\0'); - - *s++ = '}'; - *s = '\0'; - - return true; -} - -/* Start a class type. */ - -static boolean -pr_start_class_type (p, tag, id, structp, size, vptr, ownvptr) - PTR p; - const char *tag; - unsigned int id; - boolean structp; - unsigned int size; - boolean vptr; - boolean ownvptr; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *tv = NULL; - - info->indent += 2; - - if (vptr && ! ownvptr) - { - tv = pop_type (info); - if (tv == NULL) - return false; - } - - if (! push_type (info, structp ? "class " : "union class ")) - return false; - if (tag != NULL) - { - if (! append_type (info, tag)) - return false; - } - else - { - char idbuf[20]; - - sprintf (idbuf, "%%anon%u", id); - if (! append_type (info, idbuf)) - return false; - } - - if (! append_type (info, " {")) - return false; - if (size != 0 || vptr || ownvptr || tag != NULL) - { - if (! append_type (info, " /*")) - return false; - - if (size != 0) - { - char ab[20]; - - sprintf (ab, "%u", size); - if (! append_type (info, " size ") - || ! append_type (info, ab)) - return false; - } - - if (vptr) - { - if (! append_type (info, " vtable ")) - return false; - if (ownvptr) - { - if (! append_type (info, "self ")) - return false; - } - else - { - if (! append_type (info, tv) - || ! append_type (info, " ")) - return false; - } - } - - if (tag != NULL) - { - char ab[30]; - - sprintf (ab, " id %u", id); - if (! append_type (info, ab)) - return false; - } - - if (! append_type (info, " */")) - return false; - } - - info->stack->visibility = DEBUG_VISIBILITY_PRIVATE; - - return (append_type (info, "\n") - && indent_type (info)); -} - -/* Add a static member to a class. */ - -static boolean -pr_class_static_member (p, name, physname, visibility) - PTR p; - const char *name; - const char *physname; - enum debug_visibility visibility; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - - if (! substitute_type (info, name)) - return false; - - if (! prepend_type (info, "static ") - || ! append_type (info, "; /* ") - || ! append_type (info, physname) - || ! append_type (info, " */\n") - || ! indent_type (info)) - return false; - - t = pop_type (info); - if (t == NULL) - return false; - - if (! pr_fix_visibility (info, visibility)) - return false; - - return append_type (info, t); -} - -/* Add a base class to a class. */ - -static boolean -pr_class_baseclass (p, bitpos, virtual, visibility) - PTR p; - bfd_vma bitpos; - boolean virtual; - enum debug_visibility visibility; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - const char *prefix; - char ab[20]; - char *s, *l, *n; - - assert (info->stack != NULL && info->stack->next != NULL); - - if (! substitute_type (info, "")) - return false; - - t = pop_type (info); - if (t == NULL) - return false; - - if (strncmp (t, "class ", sizeof "class " - 1) == 0) - t += sizeof "class " - 1; - - /* Push it back on to take advantage of the prepend_type and - append_type routines. */ - if (! push_type (info, t)) - return false; - - if (virtual) - { - if (! prepend_type (info, "virtual ")) - return false; - } - - switch (visibility) - { - case DEBUG_VISIBILITY_PUBLIC: - prefix = "public "; - break; - case DEBUG_VISIBILITY_PROTECTED: - prefix = "protected "; - break; - case DEBUG_VISIBILITY_PRIVATE: - prefix = "private "; - break; - default: - prefix = "/* unknown visibility */ "; - break; - } - - if (! prepend_type (info, prefix)) - return false; - - if (bitpos != 0) - { - print_vma (bitpos, ab, true, false); - if (! append_type (info, " /* bitpos ") - || ! append_type (info, ab) - || ! append_type (info, " */")) - return false; - } - - /* Now the top of the stack is something like "public A / * bitpos - 10 * /". The next element on the stack is something like "class - xx { / * size 8 * /\n...". We want to substitute the top of the - stack in before the {. */ - s = strchr (info->stack->next->type, '{'); - assert (s != NULL); - --s; - - /* If there is already a ':', then we already have a baseclass, and - we must append this one after a comma. */ - for (l = info->stack->next->type; l != s; l++) - if (*l == ':') - break; - if (! prepend_type (info, l == s ? " : " : ", ")) - return false; - - t = pop_type (info); - if (t == NULL) - return false; - - n = (char *) xmalloc (strlen (info->stack->type) + strlen (t) + 1); - memcpy (n, info->stack->type, s - info->stack->type); - strcpy (n + (s - info->stack->type), t); - strcat (n, s); - - free (info->stack->type); - info->stack->type = n; - - free (t); - - return true; -} - -/* Start adding a method to a class. */ - -static boolean -pr_class_start_method (p, name) - PTR p; - const char *name; -{ - struct pr_handle *info = (struct pr_handle *) p; - - assert (info->stack != NULL); - info->stack->method = name; - return true; -} - -/* Add a variant to a method. */ - -static boolean -pr_class_method_variant (p, physname, visibility, constp, volatilep, voffset, - context) - PTR p; - const char *physname; - enum debug_visibility visibility; - boolean constp; - boolean volatilep; - bfd_vma voffset; - boolean context; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *method_type; - char *context_type; - - assert (info->stack != NULL); - assert (info->stack->next != NULL); - - /* Put the const and volatile qualifiers on the type. */ - if (volatilep) - { - if (! append_type (info, " volatile")) - return false; - } - if (constp) - { - if (! append_type (info, " const")) - return false; - } - - /* Stick the name of the method into its type. */ - if (! substitute_type (info, - (context - ? info->stack->next->next->method - : info->stack->next->method))) - return false; - - /* Get the type. */ - method_type = pop_type (info); - if (method_type == NULL) - return false; - - /* Pull off the context type if there is one. */ - if (! context) - context_type = NULL; - else - { - context_type = pop_type (info); - if (context_type == NULL) - return false; - } - - /* Now the top of the stack is the class. */ - - if (! pr_fix_visibility (info, visibility)) - return false; - - if (! append_type (info, method_type) - || ! append_type (info, " /* ") - || ! append_type (info, physname) - || ! append_type (info, " ")) - return false; - if (context || voffset != 0) - { - char ab[20]; - - if (context) - { - if (! append_type (info, "context ") - || ! append_type (info, context_type) - || ! append_type (info, " ")) - return false; - } - print_vma (voffset, ab, true, false); - if (! append_type (info, "voffset ") - || ! append_type (info, ab)) - return false; - } - - return (append_type (info, " */;\n") - && indent_type (info)); -} - -/* Add a static variant to a method. */ - -static boolean -pr_class_static_method_variant (p, physname, visibility, constp, volatilep) - PTR p; - const char *physname; - enum debug_visibility visibility; - boolean constp; - boolean volatilep; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *method_type; - - assert (info->stack != NULL); - assert (info->stack->next != NULL); - assert (info->stack->next->method != NULL); - - /* Put the const and volatile qualifiers on the type. */ - if (volatilep) - { - if (! append_type (info, " volatile")) - return false; - } - if (constp) - { - if (! append_type (info, " const")) - return false; - } - - /* Mark it as static. */ - if (! prepend_type (info, "static ")) - return false; - - /* Stick the name of the method into its type. */ - if (! substitute_type (info, info->stack->next->method)) - return false; - - /* Get the type. */ - method_type = pop_type (info); - if (method_type == NULL) - return false; - - /* Now the top of the stack is the class. */ - - if (! pr_fix_visibility (info, visibility)) - return false; - - return (append_type (info, method_type) - && append_type (info, " /* ") - && append_type (info, physname) - && append_type (info, " */;\n") - && indent_type (info)); -} - -/* Finish up a method. */ - -static boolean -pr_class_end_method (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - - info->stack->method = NULL; - return true; -} - -/* Finish up a class. */ - -static boolean -pr_end_class_type (p) - PTR p; -{ - return pr_end_struct_type (p); -} - -/* Push a type on the stack using a typedef name. */ - -static boolean -pr_typedef_type (p, name) - PTR p; - const char *name; -{ - struct pr_handle *info = (struct pr_handle *) p; - - return push_type (info, name); -} - -/* Push a type on the stack using a tag name. */ - -static boolean -pr_tag_type (p, name, id, kind) - PTR p; - const char *name; - unsigned int id; - enum debug_type_kind kind; -{ - struct pr_handle *info = (struct pr_handle *) p; - const char *t, *tag; - char idbuf[30]; - - switch (kind) - { - case DEBUG_KIND_STRUCT: - t = "struct "; - break; - case DEBUG_KIND_UNION: - t = "union "; - break; - case DEBUG_KIND_ENUM: - t = "enum "; - break; - case DEBUG_KIND_CLASS: - t = "class "; - break; - case DEBUG_KIND_UNION_CLASS: - t = "union class "; - break; - default: - abort (); - return false; - } - - if (! push_type (info, t)) - return false; - if (name != NULL) - tag = name; - else - { - sprintf (idbuf, "%%anon%u", id); - tag = idbuf; - } - - if (! append_type (info, tag)) - return false; - if (name != NULL && kind != DEBUG_KIND_ENUM) - { - sprintf (idbuf, " /* id %u */", id); - if (! append_type (info, idbuf)) - return false; - } - - return true; -} - -/* Output a typedef. */ - -static boolean -pr_typdef (p, name) - PTR p; - const char *name; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *s; - - if (! substitute_type (info, name)) - return false; - - s = pop_type (info); - if (s == NULL) - return false; -/* - indent (info); - TRACE_FPRINTF( (info->f, "typedef %s;\n", s)); -*/ - free (s); - - return true; -} - -/* Output a tag. The tag should already be in the string on the - stack, so all we have to do here is print it out. */ - -/*ARGSUSED*/ -static boolean -pr_tag (p, name) - PTR p; - const char *name; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - - t = pop_type (info); - if (t == NULL) - return false; -/* - indent (info); - TRACE_FPRINTF( (info->f, "%s;\n", t)); -*/ - free (t); - - return true; -} - -/* Output an integer constant. */ - -static boolean -pr_int_constant (p, name, val) - PTR p; - const char *name; - bfd_vma val; -{ -/* - struct pr_handle *info = (struct pr_handle *) p; - char ab[20]; - indent (info); - print_vma (val, ab, false, false); - TRACE_FPRINTF( (info->f, "const int %s = %s;\n", name, ab)); - */ - return true; -} - -/* Output a floating point constant. */ - -static boolean -pr_float_constant (p, name, val) - PTR p; - const char *name; - double val; -{ -/* - struct pr_handle *info = (struct pr_handle *) p; - indent (info); - TRACE_FPRINTF( (info->f, "const double %s = %g;\n", name, val)); - */ - return true; -} - -/* Output a typed constant. */ - -static boolean -pr_typed_constant (p, name, val) - PTR p; - const char *name; - bfd_vma val; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - - t = pop_type (info); - if (t == NULL) - return false; -/* - char ab[20]; - indent (info); - print_vma (val, ab, false, false); - TRACE_FPRINTF( (info->f, "const %s %s = %s;\n", t, name, ab)); -*/ - free (t); - - return true; -} - -/* Output a variable. */ - -static boolean -pr_variable (p, name, kind, val) - PTR p; - const char *name; - enum debug_var_kind kind; - bfd_vma val; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - char ab[20]; - (void)ab; - - if (! substitute_type (info, name)) - return false; - - t = pop_type (info); - if (t == NULL) - return false; - -#if 0 - indent (info); - switch (kind) - { - case DEBUG_STATIC: - case DEBUG_LOCAL_STATIC: - TRACE_FPRINTF( (info->f, "static ")); - break; - case DEBUG_REGISTER: - TRACE_FPRINTF( (info->f, "register ")); - break; - default: - break; - } - print_vma (val, ab, true, true); - TRACE_FPRINTF( (info->f, "%s /* %s */;\n", t, ab)); -#else /* 0 */ -#if 0 - if (kind==DEBUG_STATIC || kind==DEBUG_LOCAL_STATIC) { - print_vma (val, ab, true, true); - TRACE_FPRINTF( (info->f, "STATIC_VAR: %s /* %s */;\n", t, ab)); - } -#endif /* 0 */ -#endif /* !0 */ - - free (t); - - return true; -} - -/* Start outputting a function. */ - -static boolean -pr_start_function (p, name, global) - PTR p; - const char *name; - boolean global; -{ - struct pr_handle *info = (struct pr_handle *) p; - char *t; - - if (! substitute_type (info, name)) - return false; - - t = pop_type (info); - if (t == NULL) - return false; - -#if 0 - indent (info); - if (! global) - TRACE_FPRINTF( (info->f, "static ")); - TRACE_FPRINTF( (info->f, "%s (", t)); - info->parameter = 1; -#else /* 0 */ - if (info->functions_size==info->functions_maxsize) { - info->functions_maxsize *= 2; - info->functions = xrealloc(info->functions, - info->functions_maxsize*sizeof(debug_function_t)); - assert(info->functions!=0); - } - /* info->functions[info->functions_size] = xmalloc(sizeof(debug_function_t)); */ - info->function = &info->functions[info->functions_size]; - ++info->functions_size; - info->function->symbol = NULL; - info->function->lines = NULL; - info->function->lines_count = 0; - info->function->max_lines_count = 0; - info->function->name = t; - info->function->filename = NULL; - info->function->block = NULL; - info->function->argv = NULL; - info->function->argc = 0; - info->function->max_argc = 0; -#endif /* !0 */ - return true; -} - -/* Output a function parameter. */ - -static boolean -pr_function_parameter (p, name, kind, val) - PTR p; - const char *name; - enum debug_parm_kind kind; - bfd_vma val; -{ - struct pr_handle *info = (struct pr_handle *) p; - debug_function_t* f = info->function; - char *t; - char ab[20]; - (void)ab; - - if (kind == DEBUG_PARM_REFERENCE - || kind == DEBUG_PARM_REF_REG) - { - if (! pr_reference_type (p)) - return false; - } - - if (! substitute_type (info, name)) - return false; - - t = pop_type (info); - if (t == NULL) - return false; - -#if 0 - if (info->parameter != 1) - TRACE_FPRINTF( (info->f, ", ")); - - if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG) - TRACE_FPRINTF( (info->f, "register ")); - - print_vma (val, ab, true, true); - TRACE_FPRINTF( (info->f, "%s /* %s */", t, ab)); - free (t); - ++info->parameter; -#else /* 0 */ - assert(f!=NULL); - if (f->argv==NULL) { - f->max_argc = 7; /* rarely anyone has more than that many args... */ - f->argv = xmalloc(sizeof(debug_parameter_t)*f->max_argc); - } else if (f->argc==f->max_argc) { - f->max_argc *= 2; - f->argv = realloc(f->argv,sizeof(debug_parameter_t)*f->max_argc); - } - f->argv[f->argc].offset = val; - f->argv[f->argc].name = t; - ++f->argc; -#endif /* !0 */ - return true; -} - -/* Start writing out a block. */ - -static boolean -pr_start_block (p, addr) - PTR p; - bfd_vma addr; -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[20]; - debug_block_t* block = 0; - (void)ab; -#if 0 - if (info->parameter > 0) - { - TRACE_FPRINTF( (info->f, ")\n")); - info->parameter = 0; - } - indent (info); - print_vma (addr, ab, true, true); - TRACE_FPRINTF( (info->f, "{ /* %s */\n", ab)); - info->indent += 2; -#else - if (info->block) { - if (info->block->childs_count==0) - info->block->childs = xmalloc(sizeof(debug_block_t)); - else - info->block->childs = xrealloc(info->block->childs, - info->block->childs_count*sizeof(debug_block_t)); - block = &info->block->childs[info->block->childs_count]; - } else { - block = xmalloc(sizeof(debug_block_t)); - info->function->block = block; - } - block->begin_addr = addr; - block->end_addr = 0; - block->parent = info->block; - block->childs = NULL; - block->childs_count = 0; - info->block = block; -#endif - return true; -} - -/* Write out line number information. */ - -static boolean -pr_lineno (p, filename, lineno, addr) - PTR p; - const char *filename; - unsigned long lineno; - bfd_vma addr; -{ - struct pr_handle *info = (struct pr_handle *) p; - char ab[20]; - debug_function_t* f = info->function; - (void)ab; - -#if 0 - indent (info); - print_vma (addr, ab, true, true); - TRACE_FPRINTF( (info->f, "/* file %s line %lu addr %s */\n", filename, lineno, ab)); -#else /* 0 */ - if (f==NULL) /* FIXME: skips junk silently. */ - return true; - /* assert(f!=NULL); */ - if (f->filename==NULL) { - f->filename = filename; - assert(f->lines==0); - f->max_lines_count = 4; - f->lines = xmalloc(sizeof(debug_lineno_t)*f->max_lines_count); - } - if (f->lines_count==f->max_lines_count) { - f->max_lines_count *= 2; - f->lines = xrealloc(f->lines, sizeof(debug_lineno_t)*f->max_lines_count); - } - f->lines[f->lines_count].lineno = lineno; - f->lines[f->lines_count].addr = addr; - ++f->lines_count; -#endif /* !0 */ - - return true; -} - -/* Finish writing out a block. */ - -static boolean -pr_end_block (p, addr) - PTR p; - bfd_vma addr; -{ - struct pr_handle *info = (struct pr_handle *) p; - -#if 0 - char ab[20]; - - info->indent -= 2; - indent (info); - print_vma (addr, ab, true, true); - TRACE_FPRINTF( (info->f, "} /* %s */\n", ab)); -#else /* 0 */ - assert(info->block!=0); - info->block->end_addr = addr; - info->block = info->block->parent; -#endif /* !0 */ - - return true; -} - -/* Finish writing out a function. */ - -/*ARGSUSED*/ -static boolean -pr_end_function (p) - PTR p; -{ - struct pr_handle *info = (struct pr_handle *) p; - assert(info->block==0); - info->function = NULL; - return true; -} - -/* third parameter to segv_action. */ -/* Got it after a bit of head scratching and stack dumping. */ -typedef struct { - u_int32_t foo1; /* +0x00 */ - u_int32_t foo2; - u_int32_t foo3; - u_int32_t foo4; /* usually 2 */ - u_int32_t foo5; /* +0x10 */ - u_int32_t xgs; /* always zero */ - u_int32_t xfs; /* always zero */ - u_int32_t xes; /* always es=ds=ss */ - u_int32_t xds; /* +0x20 */ - u_int32_t edi; - u_int32_t esi; - u_int32_t ebp; - u_int32_t esp; /* +0x30 */ - u_int32_t ebx; - u_int32_t edx; - u_int32_t ecx; - u_int32_t eax; /* +0x40 */ - u_int32_t foo11; /* usually 0xe */ - u_int32_t foo12; /* usually 0x6 */ - u_int32_t eip; /* instruction pointer */ - u_int32_t xcs; /* +0x50 */ - u_int32_t foo21; /* usually 0x2 */ - u_int32_t foo22; /* second stack pointer?! Probably. */ - u_int32_t xss; - u_int32_t foo31; /* +0x60 */ /* usually 0x0 */ - u_int32_t foo32; /* usually 0x2 */ - u_int32_t fault_addr; /* Address which caused a fault */ - u_int32_t foo41; /* usually 0x2 */ -} signal_regs_t; - -signal_regs_t* ptrace_regs = 0; /* Tells my_ptrace to "ptrace" current process" */ -/* - * my_ptrace: small wrapper around ptrace. - * Act as normal ptrace if ptrace_regs==0. - * Read data from current process if ptrace_regs!=0. - */ -static int -my_ptrace( int request, - int pid, - int addr, - int data) -{ - if (ptrace_regs==0) - return ptrace(request, pid, addr, data); - /* we are tracing ourselves! */ - switch (request) { - case PTRACE_ATTACH: return 0; - case PTRACE_CONT: return 0; - case PTRACE_DETACH: return 0; - case PTRACE_PEEKUSER: - switch (addr / 4) { - case EIP: return ptrace_regs->eip; - case EBP: return ptrace_regs->ebp; - default: assert(0); - } - case PTRACE_PEEKTEXT: /* FALLTHROUGH */ - case PTRACE_PEEKDATA: return *(int*)(addr); - default: assert(0); - } - errno = 1; /* what to do here? */ - return 1; /* failed?! */ -} - -#define MAXARGS 6 - -/* - * To minimize the number of parameters. - */ -typedef struct { - asymbol** syms; /* Sorted! */ - int symcount; - debug_function_t** functions; - int functions_size; -} symbol_data_t; - -/* - * Perform a search. A binary search for a symbol. - */ -static void -decode_symbol( symbol_data_t* symbol_data, - const unsigned long addr, - char* buf, - const int bufsize) -{ - asymbol** syms = symbol_data->syms; - const int symcount = symbol_data->symcount; - int bottom = 0; - int top = symcount - 1; - int i; - if (symcount==0) { - sprintf(buf, "????"); - return; - } - while (top>bottom+1) { - i = (top+bottom) / 2; - if (bfd_asymbol_value(syms[i])==addr) { - sprintf(buf, "%s", syms[i]->name); - return; - } else if (bfd_asymbol_value(syms[i]) > addr) - top = i; - else - bottom = i; - } - i = bottom; - if (addr(syms[i]->section->vma+syms[i]->section->_cooked_size)) - sprintf(buf, "????"); - else - sprintf(buf, "%s + 0x%lx", syms[i]->name, addr-bfd_asymbol_value(syms[i])); -} - -/* - * 1. Perform a binary search for an debug_function_t. - * 2. Fill buf/bufsize with name, parameters and lineno, if found - * Or with '????' otherwise. - */ -static debug_function_t* -find_debug_function_t( symbol_data_t* symbol_data, - const pid_t pid, - const unsigned long fp, /* frame pointer */ - const unsigned long addr, - char* buf, /* string buffer */ - const int bufsize)/* FIXME: not used! */ -{ - debug_function_t** syms = symbol_data->functions; - debug_function_t* f = NULL; - debug_block_t* block = NULL; - debug_lineno_t* lineno = NULL; - const int symcount = symbol_data->functions_size; - int bottom = 0; - int top = symcount - 1; - int i; - char* bufptr = buf; - - if (symcount==0) { - sprintf(buf, "????"); - return NULL; - } - while (top>bottom+1) { - i = (top+bottom) / 2; - if (syms[i]->block->begin_addr==addr) { - f = syms[i]; - break; - } else if (syms[i]->block->begin_addr > addr) - top = i; - else - if (syms[i]->block->end_addr >= addr) { - f = syms[i]; - break; - } else - bottom = i; - } - i = bottom; - if (f!=0) - block = f->block; - else { - block = syms[i]->block; - if (block->begin_addr>=addr && block->end_addr<=addr) - f = syms[i]; - } - if (f==0) - sprintf(buf, "????"); - else { - /* - * Do the backtrace the GDB way... - */ - unsigned long arg; - /* assert(f->lines_count>0); */ - if (f->lines_count>0) { - lineno = &f->lines[f->lines_count-1]; - for (i=1; ilines_count; ++i) - if (f->lines[i].addr>addr) { - lineno = &f->lines[i-1]; - break; - } - } - bufptr[0] = 0; - bufptr += sprintf(bufptr, "%s+0x%lx (", f->name, addr-block->begin_addr); - for (i=0; iargc; ++i) { - bufptr += sprintf(bufptr, "%s = ", f->argv[i].name); - /* FIXME: better parameter printing */ - errno = 0; - arg = my_ptrace(PTRACE_PEEKDATA, pid, fp+f->argv[i].offset, 0); - assert(errno==0); - bufptr += sprintf(bufptr, "0x%x", arg); - if (i!=f->argc-1) - bufptr += sprintf(bufptr, ", "); - } - if (lineno!=0) - bufptr += sprintf(bufptr, ") at %s:%d", f->filename, lineno->lineno); - } - return f; -} - -/* - * Advance through the stacks and display frames as needed. - */ -static int -my_crawl( int pid, - symbol_data_t* symbol_data, - int fout) -{ - unsigned long pc = 0; - unsigned long fp = 0; - unsigned long nextfp; - unsigned long nargs; - unsigned long i; - unsigned long arg; - char buf[8096]; // FIXME: enough? - debug_function_t* f = 0; - - errno = 0; - - pc = my_ptrace(PTRACE_PEEKUSER, pid, EIP * 4, 0); - if (!errno) - fp = my_ptrace(PTRACE_PEEKUSER, pid, EBP * 4, 0); - - if (!errno) { -#if 1 - f = find_debug_function_t(symbol_data, pid, fp, pc, buf, sizeof(buf)); - fdprintf(fout,"0x%08lx: %s", pc, buf); - for ( ; !errno && fp; ) { - nextfp = my_ptrace(PTRACE_PEEKDATA, pid, fp, 0); - if (errno) - break; - - if (f==0) { - nargs = (nextfp - fp - 8) / 4; - if (nargs > MAXARGS) - nargs = MAXARGS; - if (nargs > 0) { - fdputs(" (", fout); - for (i = 1; i <= nargs; i++) { - arg = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4 * (i + 1), 0); - if (errno) - break; - fdprintf(fout,"%lx", arg); - if (i < nargs) - fdputs(", ", fout); - } - fdputc(')', fout); - nargs = nextfp - fp - 8 - (4 * nargs); - if (!errno && nargs > 0) - fdprintf(fout," + %lx\n", nargs); - else - fdputc('\n', fout); - } else - fdputc('\n', fout); - } else - fdputc('\n', fout); - - if (errno || !nextfp) - break; - pc = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4, 0); - fp = nextfp; - if (errno) - break; - f = find_debug_function_t(symbol_data, pid, fp, pc, buf, sizeof(buf)); - fdprintf(fout,"0x%08lx: %s", pc, buf); - } -#else /* 1 */ - decode_symbol(symbol_data, pc, buf, sizeof(buf)); - fdprintf(fout,"0x%08lx: %s", pc, buf); - for ( ; !errno && fp; ) { - nextfp = my_ptrace(PTRACE_PEEKDATA, pid, fp, 0); - if (errno) - break; - - nargs = (nextfp - fp - 8) / 4; - if (nargs > MAXARGS) - nargs = MAXARGS; - if (nargs > 0) { - fputs(" (", fout); - for (i = 1; i <= nargs; i++) { - arg = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4 * (i + 1), 0); - if (errno) - break; - fdprintf(fout,"%lx", arg); - if (i < nargs) - fputs(", ", fout); - } - fdputc(')', fout); - nargs = nextfp - fp - 8 - (4 * nargs); - if (!errno && nargs > 0) - fdprintf(fout," + %lx\n", nargs); - else - fdputc('\n', fout); - } else - fdputc('\n', fout); - - if (errno || !nextfp) - break; - pc = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4, 0); - fp = nextfp; - if (errno) - break; - decode_symbol(symbol_data, pc, buf, sizeof(buf)); - fdprintf(fout,"0x%08lx: %s", pc, buf); - } -#endif /* !1 */ - } - if (errno) - perror("my_crawl"); - return errno; -} - -/* layout from /usr/src/linux/arch/i386/kernel/process.c */ -static void -show_regs( signal_regs_t* regs, - int fd) -{ - /* long cr0 = 0L, cr2 = 0L, cr3 = 0L; */ - - fdprintf(fd,"\n"); - fdprintf(fd,"FAULT ADDR: %08x\n", regs->fault_addr); - fdprintf(fd,"EIP: %04x:[<%08x>]",0xffff & regs->xcs,regs->eip); - if (regs->xcs & 3) - fdprintf(fd," ESP: %04x:%08x",0xffff & regs->xss,regs->esp); - /*fdprintf(fd," EFLAGS: %08lx\n",regs->eflags); */ - fdprintf(fd, "\n"); - fdprintf(fd,"EAX: %08x EBX: %08x ECX: %08x EDX: %08x\n", - regs->eax,regs->ebx,regs->ecx,regs->edx); - fdprintf(fd,"ESI: %08x EDI: %08x EBP: %08x", - regs->esi, regs->edi, regs->ebp); - fdprintf(fd," DS: %04x ES: %04x\n", - 0xffff & regs->xds,0xffff & regs->xes); - /* - __asm__("movl %%cr0, %0": "=r" (cr0)); - __asm__("movl %%cr2, %0": "=r" (cr2)); - __asm__("movl %%cr3, %0": "=r" (cr3)); - fprintf(stderr,"CR0: %08lx CR2: %08lx CR3: %08lx\n", cr0, cr2, cr3); */ -} - -/* - * Load a BFD for an executable based on PID. Return 0 on failure. - */ -static bfd* -load_bfd( const int pid) -{ - char filename[512]; - bfd* abfd = 0; - - /* Get the contents from procfs. */ -#if 1 - sprintf(filename, "/proc/%d/exe", pid); -#else - sprintf(filename, "crashing"); -#endif - - if ((abfd = bfd_openr (filename, 0))== NULL) - bfd_nonfatal (filename); - else { - char** matching; - assert(bfd_check_format(abfd, bfd_archive)!=true); - - /* - * There is no indication in BFD documentation that it should be done. - * God knows why... - */ - if (!bfd_check_format_matches (abfd, bfd_object, &matching)) { - bfd_nonfatal (bfd_get_filename (abfd)); - if (bfd_get_error () == bfd_error_file_ambiguously_recognized) { - list_matching_formats (matching); - free (matching); - } - } - } - return abfd; -} - -/* - * Those are for qsort. We need only function addresses, so all the others don't count. - */ -/* - * Compare two BFD::asymbol-s. - */ -static int -compare_symbols(const void* ap, - const void* bp) -{ - const asymbol *a = *(const asymbol **)ap; - const asymbol *b = *(const asymbol **)bp; - if (bfd_asymbol_value (a) > bfd_asymbol_value (b)) - return 1; - else if (bfd_asymbol_value (a) < bfd_asymbol_value (b)) - return -1; - return 0; -} - -/* - * Compare two debug_asymbol_t-s. - */ -static int -compare_debug_function_t(const void* ap, - const void* bp) -{ - const debug_function_t *a = *(const debug_function_t **)ap; - const debug_function_t *b = *(const debug_function_t **)bp; - assert(a->block!=0); - assert(b->block!=0); - { - const bfd_vma addr1 = a->block->begin_addr; - const bfd_vma addr2 = b->block->begin_addr; - if (addr1 > addr2) - return 1; - else if (addr2 > addr1) - return -1; - } - return 0; -} - -/* - * Filter out (in place) symbols that are useless for stack tracing. - * COUNT is the number of elements in SYMBOLS. - * Return the number of useful symbols. - */ - -static long -remove_useless_symbols( asymbol** symbols, - long count) -{ - asymbol** in_ptr = symbols; - asymbol** out_ptr = symbols; - - while (--count >= 0) { - asymbol *sym = *in_ptr++; - - if (sym->name == NULL || sym->name[0] == '\0' || sym->value==0) - continue; - if (sym->flags & (BSF_DEBUGGING)) - continue; - if (bfd_is_und_section (sym->section) || bfd_is_com_section (sym->section)) - continue; - *out_ptr++ = sym; - } - return out_ptr - symbols; -} - -/* - * Debugging information. - */ -static bfd* abfd = 0; -static PTR dhandle = 0; -static asymbol** syms = 0; -static long symcount = 0; -static asymbol** sorted_syms = 0; -static long sorted_symcount = 0; -static debug_function_t** functions = 0; -static int functions_size = 0; -static int sigreport = SIGUSR1; -static pthread_t segv_tid; /* What thread did SEGV? */ -static pid_t segv_pid; - -/* - * We'll get here after a SIGSEGV. But you can install it on other signals, too :) - * Because we are in the middle of the SIGSEGV, we are on our own. We can't do - * any malloc(), any fopen(), nothing. The last is actually a sin. We event can't - * fprintf(stderr,...)!!! - */ -static void -segv_action(int signo, siginfo_t* siginfo, void* ptr) -{ - symbol_data_t symbol_data; - int fd = -1; - - segv_pid = getpid(); - segv_tid = pthread_self(); - fd = open_log_file(segv_tid, segv_pid); - /* signal(SIGSEGV, SIG_DFL); */ - ptrace_regs = (signal_regs_t*)ptr; - assert(ptrace_regs!=0); - - /* Show user how guilty we are. */ - fdprintf(fd,"--------- SEGV in PROCESS %d, THREAD %d ---------------\n", segv_pid, pthread_self()); - show_regs(ptrace_regs, fd); - - /* Some form of stack trace, too. */ - fdprintf(fd, "STACK TRACE:\n"); - - symbol_data.syms = sorted_syms; - symbol_data.symcount = sorted_symcount; - symbol_data.functions = functions; - symbol_data.functions_size = functions_size; - my_crawl(segv_pid, &symbol_data, fd); - //fflush(stdout); - close(fd); - linuxthreads_notify_others(sigreport); -} - - -static void -report_action(int signo, siginfo_t* siginfo, void* ptr) -{ - const int pid = getpid(); - pthread_t tid = pthread_self(); - symbol_data_t symbol_data; - int fd; - if (pthread_equal(tid, segv_tid)) { - /* We have already printed our stack trace... */ - return; - } - - fd = open_log_file(tid, pid); - fdprintf(fd, "REPORT: CURRENT PROCESS:%d, THREAD:%d\n", getpid(), pthread_self()); - /* signal(SIGSEGV, SIG_DFL); */ - ptrace_regs = (signal_regs_t*)ptr; - assert(ptrace_regs!=0); - - /* Show user how guilty we are. */ - fdprintf(fd,"--------- STACK TRACE FOR PROCESS %d, THREAD %d ---------------\n", pid, pthread_self()); - show_regs(ptrace_regs, fd); - - /* Some form of stack trace, too. */ - fdprintf(fd, "STACK TRACE:\n"); - - symbol_data.syms = sorted_syms; - symbol_data.symcount = sorted_symcount; - symbol_data.functions = functions; - symbol_data.functions_size = functions_size; - my_crawl(pid, &symbol_data, fd); - //fflush(stdout); - close(fd); - /* Tell segv_thread to proceed after pause(). */ - /*pthread_kill(segv_tid, sigreport); - kill(segv_pid, sigreport); - pthread_cancel(tid); */ -} - -/* - * Main library routine. Just call it on your program. - */ -int -pstack_install_segv_action( const char* path_format_) -{ - const int pid = getpid(); - struct sigaction act; - - /* Store what we have to for later usage. */ - path_format = path_format_; - - /* We need a signal action for SIGSEGV and sigreport ! */ - sigreport = SIGUSR1; - act.sa_handler = 0; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_SIGINFO|SA_ONESHOT; /* Just one SIGSEGV. */ - act.sa_sigaction = segv_action; - act.sa_restorer = NULL; - if (sigaction(SIGSEGV, &act, NULL)!=0) { - perror("sigaction"); - return 1; - } - act.sa_sigaction = report_action; - act.sa_flags = SA_SIGINFO; /* But many sigreports. */ - if (sigaction(sigreport, &act, NULL)!=0) { - perror("sigaction"); - return 1; - } - - /* And a little setup for libiberty. */ - program_name = "crashing"; - xmalloc_set_program_name (program_name); - - /* Umm, and initialize BFD, too */ - bfd_init(); -#if 0 - list_supported_targets(0, stdout); - set_default_bfd_target(); -#endif /* 0 */ - - if ((abfd = load_bfd(pid))==0) - fprintf(stderr, "BFD load failed..\n"); - else { - long storage_needed= (bfd_get_file_flags(abfd) & HAS_SYMS) ? - bfd_get_symtab_upper_bound (abfd) : 0; - long i; - (void)i; - - if (storage_needed < 0) - fprintf(stderr, "Symbol table size estimation failure.\n"); - else if (storage_needed > 0) { - syms = (asymbol **) xmalloc (storage_needed); - symcount = bfd_canonicalize_symtab (abfd, syms); - - TRACE_FPRINTF((stderr, "TOTAL: %ld SYMBOLS.\n", symcount)); - /* We need debugging info, too! */ - if (symcount==0 || (dhandle = read_debugging_info (abfd, syms, symcount))==0) - fprintf(stderr, "NO DEBUGGING INFORMATION FOUND.\n"); - - /* We make a copy of syms to sort. We don't want to sort syms - because that will screw up the relocs. */ - sorted_syms = (asymbol **) xmalloc (symcount * sizeof (asymbol *)); - memcpy (sorted_syms, syms, symcount * sizeof (asymbol *)); - -#if 0 - for (i=0; iname!=0 && strlen(syms[i]->name)>0 && syms[i]->value!=0) - printf("%08lx T %s\n", syms[i]->section->vma + syms[i]->value, syms[i]->name); -#endif - sorted_symcount = remove_useless_symbols (sorted_syms, symcount); - TRACE_FPRINTF((stderr, "SORTED: %ld SYMBOLS.\n", sorted_symcount)); - - /* Sort the symbols into section and symbol order */ - qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols); -#if 0 - for (i=0; iname!=0 && strlen(sorted_syms[i]->name)>0 && sorted_syms[i]->value!=0) - printf("%08lx T %s\n", sorted_syms[i]->section->vma + sorted_syms[i]->value, sorted_syms[i]->name); -#endif - /* We have symbols, we need debugging info somehow sorted out. */ - if (dhandle==0) { - fprintf(stderr, "STACK TRACE WILL BE UNCOMFORTABLE.\n"); - } else { - /* Start collecting the debugging information.... */ - struct pr_handle info; - - info.f = stdout; - info.indent = 0; - info.stack = NULL; - info.parameter = 0; - info.block = NULL; - info.function = NULL; - info.functions_size = 0; - info.functions_maxsize = 1000; - info.functions = (debug_function_t*)xmalloc(sizeof(debug_function_t)*info.functions_maxsize); - debug_write (dhandle, &pr_fns, (PTR) &info); - TRACE_FPRINTF((stdout, "\n%d DEBUG SYMBOLS\n", info.functions_size)); - assert(info.functions_size!=0); - functions = xmalloc(sizeof(debug_function_t*)*info.functions_size); - functions_size = info.functions_size; - for (i=0; ibegin_addr, info.functions[i].name); -#endif - fflush(stdout); - } - } else /* storage_needed == 0 */ - fprintf(stderr, "NO SYMBOLS FOUND.\n"); - } - return 0; -} - -/*********************************************************************/ -/*********************************************************************/ -/*********************************************************************/ diff --git a/pstack/pstack.h b/pstack/pstack.h deleted file mode 100644 index 4c4fad7e754..00000000000 --- a/pstack/pstack.h +++ /dev/null @@ -1,22 +0,0 @@ -/* $Header$ */ - -#ifndef pstack_pstack_h_ -#define pstack_pstack_h_ - -#include "pstacktrace.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Install the stack-trace-on-SEGV handler.... - */ -extern int -pstack_install_segv_action( const char* path_format); -#ifdef __cplusplus -} -#endif - -#endif /* pstack_pstack_h_ */ - diff --git a/pstack/pstacktrace.h b/pstack/pstacktrace.h deleted file mode 100644 index c884bcb9f87..00000000000 --- a/pstack/pstacktrace.h +++ /dev/null @@ -1,24 +0,0 @@ -/* $Header$ */ - -/* - * Debugging macros. - */ - -#ifndef pstacktrace_h_ -#define pstacktrace_h_ - -#define PSTACK_DEBUG 1 -#undef PSTACK_DEBUG - -#ifdef PSTACK_DEBUG -# define TRACE_PUTC(a) putc a -# define TRACE_FPUTS(a) fputs a -# define TRACE_FPRINTF(a) fprintf a -#else /* PSTACK_DEBUG */ -# define TRACE_PUTC(a) (void)0 -# define TRACE_FPUTS(a) (void)0 -# define TRACE_FPRINTF(a) (void)0 -#endif /* !PSTACK_DEBUG */ - -#endif /* pstacktrace_h_ */ - diff --git a/pstack/rddbg.c b/pstack/rddbg.c deleted file mode 100644 index be3dfc21c57..00000000000 --- a/pstack/rddbg.c +++ /dev/null @@ -1,462 +0,0 @@ -/* rddbg.c -- Read debugging information into a generic form. - Copyright (C) 1995, 96, 1997 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -/* This file reads debugging information into a generic form. This - file knows how to dig the debugging information out of an object - file. */ - -#include -#include "bucomm.h" -#include -#include "debug.h" -#include "budbg.h" - -static boolean read_section_stabs_debugging_info - PARAMS ((bfd *, asymbol **, long, PTR, boolean *)); -static boolean read_symbol_stabs_debugging_info - PARAMS ((bfd *, asymbol **, long, PTR, boolean *)); -static boolean read_ieee_debugging_info PARAMS ((bfd *, PTR, boolean *)); -static void save_stab PARAMS ((int, int, bfd_vma, const char *)); -static void stab_context PARAMS ((void)); -static void free_saved_stabs PARAMS ((void)); - -/* Read debugging information from a BFD. Returns a generic debugging - pointer. */ - -PTR -read_debugging_info (abfd, syms, symcount) - bfd *abfd; - asymbol **syms; - long symcount; -{ - PTR dhandle; - boolean found; - - dhandle = debug_init (); - if (dhandle == NULL) - return NULL; - - if (! read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, - &found)) - return NULL; - - if (bfd_get_flavour (abfd) == bfd_target_aout_flavour) - { - if (! read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, - &found)) - return NULL; - } - - if (bfd_get_flavour (abfd) == bfd_target_ieee_flavour) - { - if (! read_ieee_debugging_info (abfd, dhandle, &found)) - return NULL; - } - - /* Try reading the COFF symbols if we didn't find any stabs in COFF - sections. */ - if (! found - && bfd_get_flavour (abfd) == bfd_target_coff_flavour - && symcount > 0) - { -#if 0 -/* - * JZ: Do we need coff? - */ - if (! parse_coff (abfd, syms, symcount, dhandle)) -#else - fprintf (stderr, "%s: COFF support temporarily disabled\n", - bfd_get_filename (abfd)); - return NULL; -#endif - return NULL; - found = true; - } - - if (! found) - { - fprintf (stderr, "%s: no recognized debugging information\n", - bfd_get_filename (abfd)); - return NULL; - } - - return dhandle; -} - -/* Read stabs in sections debugging information from a BFD. */ - -static boolean -read_section_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound) - bfd *abfd; - asymbol **syms; - long symcount; - PTR dhandle; - boolean *pfound; -{ - static struct - { - const char *secname; - const char *strsecname; - } names[] = { { ".stab", ".stabstr" } }; - unsigned int i; - PTR shandle; - - *pfound = false; - shandle = NULL; - - for (i = 0; i < sizeof names / sizeof names[0]; i++) - { - asection *sec, *strsec; - - sec = bfd_get_section_by_name (abfd, names[i].secname); - strsec = bfd_get_section_by_name (abfd, names[i].strsecname); - if (sec != NULL && strsec != NULL) - { - bfd_size_type stabsize, strsize; - bfd_byte *stabs, *strings; - bfd_byte *stab; - bfd_size_type stroff, next_stroff; - - stabsize = bfd_section_size (abfd, sec); - stabs = (bfd_byte *) xmalloc (stabsize); - if (! bfd_get_section_contents (abfd, sec, stabs, 0, stabsize)) - { - fprintf (stderr, "%s: %s: %s\n", - bfd_get_filename (abfd), names[i].secname, - bfd_errmsg (bfd_get_error ())); - return false; - } - - strsize = bfd_section_size (abfd, strsec); - strings = (bfd_byte *) xmalloc (strsize); - if (! bfd_get_section_contents (abfd, strsec, strings, 0, strsize)) - { - fprintf (stderr, "%s: %s: %s\n", - bfd_get_filename (abfd), names[i].strsecname, - bfd_errmsg (bfd_get_error ())); - return false; - } - - if (shandle == NULL) - { - shandle = start_stab (dhandle, abfd, true, syms, symcount); - if (shandle == NULL) - return false; - } - - *pfound = true; - - stroff = 0; - next_stroff = 0; - for (stab = stabs; stab < stabs + stabsize; stab += 12) - { - bfd_size_type strx; - int type; - int other; - int desc; - bfd_vma value; - - /* This code presumes 32 bit values. */ - - strx = bfd_get_32 (abfd, stab); - type = bfd_get_8 (abfd, stab + 4); - other = bfd_get_8 (abfd, stab + 5); - desc = bfd_get_16 (abfd, stab + 6); - value = bfd_get_32 (abfd, stab + 8); - - if (type == 0) - { - /* Special type 0 stabs indicate the offset to the - next string table. */ - stroff = next_stroff; - next_stroff += value; - } - else - { - char *f, *s; - - f = NULL; - s = (char *) strings + stroff + strx; - while (s[strlen (s) - 1] == '\\' - && stab + 12 < stabs + stabsize) - { - char *p; - - stab += 12; - p = s + strlen (s) - 1; - *p = '\0'; - s = concat (s, - ((char *) strings - + stroff - + bfd_get_32 (abfd, stab)), - (const char *) NULL); - - /* We have to restore the backslash, because, if - the linker is hashing stabs strings, we may - see the same string more than once. */ - *p = '\\'; - - if (f != NULL) - free (f); - f = s; - } - - save_stab (type, desc, value, s); - - if (! parse_stab (dhandle, shandle, type, desc, value, s)) - { -#if 0 -/* - * JZ: skip the junk. - */ - stab_context (); - free_saved_stabs (); - return false; -#endif - } - - /* Don't free f, since I think the stabs code - expects strings to hang around. This should be - straightened out. FIXME. */ - } - } - - free_saved_stabs (); - free (stabs); - - /* Don't free strings, since I think the stabs code expects - the strings to hang around. This should be straightened - out. FIXME. */ - } - } - - if (shandle != NULL) - { - if (! finish_stab (dhandle, shandle)) - return false; - } - - return true; -} - -/* Read stabs in the symbol table. */ - -static boolean -read_symbol_stabs_debugging_info (abfd, syms, symcount, dhandle, pfound) - bfd *abfd; - asymbol **syms; - long symcount; - PTR dhandle; - boolean *pfound; -{ - PTR shandle; - asymbol **ps, **symend; - - shandle = NULL; - symend = syms + symcount; - for (ps = syms; ps < symend; ps++) - { - symbol_info i; - - bfd_get_symbol_info (abfd, *ps, &i); - - if (i.type == '-') - { - const char *s; - char *f; - - if (shandle == NULL) - { - shandle = start_stab (dhandle, abfd, false, syms, symcount); - if (shandle == NULL) - return false; - } - - *pfound = true; - - s = i.name; - f = NULL; - while (s[strlen (s) - 1] == '\\' - && ps + 1 < symend) - { - char *sc, *n; - - ++ps; - sc = xstrdup (s); - sc[strlen (sc) - 1] = '\0'; - n = concat (sc, bfd_asymbol_name (*ps), (const char *) NULL); - free (sc); - if (f != NULL) - free (f); - f = n; - s = n; - } - - save_stab (i.stab_type, i.stab_desc, i.value, s); - - if (! parse_stab (dhandle, shandle, i.stab_type, i.stab_desc, - i.value, s)) - { - stab_context (); - free_saved_stabs (); - return false; - } - - /* Don't free f, since I think the stabs code expects - strings to hang around. This should be straightened out. - FIXME. */ - } - } - - free_saved_stabs (); - - if (shandle != NULL) - { - if (! finish_stab (dhandle, shandle)) - return false; - } - - return true; -} - -/* Read IEEE debugging information. */ - -static boolean -read_ieee_debugging_info (abfd, dhandle, pfound) - bfd *abfd; - PTR dhandle; - boolean *pfound; -{ - asection *dsec; - bfd_size_type size; - bfd_byte *contents; - - /* The BFD backend puts the debugging information into a section - named .debug. */ - - dsec = bfd_get_section_by_name (abfd, ".debug"); - if (dsec == NULL) - return true; - - size = bfd_section_size (abfd, dsec); - contents = (bfd_byte *) xmalloc (size); - if (! bfd_get_section_contents (abfd, dsec, contents, 0, size)) - return false; - - if (! parse_ieee (dhandle, abfd, contents, size)) - return false; - - free (contents); - - *pfound = true; - - return true; -} - -/* Record stabs strings, so that we can give some context for errors. */ - -#define SAVE_STABS_COUNT (16) - -struct saved_stab -{ - int type; - int desc; - bfd_vma value; - char *string; -}; - -static struct saved_stab saved_stabs[SAVE_STABS_COUNT]; -static int saved_stabs_index; - -/* Save a stabs string. */ - -static void -save_stab (type, desc, value, string) - int type; - int desc; - bfd_vma value; - const char *string; -{ - if (saved_stabs[saved_stabs_index].string != NULL) - free (saved_stabs[saved_stabs_index].string); - saved_stabs[saved_stabs_index].type = type; - saved_stabs[saved_stabs_index].desc = desc; - saved_stabs[saved_stabs_index].value = value; - saved_stabs[saved_stabs_index].string = xstrdup (string); - saved_stabs_index = (saved_stabs_index + 1) % SAVE_STABS_COUNT; -} - -/* Provide context for an error. */ - -static void -stab_context () -{ - int i; - - fprintf (stderr, "Last stabs entries before error:\n"); - fprintf (stderr, "n_type n_desc n_value string\n"); - - i = saved_stabs_index; - do - { - struct saved_stab *stabp; - - stabp = saved_stabs + i; - if (stabp->string != NULL) - { - const char *s; - - s = bfd_get_stab_name (stabp->type); - if (s != NULL) - fprintf (stderr, "%-6s", s); - else if (stabp->type == 0) - fprintf (stderr, "HdrSym"); - else - fprintf (stderr, "%-6d", stabp->type); - fprintf (stderr, " %-6d ", stabp->desc); - fprintf_vma (stderr, stabp->value); - if (stabp->type != 0) - fprintf (stderr, " %s", stabp->string); - fprintf (stderr, "\n"); - } - i = (i + 1) % SAVE_STABS_COUNT; - } - while (i != saved_stabs_index); -} - -/* Free the saved stab strings. */ - -static void -free_saved_stabs () -{ - int i; - - for (i = 0; i < SAVE_STABS_COUNT; i++) - { - if (saved_stabs[i].string != NULL) - { - free (saved_stabs[i].string); - saved_stabs[i].string = NULL; - } - } - - saved_stabs_index = 0; -} diff --git a/pstack/stabs.c b/pstack/stabs.c deleted file mode 100644 index 076231d19cb..00000000000 --- a/pstack/stabs.c +++ /dev/null @@ -1,5082 +0,0 @@ -/* stabs.c -- Parse stabs debugging information - Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. - Written by Ian Lance Taylor . - - This file is part of GNU Binutils. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -/* This file contains code which parses stabs debugging information. - The organization of this code is based on the gdb stabs reading - code. The job it does is somewhat different, because it is not - trying to identify the correct address for anything. */ - -#include -#include - -#include -#include "bucomm.h" -#include -#include "demangle.h" -#include "debug.h" -#include "budbg.h" - -/* Meaningless definition needs by aout64.h. FIXME. */ -#define BYTES_IN_WORD 4 - -#include "aout/aout64.h" -#include "aout/stab_gnu.h" - -/* The number of predefined XCOFF types. */ - -#define XCOFF_TYPE_COUNT 34 - -/* This structure is used as a handle so that the stab parsing doesn't - need to use any static variables. */ - -struct stab_handle -{ - /* The BFD. */ - bfd *abfd; - /* True if this is stabs in sections. */ - boolean sections; - /* The symbol table. */ - asymbol **syms; - /* The number of symbols. */ - long symcount; - /* The accumulated file name string. */ - char *so_string; - /* The value of the last N_SO symbol. */ - bfd_vma so_value; - /* The value of the start of the file, so that we can handle file - relative N_LBRAC and N_RBRAC symbols. */ - bfd_vma file_start_offset; - /* The offset of the start of the function, so that we can handle - function relative N_LBRAC and N_RBRAC symbols. */ - bfd_vma function_start_offset; - /* The version number of gcc which compiled the current compilation - unit, 0 if not compiled by gcc. */ - int gcc_compiled; - /* Whether an N_OPT symbol was seen that was not generated by gcc, - so that we can detect the SunPRO compiler. */ - boolean n_opt_found; - /* The main file name. */ - char *main_filename; - /* A stack of unfinished N_BINCL files. */ - struct bincl_file *bincl_stack; - /* A list of finished N_BINCL files. */ - struct bincl_file *bincl_list; - /* Whether we are inside a function or not. */ - boolean within_function; - /* The address of the end of the function, used if we have seen an - N_FUN symbol while in a function. This is -1 if we have not seen - an N_FUN (the normal case). */ - bfd_vma function_end; - /* The depth of block nesting. */ - int block_depth; - /* List of pending variable definitions. */ - struct stab_pending_var *pending; - /* Number of files for which we have types. */ - unsigned int files; - /* Lists of types per file. */ - struct stab_types **file_types; - /* Predefined XCOFF types. */ - debug_type xcoff_types[XCOFF_TYPE_COUNT]; - /* Undefined tags. */ - struct stab_tag *tags; -}; - -/* A list of these structures is used to hold pending variable - definitions seen before the N_LBRAC of a block. */ - -struct stab_pending_var -{ - /* Next pending variable definition. */ - struct stab_pending_var *next; - /* Name. */ - const char *name; - /* Type. */ - debug_type type; - /* Kind. */ - enum debug_var_kind kind; - /* Value. */ - bfd_vma val; -}; - -/* A list of these structures is used to hold the types for a single - file. */ - -struct stab_types -{ - /* Next set of slots for this file. */ - struct stab_types *next; - /* Types indexed by type number. */ -#define STAB_TYPES_SLOTS (16) - debug_type types[STAB_TYPES_SLOTS]; -}; - -/* We keep a list of undefined tags that we encounter, so that we can - fill them in if the tag is later defined. */ - -struct stab_tag -{ - /* Next undefined tag. */ - struct stab_tag *next; - /* Tag name. */ - const char *name; - /* Type kind. */ - enum debug_type_kind kind; - /* Slot to hold real type when we discover it. If we don't, we fill - in an undefined tag type. */ - debug_type slot; - /* Indirect type we have created to point at slot. */ - debug_type type; -}; - -static char *savestring PARAMS ((const char *, int)); -static bfd_vma parse_number PARAMS ((const char **, boolean *)); -static void bad_stab PARAMS ((const char *)); -static void warn_stab PARAMS ((const char *, const char *)); -static boolean parse_stab_string - PARAMS ((PTR, struct stab_handle *, int, int, bfd_vma, const char *)); -static debug_type parse_stab_type - PARAMS ((PTR, struct stab_handle *, const char *, const char **, - debug_type **)); -static boolean parse_stab_type_number - PARAMS ((const char **, int *)); -static debug_type parse_stab_range_type - PARAMS ((PTR, struct stab_handle *, const char *, const char **, - const int *)); -static debug_type parse_stab_sun_builtin_type PARAMS ((PTR, const char **)); -static debug_type parse_stab_sun_floating_type - PARAMS ((PTR, const char **)); -static debug_type parse_stab_enum_type PARAMS ((PTR, const char **)); -static debug_type parse_stab_struct_type - PARAMS ((PTR, struct stab_handle *, const char *, const char **, boolean, - const int *)); -static boolean parse_stab_baseclasses - PARAMS ((PTR, struct stab_handle *, const char **, debug_baseclass **)); -static boolean parse_stab_struct_fields - PARAMS ((PTR, struct stab_handle *, const char **, debug_field **, - boolean *)); -static boolean parse_stab_cpp_abbrev - PARAMS ((PTR, struct stab_handle *, const char **, debug_field *)); -static boolean parse_stab_one_struct_field - PARAMS ((PTR, struct stab_handle *, const char **, const char *, - debug_field *, boolean *)); -static boolean parse_stab_members - PARAMS ((PTR, struct stab_handle *, const char *, const char **, - const int *, debug_method **)); -static debug_type parse_stab_argtypes - PARAMS ((PTR, struct stab_handle *, debug_type, const char *, const char *, - debug_type, const char *, boolean, boolean, const char **)); -static boolean parse_stab_tilde_field - PARAMS ((PTR, struct stab_handle *, const char **, const int *, - debug_type *, boolean *)); -static debug_type parse_stab_array_type - PARAMS ((PTR, struct stab_handle *, const char **, boolean)); -static void push_bincl PARAMS ((struct stab_handle *, const char *, bfd_vma)); -static const char *pop_bincl PARAMS ((struct stab_handle *)); -static boolean find_excl - PARAMS ((struct stab_handle *, const char *, bfd_vma)); -static boolean stab_record_variable - PARAMS ((PTR, struct stab_handle *, const char *, debug_type, - enum debug_var_kind, bfd_vma)); -static boolean stab_emit_pending_vars PARAMS ((PTR, struct stab_handle *)); -static debug_type *stab_find_slot - PARAMS ((struct stab_handle *, const int *)); -static debug_type stab_find_type - PARAMS ((PTR, struct stab_handle *, const int *)); -static boolean stab_record_type - PARAMS ((PTR, struct stab_handle *, const int *, debug_type)); -static debug_type stab_xcoff_builtin_type - PARAMS ((PTR, struct stab_handle *, int)); -static debug_type stab_find_tagged_type - PARAMS ((PTR, struct stab_handle *, const char *, int, - enum debug_type_kind)); -static debug_type *stab_demangle_argtypes - PARAMS ((PTR, struct stab_handle *, const char *, boolean *)); - -/* Save a string in memory. */ - -static char * -savestring (start, len) - const char *start; - int len; -{ - char *ret; - - ret = (char *) xmalloc (len + 1); - memcpy (ret, start, len); - ret[len] = '\0'; - return ret; -} - -/* Read a number from a string. */ - -static bfd_vma -parse_number (pp, poverflow) - const char **pp; - boolean *poverflow; -{ - unsigned long ul; - const char *orig; - - if (poverflow != NULL) - *poverflow = false; - - orig = *pp; - - errno = 0; - ul = strtoul (*pp, (char **) pp, 0); - if (ul + 1 != 0 || errno == 0) - return (bfd_vma) ul; - - /* Note that even though strtoul overflowed, it should have set *pp - to the end of the number, which is where we want it. */ - - if (sizeof (bfd_vma) > sizeof (unsigned long)) - { - const char *p; - boolean neg; - int base; - bfd_vma over, lastdig; - boolean overflow; - bfd_vma v; - - /* Our own version of strtoul, for a bfd_vma. */ - - p = orig; - - neg = false; - if (*p == '+') - ++p; - else if (*p == '-') - { - neg = true; - ++p; - } - - base = 10; - if (*p == '0') - { - if (p[1] == 'x' || p[1] == 'X') - { - base = 16; - p += 2; - } - else - { - base = 8; - ++p; - } - } - - over = ((bfd_vma) (bfd_signed_vma) -1) / (bfd_vma) base; - lastdig = ((bfd_vma) (bfd_signed_vma) -1) % (bfd_vma) base; - - overflow = false; - v = 0; - while (1) - { - int d; - - d = *p++; - if (isdigit ((unsigned char) d)) - d -= '0'; - else if (isupper ((unsigned char) d)) - d -= 'A'; - else if (islower ((unsigned char) d)) - d -= 'a'; - else - break; - - if (d >= base) - break; - - if (v > over || (v == over && (bfd_vma) d > lastdig)) - { - overflow = true; - break; - } - } - - if (! overflow) - { - if (neg) - v = - v; - return v; - } - } - - /* If we get here, the number is too large to represent in a - bfd_vma. */ - - if (poverflow != NULL) - *poverflow = true; - else - warn_stab (orig, "numeric overflow"); - - return 0; -} - -/* Give an error for a bad stab string. */ - -static void -bad_stab (p) - const char *p; -{ - fprintf (stderr, "Bad stab: %s\n", p); -} - -/* Warn about something in a stab string. */ - -static void -warn_stab (p, err) - const char *p; - const char *err; -{ - fprintf (stderr, "Warning: %s: %s\n", err, p); -} - -/* Create a handle to parse stabs symbols with. */ - -/*ARGSUSED*/ -PTR -start_stab (dhandle, abfd, sections, syms, symcount) - PTR dhandle; - bfd *abfd; - boolean sections; - asymbol **syms; - long symcount; -{ - struct stab_handle *ret; - - ret = (struct stab_handle *) xmalloc (sizeof *ret); - memset (ret, 0, sizeof *ret); - ret->abfd = abfd; - ret->sections = sections; - ret->syms = syms; - ret->symcount = symcount; - ret->files = 1; - ret->file_types = (struct stab_types **) xmalloc (sizeof *ret->file_types); - ret->file_types[0] = NULL; - ret->function_end = (bfd_vma) -1; - return (PTR) ret; -} - -/* When we have processed all the stabs information, we need to go - through and fill in all the undefined tags. */ - -boolean -finish_stab (dhandle, handle) - PTR dhandle; - PTR handle; -{ - struct stab_handle *info = (struct stab_handle *) handle; - struct stab_tag *st; - - if (info->within_function) - { - if (! stab_emit_pending_vars (dhandle, info) - || ! debug_end_function (dhandle, info->function_end)) - return false; - info->within_function = false; - info->function_end = (bfd_vma) -1; - } - - for (st = info->tags; st != NULL; st = st->next) - { - enum debug_type_kind kind; - - kind = st->kind; - if (kind == DEBUG_KIND_ILLEGAL) - kind = DEBUG_KIND_STRUCT; - st->slot = debug_make_undefined_tagged_type (dhandle, st->name, kind); - if (st->slot == DEBUG_TYPE_NULL) - return false; - } - - return true; -} - -/* Handle a single stabs symbol. */ - -boolean -parse_stab (dhandle, handle, type, desc, value, string) - PTR dhandle; - PTR handle; - int type; - int desc; - bfd_vma value; - const char *string; -{ - struct stab_handle *info = (struct stab_handle *) handle; - - /* gcc will emit two N_SO strings per compilation unit, one for the - directory name and one for the file name. We just collect N_SO - strings as we see them, and start the new compilation unit when - we see a non N_SO symbol. */ - if (info->so_string != NULL - && (type != N_SO || *string == '\0' || value != info->so_value)) - { - if (! debug_set_filename (dhandle, info->so_string)) - return false; - info->main_filename = info->so_string; - - info->gcc_compiled = 0; - info->n_opt_found = false; - - /* Generally, for stabs in the symbol table, the N_LBRAC and - N_RBRAC symbols are relative to the N_SO symbol value. */ - if (! info->sections) - info->file_start_offset = info->so_value; - - /* We need to reset the mapping from type numbers to types. We - can't free the old mapping, because of the use of - debug_make_indirect_type. */ - info->files = 1; - info->file_types = ((struct stab_types **) - xmalloc (sizeof *info->file_types)); - info->file_types[0] = NULL; - - info->so_string = NULL; - - /* Now process whatever type we just got. */ - } - - switch (type) - { - case N_FN: - case N_FN_SEQ: - break; - - case N_LBRAC: - /* Ignore extra outermost context from SunPRO cc and acc. */ - if (info->n_opt_found && desc == 1) - break; - - if (! info->within_function) - { - fprintf (stderr, "N_LBRAC not within function\n"); - return false; - } - - /* Start an inner lexical block. */ - if (! debug_start_block (dhandle, - (value - + info->file_start_offset - + info->function_start_offset))) - return false; - - /* Emit any pending variable definitions. */ - if (! stab_emit_pending_vars (dhandle, info)) - return false; - - ++info->block_depth; - break; - - case N_RBRAC: - /* Ignore extra outermost context from SunPRO cc and acc. */ - if (info->n_opt_found && desc == 1) - break; - - /* We shouldn't have any pending variable definitions here, but, - if we do, we probably need to emit them before closing the - block. */ - if (! stab_emit_pending_vars (dhandle, info)) - return false; - - /* End an inner lexical block. */ - if (! debug_end_block (dhandle, - (value - + info->file_start_offset - + info->function_start_offset))) - return false; - - --info->block_depth; - if (info->block_depth < 0) - { - fprintf (stderr, "Too many N_RBRACs\n"); - return false; - } - break; - - case N_SO: - /* This always ends a function. */ - if (info->within_function) - { - bfd_vma endval; - - endval = value; - if (*string != '\0' - && info->function_end != (bfd_vma) -1 - && info->function_end < endval) - endval = info->function_end; - if (! stab_emit_pending_vars (dhandle, info) - || ! debug_end_function (dhandle, endval)) - return false; - info->within_function = false; - info->function_end = (bfd_vma) -1; - } - - /* An empty string is emitted by gcc at the end of a compilation - unit. */ - if (*string == '\0') - return true; - - /* Just accumulate strings until we see a non N_SO symbol. If - the string starts with '/', we discard the previously - accumulated strings. */ - if (info->so_string == NULL) - info->so_string = xstrdup (string); - else - { - char *f; - - f = info->so_string; - if (*string == '/') - info->so_string = xstrdup (string); - else - info->so_string = concat (info->so_string, string, - (const char *) NULL); - free (f); - } - - info->so_value = value; - - break; - - case N_SOL: - /* Start an include file. */ - if (! debug_start_source (dhandle, string)) - return false; - break; - - case N_BINCL: - /* Start an include file which may be replaced. */ - push_bincl (info, string, value); - if (! debug_start_source (dhandle, string)) - return false; - break; - - case N_EINCL: - /* End an N_BINCL include. */ - if (! debug_start_source (dhandle, pop_bincl (info))) - return false; - break; - - case N_EXCL: - /* This is a duplicate of a header file named by N_BINCL which - was eliminated by the linker. */ - if (! find_excl (info, string, value)) - return false; - break; - - case N_SLINE: - if (! debug_record_line (dhandle, desc, - value + info->function_start_offset)) - return false; - break; - - case N_BCOMM: - if (! debug_start_common_block (dhandle, string)) - return false; - break; - - case N_ECOMM: - if (! debug_end_common_block (dhandle, string)) - return false; - break; - - case N_FUN: - if (*string == '\0') - { - if (info->within_function) - { - /* This always marks the end of a function; we don't - need to worry about info->function_end. */ - if (info->sections) - value += info->function_start_offset; - if (! stab_emit_pending_vars (dhandle, info) - || ! debug_end_function (dhandle, value)) - return false; - info->within_function = false; - info->function_end = (bfd_vma) -1; - } - break; - } - - /* A const static symbol in the .text section will have an N_FUN - entry. We need to use these to mark the end of the function, - in case we are looking at gcc output before it was changed to - always emit an empty N_FUN. We can't call debug_end_function - here, because it might be a local static symbol. */ - if (info->within_function - && (info->function_end == (bfd_vma) -1 - || value < info->function_end)) - info->function_end = value; - - /* Fall through. */ - /* FIXME: gdb checks the string for N_STSYM, N_LCSYM or N_ROSYM - symbols, and if it does not start with :S, gdb relocates the - value to the start of the section. gcc always seems to use - :S, so we don't worry about this. */ - /* Fall through. */ - default: - { - const char *colon; - - colon = strchr (string, ':'); - if (colon != NULL - && (colon[1] == 'f' || colon[1] == 'F')) - { - if (info->within_function) - { - bfd_vma endval; - - endval = value; - if (info->function_end != (bfd_vma) -1 - && info->function_end < endval) - endval = info->function_end; - if (! stab_emit_pending_vars (dhandle, info) - || ! debug_end_function (dhandle, endval)) - return false; - info->function_end = (bfd_vma) -1; - } - /* For stabs in sections, line numbers and block addresses - are offsets from the start of the function. */ - if (info->sections) - info->function_start_offset = value; - info->within_function = true; - } - - if (! parse_stab_string (dhandle, info, type, desc, value, string)) - return false; - } - break; - - case N_OPT: - if (string != NULL && strcmp (string, "gcc2_compiled.") == 0) - info->gcc_compiled = 2; - else if (string != NULL && strcmp (string, "gcc_compiled.") == 0) - info->gcc_compiled = 1; - else - info->n_opt_found = true; - break; - - case N_OBJ: - case N_ENDM: - case N_MAIN: - break; - } - - return true; -} - -/* Parse the stabs string. */ - -static boolean -parse_stab_string (dhandle, info, stabtype, desc, value, string) - PTR dhandle; - struct stab_handle *info; - int stabtype; - int desc; - bfd_vma value; - const char *string; -{ - const char *p; - char *name; - int type; - debug_type dtype; - boolean synonym; - unsigned int lineno; - debug_type *slot; - - p = strchr (string, ':'); - if (p == NULL) - return true; - - while (p[1] == ':') - { - p += 2; - p = strchr (p, ':'); - if (p == NULL) - { - bad_stab (string); - return false; - } - } - - /* GCC 2.x puts the line number in desc. SunOS apparently puts in - the number of bytes occupied by a type or object, which we - ignore. */ - if (info->gcc_compiled >= 2) - lineno = desc; - else - lineno = 0; - - /* FIXME: Sometimes the special C++ names start with '.'. */ - name = NULL; - if (string[0] == '$') - { - switch (string[1]) - { - case 't': - name = "this"; - break; - case 'v': - /* Was: name = "vptr"; */ - break; - case 'e': - name = "eh_throw"; - break; - case '_': - /* This was an anonymous type that was never fixed up. */ - break; - case 'X': - /* SunPRO (3.0 at least) static variable encoding. */ - break; - default: - warn_stab (string, "unknown C++ encoded name"); - break; - } - } - - if (name == NULL) - { - if (p == string || (string[0] == ' ' && p == string + 1)) - name = NULL; - else - name = savestring (string, p - string); - } - - ++p; - if (isdigit ((unsigned char) *p) || *p == '(' || *p == '-') - type = 'l'; - else - type = *p++; - - switch (type) - { - case 'c': - /* c is a special case, not followed by a type-number. - SYMBOL:c=iVALUE for an integer constant symbol. - SYMBOL:c=rVALUE for a floating constant symbol. - SYMBOL:c=eTYPE,INTVALUE for an enum constant symbol. - e.g. "b:c=e6,0" for "const b = blob1" - (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */ - if (*p != '=') - { - bad_stab (string); - return false; - } - ++p; - switch (*p++) - { - case 'r': - /* Floating point constant. */ - if (! debug_record_float_const (dhandle, name, atof (p))) - return false; - break; - case 'i': - /* Integer constant. */ - /* Defining integer constants this way is kind of silly, - since 'e' constants allows the compiler to give not only - the value, but the type as well. C has at least int, - long, unsigned int, and long long as constant types; - other languages probably should have at least unsigned as - well as signed constants. */ - if (! debug_record_int_const (dhandle, name, atoi (p))) - return false; - break; - case 'e': - /* SYMBOL:c=eTYPE,INTVALUE for a constant symbol whose value - can be represented as integral. - e.g. "b:c=e6,0" for "const b = blob1" - (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;"). */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, - &p, (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (*p != ',') - { - bad_stab (string); - return false; - } - if (! debug_record_typed_const (dhandle, name, dtype, atoi (p))) - return false; - break; - default: - bad_stab (string); - return false; - } - - break; - - case 'C': - /* The name of a caught exception. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, - &p, (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! debug_record_label (dhandle, name, dtype, value)) - return false; - break; - - case 'f': - case 'F': - /* A function definition. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! debug_record_function (dhandle, name, dtype, type == 'F', value)) - return false; - - /* Sun acc puts declared types of arguments here. We don't care - about their actual types (FIXME -- we should remember the whole - function prototype), but the list may define some new types - that we have to remember, so we must scan it now. */ - while (*p == ';') - { - ++p; - if (parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL) - == DEBUG_TYPE_NULL) - return false; - } - - break; - - case 'G': - { - char leading; - long c; - asymbol **ps; - - /* A global symbol. The value must be extracted from the - symbol table. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - leading = bfd_get_symbol_leading_char (info->abfd); - for (c = info->symcount, ps = info->syms; c > 0; --c, ++ps) - { - const char *n; - - n = bfd_asymbol_name (*ps); - if (leading != '\0' && *n == leading) - ++n; - if (*n == *name && strcmp (n, name) == 0) - break; - } - if (c > 0) - value = bfd_asymbol_value (*ps); - if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_GLOBAL, - value)) - return false; - } - break; - - /* This case is faked by a conditional above, when there is no - code letter in the dbx data. Dbx data never actually - contains 'l'. */ - case 'l': - case 's': - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL, - value)) - return false; - break; - - case 'p': - /* A function parameter. */ - if (*p != 'F') - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - else - { - /* pF is a two-letter code that means a function parameter in - Fortran. The type-number specifies the type of the return - value. Translate it into a pointer-to-function type. */ - ++p; - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype != DEBUG_TYPE_NULL) - { - debug_type ftype; - - ftype = debug_make_function_type (dhandle, dtype, - (debug_type *) NULL, false); - dtype = debug_make_pointer_type (dhandle, ftype); - } - } - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_STACK, - value)) - return false; - - /* FIXME: At this point gdb considers rearranging the parameter - address on a big endian machine if it is smaller than an int. - We have no way to do that, since we don't really know much - about the target. */ - - break; - - case 'P': - if (stabtype == N_FUN) - { - /* Prototype of a function referenced by this file. */ - while (*p == ';') - { - ++p; - if (parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL) - == DEBUG_TYPE_NULL) - return false; - } - break; - } - /* Fall through. */ - case 'R': - /* Parameter which is in a register. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REG, - value)) - return false; - break; - - case 'r': - /* Register variable (either global or local). */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_REGISTER, - value)) - return false; - - /* FIXME: At this point gdb checks to combine pairs of 'p' and - 'r' stabs into a single 'P' stab. */ - - break; - - case 'S': - /* Static symbol at top level of file */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_STATIC, - value)) - return false; - break; - - case 't': - /* A typedef. */ - dtype = parse_stab_type (dhandle, info, name, &p, &slot); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (name == NULL) - { - /* A nameless type. Nothing to do. */ - return true; - } - - dtype = debug_name_type (dhandle, name, dtype); - if (dtype == DEBUG_TYPE_NULL) - return false; - - if (slot != NULL) - *slot = dtype; - - break; - - case 'T': - /* Struct, union, or enum tag. For GNU C++, this can be be followed - by 't' which means we are typedef'ing it as well. */ - if (*p != 't') - { - synonym = false; - /* FIXME: gdb sets synonym to true if the current language - is C++. */ - } - else - { - synonym = true; - ++p; - } - - dtype = parse_stab_type (dhandle, info, name, &p, &slot); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (name == NULL) - return true; - - dtype = debug_tag_type (dhandle, name, dtype); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (slot != NULL) - *slot = dtype; - - /* See if we have a cross reference to this tag which we can now - fill in. */ - { - register struct stab_tag **pst; - - for (pst = &info->tags; *pst != NULL; pst = &(*pst)->next) - { - if ((*pst)->name[0] == name[0] - && strcmp ((*pst)->name, name) == 0) - { - (*pst)->slot = dtype; - *pst = (*pst)->next; - break; - } - } - } - - if (synonym) - { - dtype = debug_name_type (dhandle, name, dtype); - if (dtype == DEBUG_TYPE_NULL) - return false; - - if (slot != NULL) - *slot = dtype; - } - - break; - - case 'V': - /* Static symbol of local scope */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - /* FIXME: gdb checks os9k_stabs here. */ - if (! stab_record_variable (dhandle, info, name, dtype, - DEBUG_LOCAL_STATIC, value)) - return false; - break; - - case 'v': - /* Reference parameter. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REFERENCE, - value)) - return false; - break; - - case 'a': - /* Reference parameter which is in a register. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! debug_record_parameter (dhandle, name, dtype, DEBUG_PARM_REF_REG, - value)) - return false; - break; - - case 'X': - /* This is used by Sun FORTRAN for "function result value". - Sun claims ("dbx and dbxtool interfaces", 2nd ed) - that Pascal uses it too, but when I tried it Pascal used - "x:3" (local symbol) instead. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, &p, - (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return false; - if (! stab_record_variable (dhandle, info, name, dtype, DEBUG_LOCAL, - value)) - return false; - break; - - default: - bad_stab (string); - return false; - } - - /* FIXME: gdb converts structure values to structure pointers in a - couple of cases, depending upon the target. */ - - return true; -} - -/* Parse a stabs type. The typename argument is non-NULL if this is a - typedef or a tag definition. The pp argument points to the stab - string, and is updated. The slotp argument points to a place to - store the slot used if the type is being defined. */ - -static debug_type -parse_stab_type (dhandle, info, typename, pp, slotp) - PTR dhandle; - struct stab_handle *info; - const char *typename; - const char **pp; - debug_type **slotp; -{ - const char *orig; - int typenums[2]; - int size; - boolean stringp; - int descriptor; - debug_type dtype; - - if (slotp != NULL) - *slotp = NULL; - - orig = *pp; - - size = -1; - stringp = false; - - /* Read type number if present. The type number may be omitted. - for instance in a two-dimensional array declared with type - "ar1;1;10;ar1;1;10;4". */ - if (! isdigit ((unsigned char) **pp) && **pp != '(' && **pp != '-') - { - /* 'typenums=' not present, type is anonymous. Read and return - the definition, but don't put it in the type vector. */ - typenums[0] = typenums[1] = -1; - } - else - { - if (! parse_stab_type_number (pp, typenums)) - return DEBUG_TYPE_NULL; - - if (**pp != '=') - { - /* Type is not being defined here. Either it already - exists, or this is a forward reference to it. */ - return stab_find_type (dhandle, info, typenums); - } - - /* Only set the slot if the type is being defined. This means - that the mapping from type numbers to types will only record - the name of the typedef which defines a type. If we don't do - this, then something like - typedef int foo; - int i; - will record that i is of type foo. Unfortunately, stabs - information is ambiguous about variable types. For this code, - typedef int foo; - int i; - foo j; - the stabs information records both i and j as having the same - type. This could be fixed by patching the compiler. */ - if (slotp != NULL && typenums[0] >= 0 && typenums[1] >= 0) - *slotp = stab_find_slot (info, typenums); - - /* Type is being defined here. */ - /* Skip the '='. */ - ++*pp; - - while (**pp == '@') - { - const char *p = *pp + 1; - const char *attr; - - if (isdigit ((unsigned char) *p) || *p == '(' || *p == '-') - { - /* Member type. */ - break; - } - - /* Type attributes. */ - attr = p; - - for (; *p != ';'; ++p) - { - if (*p == '\0') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - } - *pp = p + 1; - - switch (*attr) - { - case 's': - size = atoi (attr + 1); - if (size <= 0) - size = -1; - break; - - case 'S': - stringp = true; - break; - - default: - /* Ignore unrecognized type attributes, so future - compilers can invent new ones. */ - break; - } - } - } - - descriptor = **pp; - ++*pp; - - switch (descriptor) - { - case 'x': - { - enum debug_type_kind code; - const char *q1, *q2, *p; - - /* A cross reference to another type. */ - - switch (**pp) - { - case 's': - code = DEBUG_KIND_STRUCT; - break; - case 'u': - code = DEBUG_KIND_UNION; - break; - case 'e': - code = DEBUG_KIND_ENUM; - break; - default: - /* Complain and keep going, so compilers can invent new - cross-reference types. */ - warn_stab (orig, "unrecognized cross reference type"); - code = DEBUG_KIND_STRUCT; - break; - } - ++*pp; - - q1 = strchr (*pp, '<'); - p = strchr (*pp, ':'); - if (p == NULL) - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - while (q1 != NULL && p > q1 && p[1] == ':') - { - q2 = strchr (q1, '>'); - if (q2 == NULL || q2 < p) - break; - p += 2; - p = strchr (p, ':'); - if (p == NULL) - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - } - - dtype = stab_find_tagged_type (dhandle, info, *pp, p - *pp, code); - - *pp = p + 1; - } - break; - - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '(': - { - const char *hold; - int xtypenums[2]; - - /* This type is defined as another type. */ - - (*pp)--; - hold = *pp; - - /* Peek ahead at the number to detect void. */ - if (! parse_stab_type_number (pp, xtypenums)) - return DEBUG_TYPE_NULL; - - if (typenums[0] == xtypenums[0] && typenums[1] == xtypenums[1]) - { - /* This type is being defined as itself, which means that - it is void. */ - dtype = debug_make_void_type (dhandle); - } - else - { - *pp = hold; - - /* Go back to the number and have parse_stab_type get it. - This means that we can deal with something like - t(1,2)=(3,4)=... which the Lucid compiler uses. */ - dtype = parse_stab_type (dhandle, info, (const char *) NULL, - pp, (debug_type **) NULL); - if (dtype == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - } - - if (typenums[0] != -1) - { - if (! stab_record_type (dhandle, info, typenums, dtype)) - return DEBUG_TYPE_NULL; - } - - break; - } - - case '*': - dtype = debug_make_pointer_type (dhandle, - parse_stab_type (dhandle, info, - (const char *) NULL, - pp, - (debug_type **) NULL)); - break; - - case '&': - /* Reference to another type. */ - dtype = (debug_make_reference_type - (dhandle, - parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL))); - break; - - case 'f': - /* Function returning another type. */ - /* FIXME: gdb checks os9k_stabs here. */ - dtype = (debug_make_function_type - (dhandle, - parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL), - (debug_type *) NULL, false)); - break; - - case 'k': - /* Const qualifier on some type (Sun). */ - /* FIXME: gdb accepts 'c' here if os9k_stabs. */ - dtype = debug_make_const_type (dhandle, - parse_stab_type (dhandle, info, - (const char *) NULL, - pp, - (debug_type **) NULL)); - break; - - case 'B': - /* Volatile qual on some type (Sun). */ - /* FIXME: gdb accepts 'i' here if os9k_stabs. */ - dtype = (debug_make_volatile_type - (dhandle, - parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL))); - break; - - case '@': - /* Offset (class & variable) type. This is used for a pointer - relative to an object. */ - { - debug_type domain; - debug_type memtype; - - /* Member type. */ - - domain = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (domain == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - - if (**pp != ',') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - memtype = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (memtype == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - - dtype = debug_make_offset_type (dhandle, domain, memtype); - } - break; - - case '#': - /* Method (class & fn) type. */ - if (**pp == '#') - { - debug_type return_type; - - ++*pp; - return_type = parse_stab_type (dhandle, info, (const char *) NULL, - pp, (debug_type **) NULL); - if (return_type == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - dtype = debug_make_method_type (dhandle, return_type, - DEBUG_TYPE_NULL, - (debug_type *) NULL, false); - } - else - { - debug_type domain; - debug_type return_type; - debug_type *args; - unsigned int n; - unsigned int alloc; - boolean varargs; - - domain = parse_stab_type (dhandle, info, (const char *) NULL, - pp, (debug_type **) NULL); - if (domain == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - - if (**pp != ',') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - return_type = parse_stab_type (dhandle, info, (const char *) NULL, - pp, (debug_type **) NULL); - if (return_type == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - - alloc = 10; - args = (debug_type *) xmalloc (alloc * sizeof *args); - n = 0; - while (**pp != ';') - { - if (**pp != ',') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - if (n + 1 >= alloc) - { - alloc += 10; - args = ((debug_type *) - xrealloc ((PTR) args, alloc * sizeof *args)); - } - - args[n] = parse_stab_type (dhandle, info, (const char *) NULL, - pp, (debug_type **) NULL); - if (args[n] == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - ++n; - } - ++*pp; - - /* If the last type is not void, then this function takes a - variable number of arguments. Otherwise, we must strip - the void type. */ - if (n == 0 - || debug_get_type_kind (dhandle, args[n - 1]) != DEBUG_KIND_VOID) - varargs = true; - else - { - --n; - varargs = false; - } - - args[n] = DEBUG_TYPE_NULL; - - dtype = debug_make_method_type (dhandle, return_type, domain, args, - varargs); - } - break; - - case 'r': - /* Range type. */ - dtype = parse_stab_range_type (dhandle, info, typename, pp, typenums); - break; - - case 'b': - /* FIXME: gdb checks os9k_stabs here. */ - /* Sun ACC builtin int type. */ - dtype = parse_stab_sun_builtin_type (dhandle, pp); - break; - - case 'R': - /* Sun ACC builtin float type. */ - dtype = parse_stab_sun_floating_type (dhandle, pp); - break; - - case 'e': - /* Enumeration type. */ - dtype = parse_stab_enum_type (dhandle, pp); - break; - - case 's': - case 'u': - /* Struct or union type. */ - dtype = parse_stab_struct_type (dhandle, info, typename, pp, - descriptor == 's', typenums); - break; - - case 'a': - /* Array type. */ - if (**pp != 'r') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - dtype = parse_stab_array_type (dhandle, info, pp, stringp); - break; - - case 'S': - dtype = debug_make_set_type (dhandle, - parse_stab_type (dhandle, info, - (const char *) NULL, - pp, - (debug_type **) NULL), - stringp); - break; - - default: - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - - if (dtype == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - - if (typenums[0] != -1) - { - if (! stab_record_type (dhandle, info, typenums, dtype)) - return DEBUG_TYPE_NULL; - } - - if (size != -1) - { - if (! debug_record_type_size (dhandle, dtype, (unsigned int) size)) - return DEBUG_TYPE_NULL; - } - - return dtype; -} - -/* Read a number by which a type is referred to in dbx data, or - perhaps read a pair (FILENUM, TYPENUM) in parentheses. Just a - single number N is equivalent to (0,N). Return the two numbers by - storing them in the vector TYPENUMS. */ - -static boolean -parse_stab_type_number (pp, typenums) - const char **pp; - int *typenums; -{ - const char *orig; - - orig = *pp; - - if (**pp != '(') - { - typenums[0] = 0; - typenums[1] = (int) parse_number (pp, (boolean *) NULL); - } - else - { - ++*pp; - typenums[0] = (int) parse_number (pp, (boolean *) NULL); - if (**pp != ',') - { - bad_stab (orig); - return false; - } - ++*pp; - typenums[1] = (int) parse_number (pp, (boolean *) NULL); - if (**pp != ')') - { - bad_stab (orig); - return false; - } - ++*pp; - } - - return true; -} - -/* Parse a range type. */ - -static debug_type -parse_stab_range_type (dhandle, info, typename, pp, typenums) - PTR dhandle; - struct stab_handle *info; - const char *typename; - const char **pp; - const int *typenums; -{ - const char *orig; - int rangenums[2]; - boolean self_subrange; - debug_type index_type; - const char *s2, *s3; - bfd_signed_vma n2, n3; - boolean ov2, ov3; - - orig = *pp; - - index_type = DEBUG_TYPE_NULL; - - /* First comes a type we are a subrange of. - In C it is usually 0, 1 or the type being defined. */ - if (! parse_stab_type_number (pp, rangenums)) - return DEBUG_TYPE_NULL; - - self_subrange = (rangenums[0] == typenums[0] - && rangenums[1] == typenums[1]); - - if (**pp == '=') - { - *pp = orig; - index_type = parse_stab_type (dhandle, info, (const char *) NULL, - pp, (debug_type **) NULL); - if (index_type == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - } - - if (**pp == ';') - ++*pp; - - /* The remaining two operands are usually lower and upper bounds of - the range. But in some special cases they mean something else. */ - s2 = *pp; - n2 = parse_number (pp, &ov2); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - s3 = *pp; - n3 = parse_number (pp, &ov3); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - if (ov2 || ov3) - { - /* gcc will emit range stabs for long long types. Handle this - as a special case. FIXME: This needs to be more general. */ -#define LLLOW "01000000000000000000000;" -#define LLHIGH "0777777777777777777777;" -#define ULLHIGH "01777777777777777777777;" - if (index_type == DEBUG_TYPE_NULL) - { - if (strncmp (s2, LLLOW, sizeof LLLOW - 1) == 0 - && strncmp (s3, LLHIGH, sizeof LLHIGH - 1) == 0) - return debug_make_int_type (dhandle, 8, false); - if (! ov2 - && n2 == 0 - && strncmp (s3, ULLHIGH, sizeof ULLHIGH - 1) == 0) - return debug_make_int_type (dhandle, 8, true); - } - - warn_stab (orig, "numeric overflow"); - } - - if (index_type == DEBUG_TYPE_NULL) - { - /* A type defined as a subrange of itself, with both bounds 0, - is void. */ - if (self_subrange && n2 == 0 && n3 == 0) - return debug_make_void_type (dhandle); - - /* A type defined as a subrange of itself, with n2 positive and - n3 zero, is a complex type, and n2 is the number of bytes. */ - if (self_subrange && n3 == 0 && n2 > 0) - return debug_make_complex_type (dhandle, n2); - - /* If n3 is zero and n2 is positive, this is a floating point - type, and n2 is the number of bytes. */ - if (n3 == 0 && n2 > 0) - return debug_make_float_type (dhandle, n2); - - /* If the upper bound is -1, this is an unsigned int. */ - if (n2 == 0 && n3 == -1) - { - /* When gcc is used with -gstabs, but not -gstabs+, it will emit - long long int:t6=r1;0;-1; - long long unsigned int:t7=r1;0;-1; - We hack here to handle this reasonably. */ - if (typename != NULL) - { - if (strcmp (typename, "long long int") == 0) - return debug_make_int_type (dhandle, 8, false); - else if (strcmp (typename, "long long unsigned int") == 0) - return debug_make_int_type (dhandle, 8, true); - } - /* FIXME: The size here really depends upon the target. */ - return debug_make_int_type (dhandle, 4, true); - } - - /* A range of 0 to 127 is char. */ - if (self_subrange && n2 == 0 && n3 == 127) - return debug_make_int_type (dhandle, 1, false); - - /* FIXME: gdb checks for the language CHILL here. */ - - if (n2 == 0) - { - if (n3 < 0) - return debug_make_int_type (dhandle, - n3, true); - else if (n3 == 0xff) - return debug_make_int_type (dhandle, 1, true); - else if (n3 == 0xffff) - return debug_make_int_type (dhandle, 2, true); - /* -1 is used for the upper bound of (4 byte) "unsigned int" - and "unsigned long", and we already checked for that, so - don't need to test for it here. */ - } - else if (n3 == 0 - && n2 < 0 - && (self_subrange || n2 == -8)) - return debug_make_int_type (dhandle, - n2, true); - else if (n2 == - n3 - 1) - { - if (n3 == 0x7f) - return debug_make_int_type (dhandle, 1, false); - else if (n3 == 0x7fff) - return debug_make_int_type (dhandle, 2, false); - else if (n3 == 0x7fffffff) - return debug_make_int_type (dhandle, 4, false); - } - } - - /* At this point I don't have the faintest idea how to deal with a - self_subrange type; I'm going to assume that this is used as an - idiom, and that all of them are special cases. So . . . */ - if (self_subrange) - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - - index_type = stab_find_type (dhandle, info, rangenums); - if (index_type == DEBUG_TYPE_NULL) - { - /* Does this actually ever happen? Is that why we are worrying - about dealing with it rather than just calling error_type? */ - warn_stab (orig, "missing index type"); - index_type = debug_make_int_type (dhandle, 4, false); - } - - return debug_make_range_type (dhandle, index_type, n2, n3); -} - -/* Sun's ACC uses a somewhat saner method for specifying the builtin - typedefs in every file (for int, long, etc): - - type = b ; ; - signed = u or s. Possible c in addition to u or s (for char?). - offset = offset from high order bit to start bit of type. - width is # bytes in object of this type, nbits is # bits in type. - - The width/offset stuff appears to be for small objects stored in - larger ones (e.g. `shorts' in `int' registers). We ignore it for now, - FIXME. */ - -static debug_type -parse_stab_sun_builtin_type (dhandle, pp) - PTR dhandle; - const char **pp; -{ - const char *orig; - boolean unsignedp; - bfd_vma bits; - - orig = *pp; - - switch (**pp) - { - case 's': - unsignedp = false; - break; - case 'u': - unsignedp = true; - break; - default: - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - /* For some odd reason, all forms of char put a c here. This is strange - because no other type has this honor. We can safely ignore this because - we actually determine 'char'acterness by the number of bits specified in - the descriptor. */ - if (**pp == 'c') - ++*pp; - - /* The first number appears to be the number of bytes occupied - by this type, except that unsigned short is 4 instead of 2. - Since this information is redundant with the third number, - we will ignore it. */ - (void) parse_number (pp, (boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - /* The second number is always 0, so ignore it too. */ - (void) parse_number (pp, (boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - /* The third number is the number of bits for this type. */ - bits = parse_number (pp, (boolean *) NULL); - - /* The type *should* end with a semicolon. If it are embedded - in a larger type the semicolon may be the only way to know where - the type ends. If this type is at the end of the stabstring we - can deal with the omitted semicolon (but we don't have to like - it). Don't bother to complain(), Sun's compiler omits the semicolon - for "void". */ - if (**pp == ';') - ++*pp; - - if (bits == 0) - return debug_make_void_type (dhandle); - - return debug_make_int_type (dhandle, bits / 8, unsignedp); -} - -/* Parse a builtin floating type generated by the Sun compiler. */ - -static debug_type -parse_stab_sun_floating_type (dhandle, pp) - PTR dhandle; - const char **pp; -{ - const char *orig; - bfd_vma details; - bfd_vma bytes; - - orig = *pp; - - /* The first number has more details about the type, for example - FN_COMPLEX. */ - details = parse_number (pp, (boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - - /* The second number is the number of bytes occupied by this type */ - bytes = parse_number (pp, (boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - - if (details == NF_COMPLEX - || details == NF_COMPLEX16 - || details == NF_COMPLEX32) - return debug_make_complex_type (dhandle, bytes); - - return debug_make_float_type (dhandle, bytes); -} - -/* Handle an enum type. */ - -static debug_type -parse_stab_enum_type (dhandle, pp) - PTR dhandle; - const char **pp; -{ - const char *orig; - const char **names; - bfd_signed_vma *values; - unsigned int n; - unsigned int alloc; - - orig = *pp; - - /* FIXME: gdb checks os9k_stabs here. */ - - /* The aix4 compiler emits an extra field before the enum members; - my guess is it's a type of some sort. Just ignore it. */ - if (**pp == '-') - { - while (**pp != ':') - ++*pp; - ++*pp; - } - - /* Read the value-names and their values. - The input syntax is NAME:VALUE,NAME:VALUE, and so on. - A semicolon or comma instead of a NAME means the end. */ - alloc = 10; - names = (const char **) xmalloc (alloc * sizeof *names); - values = (bfd_signed_vma *) xmalloc (alloc * sizeof *values); - n = 0; - while (**pp != '\0' && **pp != ';' && **pp != ',') - { - const char *p; - char *name; - bfd_signed_vma val; - - p = *pp; - while (*p != ':') - ++p; - - name = savestring (*pp, p - *pp); - - *pp = p + 1; - val = (bfd_signed_vma) parse_number (pp, (boolean *) NULL); - if (**pp != ',') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - if (n + 1 >= alloc) - { - alloc += 10; - names = ((const char **) - xrealloc ((PTR) names, alloc * sizeof *names)); - values = ((bfd_signed_vma *) - xrealloc ((PTR) values, alloc * sizeof *values)); - } - - names[n] = name; - values[n] = val; - ++n; - } - - names[n] = NULL; - values[n] = 0; - - if (**pp == ';') - ++*pp; - - return debug_make_enum_type (dhandle, names, values); -} - -/* Read the description of a structure (or union type) and return an object - describing the type. - - PP points to a character pointer that points to the next unconsumed token - in the the stabs string. For example, given stabs "A:T4=s4a:1,0,32;;", - *PP will point to "4a:1,0,32;;". */ - -static debug_type -parse_stab_struct_type (dhandle, info, tagname, pp, structp, typenums) - PTR dhandle; - struct stab_handle *info; - const char *tagname; - const char **pp; - boolean structp; - const int *typenums; -{ - const char *orig; - bfd_vma size; - debug_baseclass *baseclasses; - debug_field *fields; - boolean statics; - debug_method *methods; - debug_type vptrbase; - boolean ownvptr; - - orig = *pp; - - /* Get the size. */ - size = parse_number (pp, (boolean *) NULL); - - /* Get the other information. */ - if (! parse_stab_baseclasses (dhandle, info, pp, &baseclasses) - || ! parse_stab_struct_fields (dhandle, info, pp, &fields, &statics) - || ! parse_stab_members (dhandle, info, tagname, pp, typenums, &methods) - || ! parse_stab_tilde_field (dhandle, info, pp, typenums, &vptrbase, - &ownvptr)) - return DEBUG_TYPE_NULL; - - if (! statics - && baseclasses == NULL - && methods == NULL - && vptrbase == DEBUG_TYPE_NULL - && ! ownvptr) - return debug_make_struct_type (dhandle, structp, size, fields); - - return debug_make_object_type (dhandle, structp, size, fields, baseclasses, - methods, vptrbase, ownvptr); -} - -/* The stabs for C++ derived classes contain baseclass information which - is marked by a '!' character after the total size. This function is - called when we encounter the baseclass marker, and slurps up all the - baseclass information. - - Immediately following the '!' marker is the number of base classes that - the class is derived from, followed by information for each base class. - For each base class, there are two visibility specifiers, a bit offset - to the base class information within the derived class, a reference to - the type for the base class, and a terminating semicolon. - - A typical example, with two base classes, would be "!2,020,19;0264,21;". - ^^ ^ ^ ^ ^ ^ ^ - Baseclass information marker __________________|| | | | | | | - Number of baseclasses __________________________| | | | | | | - Visibility specifiers (2) ________________________| | | | | | - Offset in bits from start of class _________________| | | | | - Type number for base class ___________________________| | | | - Visibility specifiers (2) _______________________________| | | - Offset in bits from start of class ________________________| | - Type number of base class ____________________________________| - - Return true for success, false for failure. */ - -static boolean -parse_stab_baseclasses (dhandle, info, pp, retp) - PTR dhandle; - struct stab_handle *info; - const char **pp; - debug_baseclass **retp; -{ - const char *orig; - unsigned int c, i; - debug_baseclass *classes; - - *retp = NULL; - - orig = *pp; - - if (**pp != '!') - { - /* No base classes. */ - return true; - } - ++*pp; - - c = (unsigned int) parse_number (pp, (boolean *) NULL); - - if (**pp != ',') - { - bad_stab (orig); - return false; - } - ++*pp; - - classes = (debug_baseclass *) xmalloc ((c + 1) * sizeof (**retp)); - - for (i = 0; i < c; i++) - { - boolean virtual; - enum debug_visibility visibility; - bfd_vma bitpos; - debug_type type; - - switch (**pp) - { - case '0': - virtual = false; - break; - case '1': - virtual = true; - break; - default: - warn_stab (orig, "unknown virtual character for baseclass"); - virtual = false; - break; - } - ++*pp; - - switch (**pp) - { - case '0': - visibility = DEBUG_VISIBILITY_PRIVATE; - break; - case '1': - visibility = DEBUG_VISIBILITY_PROTECTED; - break; - case '2': - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - default: - warn_stab (orig, "unknown visibility character for baseclass"); - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - } - ++*pp; - - /* The remaining value is the bit offset of the portion of the - object corresponding to this baseclass. Always zero in the - absence of multiple inheritance. */ - bitpos = parse_number (pp, (boolean *) NULL); - if (**pp != ',') - { - bad_stab (orig); - return false; - } - ++*pp; - - type = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (type == DEBUG_TYPE_NULL) - return false; - - classes[i] = debug_make_baseclass (dhandle, type, bitpos, virtual, - visibility); - if (classes[i] == DEBUG_BASECLASS_NULL) - return false; - - if (**pp != ';') - return false; - ++*pp; - } - - classes[i] = DEBUG_BASECLASS_NULL; - - *retp = classes; - - return true; -} - -/* Read struct or class data fields. They have the form: - - NAME : [VISIBILITY] TYPENUM , BITPOS , BITSIZE ; - - At the end, we see a semicolon instead of a field. - - In C++, this may wind up being NAME:?TYPENUM:PHYSNAME; for - a static field. - - The optional VISIBILITY is one of: - - '/0' (VISIBILITY_PRIVATE) - '/1' (VISIBILITY_PROTECTED) - '/2' (VISIBILITY_PUBLIC) - '/9' (VISIBILITY_IGNORE) - - or nothing, for C style fields with public visibility. - - Returns 1 for success, 0 for failure. */ - -static boolean -parse_stab_struct_fields (dhandle, info, pp, retp, staticsp) - PTR dhandle; - struct stab_handle *info; - const char **pp; - debug_field **retp; - boolean *staticsp; -{ - const char *orig; - const char *p; - debug_field *fields; - unsigned int c; - unsigned int alloc; - - *retp = NULL; - *staticsp = false; - - orig = *pp; - - c = 0; - alloc = 10; - fields = (debug_field *) xmalloc (alloc * sizeof *fields); - while (**pp != ';') - { - /* FIXME: gdb checks os9k_stabs here. */ - - p = *pp; - - /* Add 1 to c to leave room for NULL pointer at end. */ - if (c + 1 >= alloc) - { - alloc += 10; - fields = ((debug_field *) - xrealloc ((PTR) fields, alloc * sizeof *fields)); - } - - /* If it starts with CPLUS_MARKER it is a special abbreviation, - unless the CPLUS_MARKER is followed by an underscore, in - which case it is just the name of an anonymous type, which we - should handle like any other type name. We accept either '$' - or '.', because a field name can never contain one of these - characters except as a CPLUS_MARKER. */ - - if ((*p == '$' || *p == '.') && p[1] != '_') - { - ++*pp; - if (! parse_stab_cpp_abbrev (dhandle, info, pp, fields + c)) - return false; - ++c; - continue; - } - - /* Look for the ':' that separates the field name from the field - values. Data members are delimited by a single ':', while member - functions are delimited by a pair of ':'s. When we hit the member - functions (if any), terminate scan loop and return. */ - - p = strchr (p, ':'); - if (p == NULL) - { - bad_stab (orig); - return false; - } - - if (p[1] == ':') - break; - - if (! parse_stab_one_struct_field (dhandle, info, pp, p, fields + c, - staticsp)) - return false; - - ++c; - } - - fields[c] = DEBUG_FIELD_NULL; - - *retp = fields; - - return true; -} - -/* Special GNU C++ name. */ - -static boolean -parse_stab_cpp_abbrev (dhandle, info, pp, retp) - PTR dhandle; - struct stab_handle *info; - const char **pp; - debug_field *retp; -{ - const char *orig; - int cpp_abbrev; - debug_type context; - const char *name; - const char *typename; - debug_type type; - bfd_vma bitpos; - - *retp = DEBUG_FIELD_NULL; - - orig = *pp; - - if (**pp != 'v') - { - bad_stab (*pp); - return false; - } - ++*pp; - - cpp_abbrev = **pp; - ++*pp; - - /* At this point, *pp points to something like "22:23=*22...", where - the type number before the ':' is the "context" and everything - after is a regular type definition. Lookup the type, find it's - name, and construct the field name. */ - - context = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (context == DEBUG_TYPE_NULL) - return false; - - switch (cpp_abbrev) - { - case 'f': - /* $vf -- a virtual function table pointer. */ - name = "_vptr$"; - break; - case 'b': - /* $vb -- a virtual bsomethingorother */ - typename = debug_get_type_name (dhandle, context); - if (typename == NULL) - { - warn_stab (orig, "unnamed $vb type"); - typename = "FOO"; - } - name = concat ("_vb$", typename, (const char *) NULL); - break; - default: - warn_stab (orig, "unrecognized C++ abbreviation"); - name = "INVALID_CPLUSPLUS_ABBREV"; - break; - } - - if (**pp != ':') - { - bad_stab (orig); - return false; - } - ++*pp; - - type = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (**pp != ',') - { - bad_stab (orig); - return false; - } - ++*pp; - - bitpos = parse_number (pp, (boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return false; - } - ++*pp; - - *retp = debug_make_field (dhandle, name, type, bitpos, 0, - DEBUG_VISIBILITY_PRIVATE); - if (*retp == DEBUG_FIELD_NULL) - return false; - - return true; -} - -/* Parse a single field in a struct or union. */ - -static boolean -parse_stab_one_struct_field (dhandle, info, pp, p, retp, staticsp) - PTR dhandle; - struct stab_handle *info; - const char **pp; - const char *p; - debug_field *retp; - boolean *staticsp; -{ - const char *orig; - char *name; - enum debug_visibility visibility; - debug_type type; - bfd_vma bitpos; - bfd_vma bitsize; - - orig = *pp; - - /* FIXME: gdb checks ARM_DEMANGLING here. */ - - name = savestring (*pp, p - *pp); - - *pp = p + 1; - - if (**pp != '/') - visibility = DEBUG_VISIBILITY_PUBLIC; - else - { - ++*pp; - switch (**pp) - { - case '0': - visibility = DEBUG_VISIBILITY_PRIVATE; - break; - case '1': - visibility = DEBUG_VISIBILITY_PROTECTED; - break; - case '2': - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - default: - warn_stab (orig, "unknown visibility character for field"); - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - } - ++*pp; - } - - type = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (type == DEBUG_TYPE_NULL) - return false; - - if (**pp == ':') - { - char *varname; - - /* This is a static class member. */ - ++*pp; - p = strchr (*pp, ';'); - if (p == NULL) - { - bad_stab (orig); - return false; - } - - varname = savestring (*pp, p - *pp); - - *pp = p + 1; - - *retp = debug_make_static_member (dhandle, name, type, varname, - visibility); - *staticsp = true; - - return true; - } - - if (**pp != ',') - { - bad_stab (orig); - return false; - } - ++*pp; - - bitpos = parse_number (pp, (boolean *) NULL); - if (**pp != ',') - { - bad_stab (orig); - return false; - } - ++*pp; - - bitsize = parse_number (pp, (boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return false; - } - ++*pp; - - if (bitpos == 0 && bitsize == 0) - { - /* This can happen in two cases: (1) at least for gcc 2.4.5 or - so, it is a field which has been optimized out. The correct - stab for this case is to use VISIBILITY_IGNORE, but that is a - recent invention. (2) It is a 0-size array. For example - union { int num; char str[0]; } foo. Printing "" - for str in "p foo" is OK, since foo.str (and thus foo.str[3]) - will continue to work, and a 0-size array as a whole doesn't - have any contents to print. - - I suspect this probably could also happen with gcc -gstabs - (not -gstabs+) for static fields, and perhaps other C++ - extensions. Hopefully few people use -gstabs with gdb, since - it is intended for dbx compatibility. */ - visibility = DEBUG_VISIBILITY_IGNORE; - } - - /* FIXME: gdb does some stuff here to mark fields as unpacked. */ - - *retp = debug_make_field (dhandle, name, type, bitpos, bitsize, visibility); - - return true; -} - -/* Read member function stabs info for C++ classes. The form of each member - function data is: - - NAME :: TYPENUM[=type definition] ARGS : PHYSNAME ; - - An example with two member functions is: - - afunc1::20=##15;:i;2A.;afunc2::20:i;2A.; - - For the case of overloaded operators, the format is op$::*.funcs, where - $ is the CPLUS_MARKER (usually '$'), `*' holds the place for an operator - name (such as `+=') and `.' marks the end of the operator name. */ - -static boolean -parse_stab_members (dhandle, info, tagname, pp, typenums, retp) - PTR dhandle; - struct stab_handle *info; - const char *tagname; - const char **pp; - const int *typenums; - debug_method **retp; -{ - const char *orig; - debug_method *methods; - unsigned int c; - unsigned int alloc; - - *retp = NULL; - - orig = *pp; - - alloc = 0; - methods = NULL; - c = 0; - - while (**pp != ';') - { - const char *p; - char *name; - debug_method_variant *variants; - unsigned int cvars; - unsigned int allocvars; - debug_type look_ahead_type; - - p = strchr (*pp, ':'); - if (p == NULL || p[1] != ':') - break; - - /* FIXME: Some systems use something other than '$' here. */ - if ((*pp)[0] != 'o' || (*pp)[1] != 'p' || (*pp)[2] != '$') - { - name = savestring (*pp, p - *pp); - *pp = p + 2; - } - else - { - /* This is a completely wierd case. In order to stuff in the - names that might contain colons (the usual name delimiter), - Mike Tiemann defined a different name format which is - signalled if the identifier is "op$". In that case, the - format is "op$::XXXX." where XXXX is the name. This is - used for names like "+" or "=". YUUUUUUUK! FIXME! */ - *pp = p + 2; - for (p = *pp; *p != '.' && *p != '\0'; p++) - ; - if (*p != '.') - { - bad_stab (orig); - return false; - } - name = savestring (*pp, p - *pp); - *pp = p + 1; - } - - allocvars = 10; - variants = ((debug_method_variant *) - xmalloc (allocvars * sizeof *variants)); - cvars = 0; - - look_ahead_type = DEBUG_TYPE_NULL; - - do - { - debug_type type; - boolean stub; - char *argtypes; - enum debug_visibility visibility; - boolean constp, volatilep, staticp; - bfd_vma voffset; - debug_type context; - const char *physname; - boolean varargs; - - if (look_ahead_type != DEBUG_TYPE_NULL) - { - /* g++ version 1 kludge */ - type = look_ahead_type; - look_ahead_type = DEBUG_TYPE_NULL; - } - else - { - type = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (type == DEBUG_TYPE_NULL) - return false; - if (**pp != ':') - { - bad_stab (orig); - return false; - } - } - - ++*pp; - p = strchr (*pp, ';'); - if (p == NULL) - { - bad_stab (orig); - return false; - } - - stub = false; - if (debug_get_type_kind (dhandle, type) == DEBUG_KIND_METHOD - && debug_get_parameter_types (dhandle, type, &varargs) == NULL) - stub = true; - - argtypes = savestring (*pp, p - *pp); - *pp = p + 1; - - switch (**pp) - { - case '0': - visibility = DEBUG_VISIBILITY_PRIVATE; - break; - case '1': - visibility = DEBUG_VISIBILITY_PROTECTED; - break; - default: - visibility = DEBUG_VISIBILITY_PUBLIC; - break; - } - ++*pp; - - constp = false; - volatilep = false; - switch (**pp) - { - case 'A': - /* Normal function. */ - ++*pp; - break; - case 'B': - /* const member function. */ - constp = true; - ++*pp; - break; - case 'C': - /* volatile member function. */ - volatilep = true; - ++*pp; - break; - case 'D': - /* const volatile member function. */ - constp = true; - volatilep = true; - ++*pp; - break; - case '*': - case '?': - case '.': - /* File compiled with g++ version 1; no information. */ - break; - default: - warn_stab (orig, "const/volatile indicator missing"); - break; - } - - staticp = false; - switch (**pp) - { - case '*': - /* virtual member function, followed by index. The sign - bit is supposedly set to distinguish - pointers-to-methods from virtual function indicies. */ - ++*pp; - voffset = parse_number (pp, (boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return false; - } - ++*pp; - voffset &= 0x7fffffff; - - if (**pp == ';' || *pp == '\0') - { - /* Must be g++ version 1. */ - context = DEBUG_TYPE_NULL; - } - else - { - /* Figure out from whence this virtual function - came. It may belong to virtual function table of - one of its baseclasses. */ - look_ahead_type = parse_stab_type (dhandle, info, - (const char *) NULL, - pp, - (debug_type **) NULL); - if (**pp == ':') - { - /* g++ version 1 overloaded methods. */ - context = DEBUG_TYPE_NULL; - } - else - { - context = look_ahead_type; - look_ahead_type = DEBUG_TYPE_NULL; - if (**pp != ';') - { - bad_stab (orig); - return false; - } - ++*pp; - } - } - break; - - case '?': - /* static member function. */ - ++*pp; - staticp = true; - voffset = 0; - context = DEBUG_TYPE_NULL; - if (strncmp (argtypes, name, strlen (name)) != 0) - stub = true; - break; - - default: - warn_stab (orig, "member function type missing"); - voffset = 0; - context = DEBUG_TYPE_NULL; - break; - - case '.': - ++*pp; - voffset = 0; - context = DEBUG_TYPE_NULL; - break; - } - - /* If the type is not a stub, then the argtypes string is - the physical name of the function. Otherwise the - argtypes string is the mangled form of the argument - types, and the full type and the physical name must be - extracted from them. */ - if (! stub) - physname = argtypes; - else - { - debug_type class_type, return_type; - - class_type = stab_find_type (dhandle, info, typenums); - if (class_type == DEBUG_TYPE_NULL) - return false; - return_type = debug_get_return_type (dhandle, type); - if (return_type == DEBUG_TYPE_NULL) - { - bad_stab (orig); - return false; - } - type = parse_stab_argtypes (dhandle, info, class_type, name, - tagname, return_type, argtypes, - constp, volatilep, &physname); - if (type == DEBUG_TYPE_NULL) - return false; - } - - if (cvars + 1 >= allocvars) - { - allocvars += 10; - variants = ((debug_method_variant *) - xrealloc ((PTR) variants, - allocvars * sizeof *variants)); - } - - if (! staticp) - variants[cvars] = debug_make_method_variant (dhandle, physname, - type, visibility, - constp, volatilep, - voffset, context); - else - variants[cvars] = debug_make_static_method_variant (dhandle, - physname, - type, - visibility, - constp, - volatilep); - if (variants[cvars] == DEBUG_METHOD_VARIANT_NULL) - return false; - - ++cvars; - } - while (**pp != ';' && **pp != '\0'); - - variants[cvars] = DEBUG_METHOD_VARIANT_NULL; - - if (**pp != '\0') - ++*pp; - - if (c + 1 >= alloc) - { - alloc += 10; - methods = ((debug_method *) - xrealloc ((PTR) methods, alloc * sizeof *methods)); - } - - methods[c] = debug_make_method (dhandle, name, variants); - - ++c; - } - - if (methods != NULL) - methods[c] = DEBUG_METHOD_NULL; - - *retp = methods; - - return true; -} - -/* Parse a string representing argument types for a method. Stabs - tries to save space by packing argument types into a mangled - string. This string should give us enough information to extract - both argument types and the physical name of the function, given - the tag name. */ - -static debug_type -parse_stab_argtypes (dhandle, info, class_type, fieldname, tagname, - return_type, argtypes, constp, volatilep, pphysname) - PTR dhandle; - struct stab_handle *info; - debug_type class_type; - const char *fieldname; - const char *tagname; - debug_type return_type; - const char *argtypes; - boolean constp; - boolean volatilep; - const char **pphysname; -{ - boolean is_full_physname_constructor; - boolean is_constructor; - boolean is_destructor; - debug_type *args; - boolean varargs; - - /* Constructors are sometimes handled specially. */ - is_full_physname_constructor = ((argtypes[0] == '_' - && argtypes[1] == '_' - && (isdigit ((unsigned char) argtypes[2]) - || argtypes[2] == 'Q' - || argtypes[2] == 't')) - || strncmp (argtypes, "__ct", 4) == 0); - - is_constructor = (is_full_physname_constructor - || (tagname != NULL - && strcmp (fieldname, tagname) == 0)); - is_destructor = ((argtypes[0] == '_' - && (argtypes[1] == '$' || argtypes[1] == '.') - && argtypes[2] == '_') - || strncmp (argtypes, "__dt", 4) == 0); - - if (is_destructor || is_full_physname_constructor) - *pphysname = argtypes; - else - { - unsigned int len; - const char *const_prefix; - const char *volatile_prefix; - char buf[20]; - unsigned int mangled_name_len; - char *physname; - - len = tagname == NULL ? 0 : strlen (tagname); - const_prefix = constp ? "C" : ""; - volatile_prefix = volatilep ? "V" : ""; - - if (len == 0) - sprintf (buf, "__%s%s", const_prefix, volatile_prefix); - else if (tagname != NULL && strchr (tagname, '<') != NULL) - { - /* Template methods are fully mangled. */ - sprintf (buf, "__%s%s", const_prefix, volatile_prefix); - tagname = NULL; - len = 0; - } - else - sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len); - - mangled_name_len = ((is_constructor ? 0 : strlen (fieldname)) - + strlen (buf) - + len - + strlen (argtypes) - + 1); - - if (fieldname[0] == 'o' - && fieldname[1] == 'p' - && (fieldname[2] == '$' || fieldname[2] == '.')) - { - const char *opname; - - opname = cplus_mangle_opname (fieldname + 3, 0); - if (opname == NULL) - { - fprintf (stderr, "No mangling for \"%s\"\n", fieldname); - return DEBUG_TYPE_NULL; - } - mangled_name_len += strlen (opname); - physname = (char *) xmalloc (mangled_name_len); - strncpy (physname, fieldname, 3); - strcpy (physname + 3, opname); - } - else - { - physname = (char *) xmalloc (mangled_name_len); - if (is_constructor) - physname[0] = '\0'; - else - strcpy (physname, fieldname); - } - - strcat (physname, buf); - if (tagname != NULL) - strcat (physname, tagname); - strcat (physname, argtypes); - - *pphysname = physname; - } - - if (*argtypes == '\0' || is_destructor) - { - args = (debug_type *) xmalloc (sizeof *args); - *args = NULL; - return debug_make_method_type (dhandle, return_type, class_type, args, - false); - } - - args = stab_demangle_argtypes (dhandle, info, *pphysname, &varargs); - if (args == NULL) - return DEBUG_TYPE_NULL; - - return debug_make_method_type (dhandle, return_type, class_type, args, - varargs); -} - -/* The tail end of stabs for C++ classes that contain a virtual function - pointer contains a tilde, a %, and a type number. - The type number refers to the base class (possibly this class itself) which - contains the vtable pointer for the current class. - - This function is called when we have parsed all the method declarations, - so we can look for the vptr base class info. */ - -static boolean -parse_stab_tilde_field (dhandle, info, pp, typenums, retvptrbase, retownvptr) - PTR dhandle; - struct stab_handle *info; - const char **pp; - const int *typenums; - debug_type *retvptrbase; - boolean *retownvptr; -{ - const char *orig; - const char *hold; - int vtypenums[2]; - - *retvptrbase = DEBUG_TYPE_NULL; - *retownvptr = false; - - orig = *pp; - - /* If we are positioned at a ';', then skip it. */ - if (**pp == ';') - ++*pp; - - if (**pp != '~') - return true; - - ++*pp; - - if (**pp == '=' || **pp == '+' || **pp == '-') - { - /* Obsolete flags that used to indicate the presence of - constructors and/or destructors. */ - ++*pp; - } - - if (**pp != '%') - return true; - - ++*pp; - - hold = *pp; - - /* The next number is the type number of the base class (possibly - our own class) which supplies the vtable for this class. */ - if (! parse_stab_type_number (pp, vtypenums)) - return false; - - if (vtypenums[0] == typenums[0] - && vtypenums[1] == typenums[1]) - *retownvptr = true; - else - { - debug_type vtype; - const char *p; - - *pp = hold; - - vtype = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - for (p = *pp; *p != ';' && *p != '\0'; p++) - ; - if (*p != ';') - { - bad_stab (orig); - return false; - } - - *retvptrbase = vtype; - - *pp = p + 1; - } - - return true; -} - -/* Read a definition of an array type. */ - -static debug_type -parse_stab_array_type (dhandle, info, pp, stringp) - PTR dhandle; - struct stab_handle *info; - const char **pp; - boolean stringp; -{ - const char *orig; - const char *p; - int typenums[2]; - debug_type index_type; - boolean adjustable; - bfd_signed_vma lower, upper; - debug_type element_type; - - /* Format of an array type: - "ar;lower;upper;". - OS9000: "arlower,upper;". - - Fortran adjustable arrays use Adigits or Tdigits for lower or upper; - for these, produce a type like float[][]. */ - - orig = *pp; - - /* FIXME: gdb checks os9k_stabs here. */ - - /* If the index type is type 0, we take it as int. */ - p = *pp; - if (! parse_stab_type_number (&p, typenums)) - return DEBUG_TYPE_NULL; - if (typenums[0] == 0 && typenums[1] == 0 && **pp != '=') - { - index_type = debug_find_named_type (dhandle, "int"); - if (index_type == DEBUG_TYPE_NULL) - { - index_type = debug_make_int_type (dhandle, 4, false); - if (index_type == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - } - *pp = p; - } - else - { - index_type = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - } - - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - adjustable = false; - - if (! isdigit ((unsigned char) **pp) && **pp != '-') - { - ++*pp; - adjustable = true; - } - - lower = (bfd_signed_vma) parse_number (pp, (boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - if (! isdigit ((unsigned char) **pp) && **pp != '-') - { - ++*pp; - adjustable = true; - } - - upper = (bfd_signed_vma) parse_number (pp, (boolean *) NULL); - if (**pp != ';') - { - bad_stab (orig); - return DEBUG_TYPE_NULL; - } - ++*pp; - - element_type = parse_stab_type (dhandle, info, (const char *) NULL, pp, - (debug_type **) NULL); - if (element_type == DEBUG_TYPE_NULL) - return DEBUG_TYPE_NULL; - - if (adjustable) - { - lower = 0; - upper = -1; - } - - return debug_make_array_type (dhandle, element_type, index_type, lower, - upper, stringp); -} - -/* This struct holds information about files we have seen using - N_BINCL. */ - -struct bincl_file -{ - /* The next N_BINCL file. */ - struct bincl_file *next; - /* The next N_BINCL on the stack. */ - struct bincl_file *next_stack; - /* The file name. */ - const char *name; - /* The hash value. */ - bfd_vma hash; - /* The file index. */ - unsigned int file; - /* The list of types defined in this file. */ - struct stab_types *file_types; -}; - -/* Start a new N_BINCL file, pushing it onto the stack. */ - -static void -push_bincl (info, name, hash) - struct stab_handle *info; - const char *name; - bfd_vma hash; -{ - struct bincl_file *n; - - n = (struct bincl_file *) xmalloc (sizeof *n); - n->next = info->bincl_list; - n->next_stack = info->bincl_stack; - n->name = name; - n->hash = hash; - n->file = info->files; - n->file_types = NULL; - info->bincl_list = n; - info->bincl_stack = n; - - ++info->files; - info->file_types = ((struct stab_types **) - xrealloc ((PTR) info->file_types, - (info->files - * sizeof *info->file_types))); - info->file_types[n->file] = NULL; -} - -/* Finish an N_BINCL file, at an N_EINCL, popping the name off the - stack. */ - -static const char * -pop_bincl (info) - struct stab_handle *info; -{ - struct bincl_file *o; - - o = info->bincl_stack; - if (o == NULL) - return info->main_filename; - info->bincl_stack = o->next_stack; - - o->file_types = info->file_types[o->file]; - - if (info->bincl_stack == NULL) - return info->main_filename; - return info->bincl_stack->name; -} - -/* Handle an N_EXCL: get the types from the corresponding N_BINCL. */ - -static boolean -find_excl (info, name, hash) - struct stab_handle *info; - const char *name; - bfd_vma hash; -{ - struct bincl_file *l; - - ++info->files; - info->file_types = ((struct stab_types **) - xrealloc ((PTR) info->file_types, - (info->files - * sizeof *info->file_types))); - - for (l = info->bincl_list; l != NULL; l = l->next) - if (l->hash == hash && strcmp (l->name, name) == 0) - break; - if (l == NULL) - { - warn_stab (name, "Undefined N_EXCL"); - info->file_types[info->files - 1] = NULL; - return true; - } - - info->file_types[info->files - 1] = l->file_types; - - return true; -} - -/* Handle a variable definition. gcc emits variable definitions for a - block before the N_LBRAC, so we must hold onto them until we see - it. The SunPRO compiler emits variable definitions after the - N_LBRAC, so we can call debug_record_variable immediately. */ - -static boolean -stab_record_variable (dhandle, info, name, type, kind, val) - PTR dhandle; - struct stab_handle *info; - const char *name; - debug_type type; - enum debug_var_kind kind; - bfd_vma val; -{ - struct stab_pending_var *v; - - if ((kind == DEBUG_GLOBAL || kind == DEBUG_STATIC) - || ! info->within_function - || (info->gcc_compiled == 0 && info->n_opt_found)) - return debug_record_variable (dhandle, name, type, kind, val); - - v = (struct stab_pending_var *) xmalloc (sizeof *v); - memset (v, 0, sizeof *v); - - v->next = info->pending; - v->name = name; - v->type = type; - v->kind = kind; - v->val = val; - info->pending = v; - - return true; -} - -/* Emit pending variable definitions. This is called after we see the - N_LBRAC that starts the block. */ - -static boolean -stab_emit_pending_vars (dhandle, info) - PTR dhandle; - struct stab_handle *info; -{ - struct stab_pending_var *v; - - v = info->pending; - while (v != NULL) - { - struct stab_pending_var *next; - - if (! debug_record_variable (dhandle, v->name, v->type, v->kind, v->val)) - return false; - - next = v->next; - free (v); - v = next; - } - - info->pending = NULL; - - return true; -} - -/* Find the slot for a type in the database. */ - -static debug_type * -stab_find_slot (info, typenums) - struct stab_handle *info; - const int *typenums; -{ - int filenum; - int index; - struct stab_types **ps; - - filenum = typenums[0]; - index = typenums[1]; - - if (filenum < 0 || (unsigned int) filenum >= info->files) - { - fprintf (stderr, "Type file number %d out of range\n", filenum); - return NULL; - } - if (index < 0) - { - fprintf (stderr, "Type index number %d out of range\n", index); - return NULL; - } - - ps = info->file_types + filenum; - - while (index >= STAB_TYPES_SLOTS) - { - if (*ps == NULL) - { - *ps = (struct stab_types *) xmalloc (sizeof **ps); - memset (*ps, 0, sizeof **ps); - } - ps = &(*ps)->next; - index -= STAB_TYPES_SLOTS; - } - if (*ps == NULL) - { - *ps = (struct stab_types *) xmalloc (sizeof **ps); - memset (*ps, 0, sizeof **ps); - } - - return (*ps)->types + index; -} - -/* Find a type given a type number. If the type has not been - allocated yet, create an indirect type. */ - -static debug_type -stab_find_type (dhandle, info, typenums) - PTR dhandle; - struct stab_handle *info; - const int *typenums; -{ - debug_type *slot; - - if (typenums[0] == 0 && typenums[1] < 0) - { - /* A negative type number indicates an XCOFF builtin type. */ - return stab_xcoff_builtin_type (dhandle, info, typenums[1]); - } - - slot = stab_find_slot (info, typenums); - if (slot == NULL) - return DEBUG_TYPE_NULL; - - if (*slot == DEBUG_TYPE_NULL) - return debug_make_indirect_type (dhandle, slot, (const char *) NULL); - - return *slot; -} - -/* Record that a given type number refers to a given type. */ - -static boolean -stab_record_type (dhandle, info, typenums, type) - PTR dhandle; - struct stab_handle *info; - const int *typenums; - debug_type type; -{ - debug_type *slot; - - slot = stab_find_slot (info, typenums); - if (slot == NULL) - return false; - - /* gdb appears to ignore type redefinitions, so we do as well. */ - - *slot = type; - - return true; -} - -/* Return an XCOFF builtin type. */ - -static debug_type -stab_xcoff_builtin_type (dhandle, info, typenum) - PTR dhandle; - struct stab_handle *info; - int typenum; -{ - debug_type rettype; - const char *name; - - if (typenum >= 0 || typenum < -XCOFF_TYPE_COUNT) - { - fprintf (stderr, "Unrecognized XCOFF type %d\n", typenum); - return DEBUG_TYPE_NULL; - } - if (info->xcoff_types[-typenum] != NULL) - return info->xcoff_types[-typenum]; - - switch (-typenum) - { - case 1: - /* The size of this and all the other types are fixed, defined - by the debugging format. */ - name = "int"; - rettype = debug_make_int_type (dhandle, 4, false); - break; - case 2: - name = "char"; - rettype = debug_make_int_type (dhandle, 1, false); - break; - case 3: - name = "short"; - rettype = debug_make_int_type (dhandle, 2, false); - break; - case 4: - name = "long"; - rettype = debug_make_int_type (dhandle, 4, false); - break; - case 5: - name = "unsigned char"; - rettype = debug_make_int_type (dhandle, 1, true); - break; - case 6: - name = "signed char"; - rettype = debug_make_int_type (dhandle, 1, false); - break; - case 7: - name = "unsigned short"; - rettype = debug_make_int_type (dhandle, 2, true); - break; - case 8: - name = "unsigned int"; - rettype = debug_make_int_type (dhandle, 4, true); - break; - case 9: - name = "unsigned"; - rettype = debug_make_int_type (dhandle, 4, true); - case 10: - name = "unsigned long"; - rettype = debug_make_int_type (dhandle, 4, true); - break; - case 11: - name = "void"; - rettype = debug_make_void_type (dhandle); - break; - case 12: - /* IEEE single precision (32 bit). */ - name = "float"; - rettype = debug_make_float_type (dhandle, 4); - break; - case 13: - /* IEEE double precision (64 bit). */ - name = "double"; - rettype = debug_make_float_type (dhandle, 8); - break; - case 14: - /* This is an IEEE double on the RS/6000, and different machines - with different sizes for "long double" should use different - negative type numbers. See stabs.texinfo. */ - name = "long double"; - rettype = debug_make_float_type (dhandle, 8); - break; - case 15: - name = "integer"; - rettype = debug_make_int_type (dhandle, 4, false); - break; - case 16: - name = "boolean"; - rettype = debug_make_bool_type (dhandle, 4); - break; - case 17: - name = "short real"; - rettype = debug_make_float_type (dhandle, 4); - break; - case 18: - name = "real"; - rettype = debug_make_float_type (dhandle, 8); - break; - case 19: - /* FIXME */ - name = "stringptr"; - rettype = NULL; - break; - case 20: - /* FIXME */ - name = "character"; - rettype = debug_make_int_type (dhandle, 1, true); - break; - case 21: - name = "logical*1"; - rettype = debug_make_bool_type (dhandle, 1); - break; - case 22: - name = "logical*2"; - rettype = debug_make_bool_type (dhandle, 2); - break; - case 23: - name = "logical*4"; - rettype = debug_make_bool_type (dhandle, 4); - break; - case 24: - name = "logical"; - rettype = debug_make_bool_type (dhandle, 4); - break; - case 25: - /* Complex type consisting of two IEEE single precision values. */ - name = "complex"; - rettype = debug_make_complex_type (dhandle, 8); - break; - case 26: - /* Complex type consisting of two IEEE double precision values. */ - name = "double complex"; - rettype = debug_make_complex_type (dhandle, 16); - break; - case 27: - name = "integer*1"; - rettype = debug_make_int_type (dhandle, 1, false); - break; - case 28: - name = "integer*2"; - rettype = debug_make_int_type (dhandle, 2, false); - break; - case 29: - name = "integer*4"; - rettype = debug_make_int_type (dhandle, 4, false); - break; - case 30: - /* FIXME */ - name = "wchar"; - rettype = debug_make_int_type (dhandle, 2, false); - break; - case 31: - name = "long long"; - rettype = debug_make_int_type (dhandle, 8, false); - break; - case 32: - name = "unsigned long long"; - rettype = debug_make_int_type (dhandle, 8, true); - break; - case 33: - name = "logical*8"; - rettype = debug_make_bool_type (dhandle, 8); - break; - case 34: - name = "integer*8"; - rettype = debug_make_int_type (dhandle, 8, false); - break; - default: - abort (); - } - - rettype = debug_name_type (dhandle, name, rettype); - - info->xcoff_types[-typenum] = rettype; - - return rettype; -} - -/* Find or create a tagged type. */ - -static debug_type -stab_find_tagged_type (dhandle, info, p, len, kind) - PTR dhandle; - struct stab_handle *info; - const char *p; - int len; - enum debug_type_kind kind; -{ - char *name; - debug_type dtype; - struct stab_tag *st; - - name = savestring (p, len); - - /* We pass DEBUG_KIND_ILLEGAL because we want all tags in the same - namespace. This is right for C, and I don't know how to handle - other languages. FIXME. */ - dtype = debug_find_tagged_type (dhandle, name, DEBUG_KIND_ILLEGAL); - if (dtype != DEBUG_TYPE_NULL) - { - free (name); - return dtype; - } - - /* We need to allocate an entry on the undefined tag list. */ - for (st = info->tags; st != NULL; st = st->next) - { - if (st->name[0] == name[0] - && strcmp (st->name, name) == 0) - { - if (st->kind == DEBUG_KIND_ILLEGAL) - st->kind = kind; - free (name); - break; - } - } - if (st == NULL) - { - st = (struct stab_tag *) xmalloc (sizeof *st); - memset (st, 0, sizeof *st); - - st->next = info->tags; - st->name = name; - st->kind = kind; - st->slot = DEBUG_TYPE_NULL; - st->type = debug_make_indirect_type (dhandle, &st->slot, name); - info->tags = st; - } - - return st->type; -} - -/* In order to get the correct argument types for a stubbed method, we - need to extract the argument types from a C++ mangled string. - Since the argument types can refer back to the return type, this - means that we must demangle the entire physical name. In gdb this - is done by calling cplus_demangle and running the results back - through the C++ expression parser. Since we have no expression - parser, we must duplicate much of the work of cplus_demangle here. - - We assume that GNU style demangling is used, since this is only - done for method stubs, and only g++ should output that form of - debugging information. */ - -/* This structure is used to hold a pointer to type information which - demangling a string. */ - -struct stab_demangle_typestring -{ - /* The start of the type. This is not null terminated. */ - const char *typestring; - /* The length of the type. */ - unsigned int len; -}; - -/* This structure is used to hold information while demangling a - string. */ - -struct stab_demangle_info -{ - /* The debugging information handle. */ - PTR dhandle; - /* The stab information handle. */ - struct stab_handle *info; - /* The array of arguments we are building. */ - debug_type *args; - /* Whether the method takes a variable number of arguments. */ - boolean varargs; - /* The array of types we have remembered. */ - struct stab_demangle_typestring *typestrings; - /* The number of typestrings. */ - unsigned int typestring_count; - /* The number of typestring slots we have allocated. */ - unsigned int typestring_alloc; -}; - -static void stab_bad_demangle PARAMS ((const char *)); -static unsigned int stab_demangle_count PARAMS ((const char **)); -static boolean stab_demangle_get_count - PARAMS ((const char **, unsigned int *)); -static boolean stab_demangle_prefix - PARAMS ((struct stab_demangle_info *, const char **)); -static boolean stab_demangle_function_name - PARAMS ((struct stab_demangle_info *, const char **, const char *)); -static boolean stab_demangle_signature - PARAMS ((struct stab_demangle_info *, const char **)); -static boolean stab_demangle_qualified - PARAMS ((struct stab_demangle_info *, const char **, debug_type *)); -static boolean stab_demangle_template - PARAMS ((struct stab_demangle_info *, const char **)); -static boolean stab_demangle_class - PARAMS ((struct stab_demangle_info *, const char **, const char **)); -static boolean stab_demangle_args - PARAMS ((struct stab_demangle_info *, const char **, debug_type **, - boolean *)); -static boolean stab_demangle_arg - PARAMS ((struct stab_demangle_info *, const char **, debug_type **, - unsigned int *, unsigned int *)); -static boolean stab_demangle_type - PARAMS ((struct stab_demangle_info *, const char **, debug_type *)); -static boolean stab_demangle_fund_type - PARAMS ((struct stab_demangle_info *, const char **, debug_type *)); -static boolean stab_demangle_remember_type - PARAMS ((struct stab_demangle_info *, const char *, int)); - -/* Warn about a bad demangling. */ - -static void -stab_bad_demangle (s) - const char *s; -{ - fprintf (stderr, "bad mangled name `%s'\n", s); -} - -/* Get a count from a stab string. */ - -static unsigned int -stab_demangle_count (pp) - const char **pp; -{ - unsigned int count; - - count = 0; - while (isdigit ((unsigned char) **pp)) - { - count *= 10; - count += **pp - '0'; - ++*pp; - } - return count; -} - -/* Require a count in a string. The count may be multiple digits, in - which case it must end in an underscore. */ - -static boolean -stab_demangle_get_count (pp, pi) - const char **pp; - unsigned int *pi; -{ - if (! isdigit ((unsigned char) **pp)) - return false; - - *pi = **pp - '0'; - ++*pp; - if (isdigit ((unsigned char) **pp)) - { - unsigned int count; - const char *p; - - count = *pi; - p = *pp; - do - { - count *= 10; - count += *p - '0'; - ++p; - } - while (isdigit ((unsigned char) *p)); - if (*p == '_') - { - *pp = p + 1; - *pi = count; - } - } - - return true; -} - -/* This function demangles a physical name, returning a NULL - terminated array of argument types. */ - -static debug_type * -stab_demangle_argtypes (dhandle, info, physname, pvarargs) - PTR dhandle; - struct stab_handle *info; - const char *physname; - boolean *pvarargs; -{ - struct stab_demangle_info minfo; - - minfo.dhandle = dhandle; - minfo.info = info; - minfo.args = NULL; - minfo.varargs = false; - minfo.typestring_alloc = 10; - minfo.typestrings = ((struct stab_demangle_typestring *) - xmalloc (minfo.typestring_alloc - * sizeof *minfo.typestrings)); - minfo.typestring_count = 0; - - /* cplus_demangle checks for special GNU mangled forms, but we can't - see any of them in mangled method argument types. */ - - if (! stab_demangle_prefix (&minfo, &physname)) - goto error_return; - - if (*physname != '\0') - { - if (! stab_demangle_signature (&minfo, &physname)) - goto error_return; - } - - free (minfo.typestrings); - minfo.typestrings = NULL; - - if (minfo.args == NULL) - fprintf (stderr, "no argument types in mangled string\n"); - - *pvarargs = minfo.varargs; - return minfo.args; - - error_return: - if (minfo.typestrings != NULL) - free (minfo.typestrings); - return NULL; -} - -/* Demangle the prefix of the mangled name. */ - -static boolean -stab_demangle_prefix (minfo, pp) - struct stab_demangle_info *minfo; - const char **pp; -{ - const char *scan; - unsigned int i; - - /* cplus_demangle checks for global constructors and destructors, - but we can't see them in mangled argument types. */ - - /* Look for `__'. */ - scan = *pp; - do - { - scan = strchr (scan, '_'); - } - while (scan != NULL && *++scan != '_'); - - if (scan == NULL) - { - stab_bad_demangle (*pp); - return false; - } - - --scan; - - /* We found `__'; move ahead to the last contiguous `__' pair. */ - i = strspn (scan, "_"); - if (i > 2) - scan += i - 2; - - if (scan == *pp - && (isdigit ((unsigned char) scan[2]) - || scan[2] == 'Q' - || scan[2] == 't')) - { - /* This is a GNU style constructor name. */ - *pp = scan + 2; - return true; - } - else if (scan == *pp - && ! isdigit ((unsigned char) scan[2]) - && scan[2] != 't') - { - /* Look for the `__' that separates the prefix from the - signature. */ - while (*scan == '_') - ++scan; - scan = strstr (scan, "__"); - if (scan == NULL || scan[2] == '\0') - { - stab_bad_demangle (*pp); - return false; - } - - return stab_demangle_function_name (minfo, pp, scan); - } - else if (scan[2] != '\0') - { - /* The name doesn't start with `__', but it does contain `__'. */ - return stab_demangle_function_name (minfo, pp, scan); - } - else - { - stab_bad_demangle (*pp); - return false; - } - /*NOTREACHED*/ -} - -/* Demangle a function name prefix. The scan argument points to the - double underscore which separates the function name from the - signature. */ - -static boolean -stab_demangle_function_name (minfo, pp, scan) - struct stab_demangle_info *minfo; - const char **pp; - const char *scan; -{ - const char *name; - - /* The string from *pp to scan is the name of the function. We - don't care about the name, since we just looking for argument - types. However, for conversion operators, the name may include a - type which we must remember in order to handle backreferences. */ - - name = *pp; - *pp = scan + 2; - - if (*pp - name >= 5 - && strncmp (name, "type", 4) == 0 - && (name[4] == '$' || name[4] == '.')) - { - const char *tem; - - /* This is a type conversion operator. */ - tem = name + 5; - if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL)) - return false; - } - else if (name[0] == '_' - && name[1] == '_' - && name[2] == 'o' - && name[3] == 'p') - { - const char *tem; - - /* This is a type conversion operator. */ - tem = name + 4; - if (! stab_demangle_type (minfo, &tem, (debug_type *) NULL)) - return false; - } - - return true; -} - -/* Demangle the signature. This is where the argument types are - found. */ - -static boolean -stab_demangle_signature (minfo, pp) - struct stab_demangle_info *minfo; - const char **pp; -{ - const char *orig; - boolean expect_func, func_done; - const char *hold; - - orig = *pp; - - expect_func = false; - func_done = false; - hold = NULL; - - while (**pp != '\0') - { - switch (**pp) - { - case 'Q': - hold = *pp; - if (! stab_demangle_qualified (minfo, pp, (debug_type *) NULL) - || ! stab_demangle_remember_type (minfo, hold, *pp - hold)) - return false; - expect_func = true; - hold = NULL; - break; - - case 'S': - /* Static member function. FIXME: Can this happen? */ - if (hold == NULL) - hold = *pp; - ++*pp; - break; - - case 'C': - /* Const member function. */ - if (hold == NULL) - hold = *pp; - ++*pp; - break; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - if (hold == NULL) - hold = *pp; - if (! stab_demangle_class (minfo, pp, (const char **) NULL) - || ! stab_demangle_remember_type (minfo, hold, *pp - hold)) - return false; - expect_func = true; - hold = NULL; - break; - - case 'F': - /* Function. I don't know if this actually happens with g++ - output. */ - hold = NULL; - func_done = true; - ++*pp; - if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs)) - return false; - break; - - case 't': - /* Template. */ - if (hold == NULL) - hold = *pp; - if (! stab_demangle_template (minfo, pp) - || ! stab_demangle_remember_type (minfo, hold, *pp - hold)) - return false; - hold = NULL; - expect_func = true; - break; - - case '_': - /* At the outermost level, we cannot have a return type - specified, so if we run into another '_' at this point we - are dealing with a mangled name that is either bogus, or - has been mangled by some algorithm we don't know how to - deal with. So just reject the entire demangling. */ - stab_bad_demangle (orig); - return false; - - default: - /* Assume we have stumbled onto the first outermost function - argument token, and start processing args. */ - func_done = true; - if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs)) - return false; - break; - } - - if (expect_func) - { - func_done = true; - if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs)) - return false; - } - } - - if (! func_done) - { - /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and - bar__3fooi is 'foo::bar(int)'. We get here when we find the - first case, and need to ensure that the '(void)' gets added - to the current declp. */ - if (! stab_demangle_args (minfo, pp, &minfo->args, &minfo->varargs)) - return false; - } - - return true; -} - -/* Demangle a qualified name, such as "Q25Outer5Inner" which is the - mangled form of "Outer::Inner". */ - -static boolean -stab_demangle_qualified (minfo, pp, ptype) - struct stab_demangle_info *minfo; - const char **pp; - debug_type *ptype; -{ - const char *orig; - const char *p; - unsigned int qualifiers; - debug_type context; - - orig = *pp; - - switch ((*pp)[1]) - { - case '_': - /* GNU mangled name with more than 9 classes. The count is - preceded by an underscore (to distinguish it from the <= 9 - case) and followed by an underscore. */ - p = *pp + 2; - if (! isdigit ((unsigned char) *p) || *p == '0') - { - stab_bad_demangle (orig); - return false; - } - qualifiers = atoi (p); - while (isdigit ((unsigned char) *p)) - ++p; - if (*p != '_') - { - stab_bad_demangle (orig); - return false; - } - *pp = p + 1; - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - qualifiers = (*pp)[1] - '0'; - /* Skip an optional underscore after the count. */ - if ((*pp)[2] == '_') - ++*pp; - *pp += 2; - break; - - case '0': - default: - stab_bad_demangle (orig); - return false; - } - - context = DEBUG_TYPE_NULL; - - /* Pick off the names. */ - while (qualifiers-- > 0) - { - if (**pp == '_') - ++*pp; - if (**pp == 't') - { - /* FIXME: I don't know how to handle the ptype != NULL case - here. */ - if (! stab_demangle_template (minfo, pp)) - return false; - } - else - { - unsigned int len; - - len = stab_demangle_count (pp); - if (strlen (*pp) < len) - { - stab_bad_demangle (orig); - return false; - } - - if (ptype != NULL) - { - const debug_field *fields; - - fields = NULL; - if (context != DEBUG_TYPE_NULL) - fields = debug_get_fields (minfo->dhandle, context); - - context = DEBUG_TYPE_NULL; - - if (fields != NULL) - { - char *name; - - /* Try to find the type by looking through the - fields of context until we find a field with the - same type. This ought to work for a class - defined within a class, but it won't work for, - e.g., an enum defined within a class. stabs does - not give us enough information to figure out the - latter case. */ - - name = savestring (*pp, len); - - for (; *fields != DEBUG_FIELD_NULL; fields++) - { - debug_type ft; - const char *dn; - - ft = debug_get_field_type (minfo->dhandle, *fields); - if (ft == NULL) - return false; - dn = debug_get_type_name (minfo->dhandle, ft); - if (dn != NULL && strcmp (dn, name) == 0) - { - context = ft; - break; - } - } - - free (name); - } - - if (context == DEBUG_TYPE_NULL) - { - /* We have to fall back on finding the type by name. - If there are more types to come, then this must - be a class. Otherwise, it could be anything. */ - - if (qualifiers == 0) - { - char *name; - - name = savestring (*pp, len); - context = debug_find_named_type (minfo->dhandle, - name); - free (name); - } - - if (context == DEBUG_TYPE_NULL) - { - context = stab_find_tagged_type (minfo->dhandle, - minfo->info, - *pp, len, - (qualifiers == 0 - ? DEBUG_KIND_ILLEGAL - : DEBUG_KIND_CLASS)); - if (context == DEBUG_TYPE_NULL) - return false; - } - } - } - - *pp += len; - } - } - - if (ptype != NULL) - *ptype = context; - - return true; -} - -/* Demangle a template. */ - -static boolean -stab_demangle_template (minfo, pp) - struct stab_demangle_info *minfo; - const char **pp; -{ - const char *orig; - unsigned int r, i; - - orig = *pp; - - ++*pp; - - /* Skip the template name. */ - r = stab_demangle_count (pp); - if (r == 0 || strlen (*pp) < r) - { - stab_bad_demangle (orig); - return false; - } - *pp += r; - - /* Get the size of the parameter list. */ - if (stab_demangle_get_count (pp, &r) == 0) - { - stab_bad_demangle (orig); - return false; - } - - for (i = 0; i < r; i++) - { - if (**pp == 'Z') - { - /* This is a type parameter. */ - ++*pp; - if (! stab_demangle_type (minfo, pp, (debug_type *) NULL)) - return false; - } - else - { - const char *old_p; - boolean pointerp, realp, integralp, charp, boolp; - boolean done; - - old_p = *pp; - pointerp = false; - realp = false; - integralp = false; - charp = false; - boolp = false; - done = false; - - /* This is a value parameter. */ - - if (! stab_demangle_type (minfo, pp, (debug_type *) NULL)) - return false; - - while (*old_p != '\0' && ! done) - { - switch (*old_p) - { - case 'P': - case 'p': - case 'R': - pointerp = true; - done = true; - break; - case 'C': /* Const. */ - case 'S': /* Signed. */ - case 'U': /* Unsigned. */ - case 'V': /* Volatile. */ - case 'F': /* Function. */ - case 'M': /* Member function. */ - case 'O': /* ??? */ - ++old_p; - break; - case 'Q': /* Qualified name. */ - integralp = true; - done = true; - break; - case 'T': /* Remembered type. */ - abort (); - case 'v': /* Void. */ - abort (); - case 'x': /* Long long. */ - case 'l': /* Long. */ - case 'i': /* Int. */ - case 's': /* Short. */ - case 'w': /* Wchar_t. */ - integralp = true; - done = true; - break; - case 'b': /* Bool. */ - boolp = true; - done = true; - break; - case 'c': /* Char. */ - charp = true; - done = true; - break; - case 'r': /* Long double. */ - case 'd': /* Double. */ - case 'f': /* Float. */ - realp = true; - done = true; - break; - default: - /* Assume it's a user defined integral type. */ - integralp = true; - done = true; - break; - } - } - - if (integralp) - { - if (**pp == 'm') - ++*pp; - while (isdigit ((unsigned char) **pp)) - ++*pp; - } - else if (charp) - { - unsigned int val; - - if (**pp == 'm') - ++*pp; - val = stab_demangle_count (pp); - if (val == 0) - { - stab_bad_demangle (orig); - return false; - } - } - else if (boolp) - { - unsigned int val; - - val = stab_demangle_count (pp); - if (val != 0 && val != 1) - { - stab_bad_demangle (orig); - return false; - } - } - else if (realp) - { - if (**pp == 'm') - ++*pp; - while (isdigit ((unsigned char) **pp)) - ++*pp; - if (**pp == '.') - { - ++*pp; - while (isdigit ((unsigned char) **pp)) - ++*pp; - } - if (**pp == 'e') - { - ++*pp; - while (isdigit ((unsigned char) **pp)) - ++*pp; - } - } - else if (pointerp) - { - unsigned int len; - - if (! stab_demangle_get_count (pp, &len)) - { - stab_bad_demangle (orig); - return false; - } - *pp += len; - } - } - } - - return true; -} - -/* Demangle a class name. */ - -static boolean -stab_demangle_class (minfo, pp, pstart) - struct stab_demangle_info *minfo; - const char **pp; - const char **pstart; -{ - const char *orig; - unsigned int n; - - orig = *pp; - - n = stab_demangle_count (pp); - if (strlen (*pp) < n) - { - stab_bad_demangle (orig); - return false; - } - - if (pstart != NULL) - *pstart = *pp; - - *pp += n; - - return true; -} - -/* Demangle function arguments. If the pargs argument is not NULL, it - is set to a NULL terminated array holding the arguments. */ - -static boolean -stab_demangle_args (minfo, pp, pargs, pvarargs) - struct stab_demangle_info *minfo; - const char **pp; - debug_type **pargs; - boolean *pvarargs; -{ - const char *orig; - unsigned int alloc, count; - - orig = *pp; - - alloc = 10; - if (pargs != NULL) - { - *pargs = (debug_type *) xmalloc (alloc * sizeof **pargs); - *pvarargs = false; - } - count = 0; - - while (**pp != '_' && **pp != '\0' && **pp != 'e') - { - if (**pp == 'N' || **pp == 'T') - { - char temptype; - unsigned int r, t; - - temptype = **pp; - ++*pp; - - if (temptype == 'T') - r = 1; - else - { - if (! stab_demangle_get_count (pp, &r)) - { - stab_bad_demangle (orig); - return false; - } - } - - if (! stab_demangle_get_count (pp, &t)) - { - stab_bad_demangle (orig); - return false; - } - - if (t >= minfo->typestring_count) - { - stab_bad_demangle (orig); - return false; - } - while (r-- > 0) - { - const char *tem; - - tem = minfo->typestrings[t].typestring; - if (! stab_demangle_arg (minfo, &tem, pargs, &count, &alloc)) - return false; - } - } - else - { - if (! stab_demangle_arg (minfo, pp, pargs, &count, &alloc)) - return false; - } - } - - if (pargs != NULL) - (*pargs)[count] = DEBUG_TYPE_NULL; - - if (**pp == 'e') - { - if (pargs != NULL) - *pvarargs = true; - ++*pp; - } - - return true; -} - -/* Demangle a single argument. */ - -static boolean -stab_demangle_arg (minfo, pp, pargs, pcount, palloc) - struct stab_demangle_info *minfo; - const char **pp; - debug_type **pargs; - unsigned int *pcount; - unsigned int *palloc; -{ - const char *start; - debug_type type; - - start = *pp; - if (! stab_demangle_type (minfo, pp, - pargs == NULL ? (debug_type *) NULL : &type) - || ! stab_demangle_remember_type (minfo, start, *pp - start)) - return false; - - if (pargs != NULL) - { - if (type == DEBUG_TYPE_NULL) - return false; - - if (*pcount + 1 >= *palloc) - { - *palloc += 10; - *pargs = ((debug_type *) - xrealloc (*pargs, *palloc * sizeof **pargs)); - } - (*pargs)[*pcount] = type; - ++*pcount; - } - - return true; -} - -/* Demangle a type. If the ptype argument is not NULL, *ptype is set - to the newly allocated type. */ - -static boolean -stab_demangle_type (minfo, pp, ptype) - struct stab_demangle_info *minfo; - const char **pp; - debug_type *ptype; -{ - const char *orig; - - orig = *pp; - - switch (**pp) - { - case 'P': - case 'p': - /* A pointer type. */ - ++*pp; - if (! stab_demangle_type (minfo, pp, ptype)) - return false; - if (ptype != NULL) - *ptype = debug_make_pointer_type (minfo->dhandle, *ptype); - break; - - case 'R': - /* A reference type. */ - ++*pp; - if (! stab_demangle_type (minfo, pp, ptype)) - return false; - if (ptype != NULL) - *ptype = debug_make_reference_type (minfo->dhandle, *ptype); - break; - - case 'A': - /* An array. */ - { - unsigned long high; - - ++*pp; - high = 0; - while (**pp != '\0' && **pp != '_') - { - if (! isdigit ((unsigned char) **pp)) - { - stab_bad_demangle (orig); - return false; - } - high *= 10; - high += **pp - '0'; - ++*pp; - } - if (**pp != '_') - { - stab_bad_demangle (orig); - return false; - } - ++*pp; - - if (! stab_demangle_type (minfo, pp, ptype)) - return false; - if (ptype != NULL) - { - debug_type int_type; - - int_type = debug_find_named_type (minfo->dhandle, "int"); - if (int_type == NULL) - int_type = debug_make_int_type (minfo->dhandle, 4, false); - *ptype = debug_make_array_type (minfo->dhandle, *ptype, int_type, - 0, high, false); - } - } - break; - - case 'T': - /* A back reference to a remembered type. */ - { - unsigned int i; - const char *p; - - ++*pp; - if (! stab_demangle_get_count (pp, &i)) - { - stab_bad_demangle (orig); - return false; - } - if (i >= minfo->typestring_count) - { - stab_bad_demangle (orig); - return false; - } - p = minfo->typestrings[i].typestring; - if (! stab_demangle_type (minfo, &p, ptype)) - return false; - } - break; - - case 'F': - /* A function. */ - { - debug_type *args; - boolean varargs; - - ++*pp; - if (! stab_demangle_args (minfo, pp, - (ptype == NULL - ? (debug_type **) NULL - : &args), - (ptype == NULL - ? (boolean *) NULL - : &varargs))) - return false; - if (**pp != '_') - { - /* cplus_demangle will accept a function without a return - type, but I don't know when that will happen, or what - to do if it does. */ - stab_bad_demangle (orig); - return false; - } - ++*pp; - if (! stab_demangle_type (minfo, pp, ptype)) - return false; - if (ptype != NULL) - *ptype = debug_make_function_type (minfo->dhandle, *ptype, args, - varargs); - - } - break; - - case 'M': - case 'O': - { - boolean memberp, constp, volatilep; - debug_type *args; - boolean varargs; - unsigned int n; - const char *name; - - memberp = **pp == 'M'; - constp = false; - volatilep = false; - args = NULL; - varargs = false; - - ++*pp; - if (! isdigit ((unsigned char) **pp)) - { - stab_bad_demangle (orig); - return false; - } - n = stab_demangle_count (pp); - if (strlen (*pp) < n) - { - stab_bad_demangle (orig); - return false; - } - name = *pp; - *pp += n; - - if (memberp) - { - if (**pp == 'C') - { - constp = true; - ++*pp; - } - else if (**pp == 'V') - { - volatilep = true; - ++*pp; - } - if (**pp != 'F') - { - stab_bad_demangle (orig); - return false; - } - ++*pp; - if (! stab_demangle_args (minfo, pp, - (ptype == NULL - ? (debug_type **) NULL - : &args), - (ptype == NULL - ? (boolean *) NULL - : &varargs))) - return false; - } - - if (**pp != '_') - { - stab_bad_demangle (orig); - return false; - } - ++*pp; - - if (! stab_demangle_type (minfo, pp, ptype)) - return false; - - if (ptype != NULL) - { - debug_type class_type; - - class_type = stab_find_tagged_type (minfo->dhandle, minfo->info, - name, (int) n, - DEBUG_KIND_CLASS); - if (class_type == DEBUG_TYPE_NULL) - return false; - - if (! memberp) - *ptype = debug_make_offset_type (minfo->dhandle, class_type, - *ptype); - else - { - /* FIXME: We have no way to record constp or - volatilep. */ - *ptype = debug_make_method_type (minfo->dhandle, *ptype, - class_type, args, varargs); - } - } - } - break; - - case 'G': - ++*pp; - if (! stab_demangle_type (minfo, pp, ptype)) - return false; - break; - - case 'C': - ++*pp; - if (! stab_demangle_type (minfo, pp, ptype)) - return false; - if (ptype != NULL) - *ptype = debug_make_const_type (minfo->dhandle, *ptype); - break; - - case 'Q': - { - const char *hold; - - hold = *pp; - if (! stab_demangle_qualified (minfo, pp, ptype)) - return false; - } - break; - - default: - if (! stab_demangle_fund_type (minfo, pp, ptype)) - return false; - break; - } - - return true; -} - -/* Demangle a fundamental type. If the ptype argument is not NULL, - *ptype is set to the newly allocated type. */ - -static boolean -stab_demangle_fund_type (minfo, pp, ptype) - struct stab_demangle_info *minfo; - const char **pp; - debug_type *ptype; -{ - const char *orig; - boolean constp, volatilep, unsignedp, signedp; - boolean done; - - orig = *pp; - - constp = false; - volatilep = false; - unsignedp = false; - signedp = false; - - done = false; - while (! done) - { - switch (**pp) - { - case 'C': - constp = true; - ++*pp; - break; - - case 'U': - unsignedp = true; - ++*pp; - break; - - case 'S': - signedp = true; - ++*pp; - break; - - case 'V': - volatilep = true; - ++*pp; - break; - - default: - done = true; - break; - } - } - - switch (**pp) - { - case '\0': - case '_': - /* cplus_demangle permits this, but I don't know what it means. */ - stab_bad_demangle (orig); - break; - - case 'v': /* void */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, "void"); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_void_type (minfo->dhandle); - } - ++*pp; - break; - - case 'x': /* long long */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, - (unsignedp - ? "long long unsigned int" - : "long long int")); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_int_type (minfo->dhandle, 8, unsignedp); - } - ++*pp; - break; - - case 'l': /* long */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, - (unsignedp - ? "long unsigned int" - : "long int")); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_int_type (minfo->dhandle, 4, unsignedp); - } - ++*pp; - break; - - case 'i': /* int */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, - (unsignedp - ? "unsigned int" - : "int")); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_int_type (minfo->dhandle, 4, unsignedp); - } - ++*pp; - break; - - case 's': /* short */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, - (unsignedp - ? "short unsigned int" - : "short int")); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_int_type (minfo->dhandle, 2, unsignedp); - } - ++*pp; - break; - - case 'b': /* bool */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, "bool"); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_bool_type (minfo->dhandle, 4); - } - ++*pp; - break; - - case 'c': /* char */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, - (unsignedp - ? "unsigned char" - : (signedp - ? "signed char" - : "char"))); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_int_type (minfo->dhandle, 1, unsignedp); - } - ++*pp; - break; - - case 'w': /* wchar_t */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, "__wchar_t"); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_int_type (minfo->dhandle, 2, true); - } - ++*pp; - break; - - case 'r': /* long double */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, "long double"); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_float_type (minfo->dhandle, 8); - } - ++*pp; - break; - - case 'd': /* double */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, "double"); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_float_type (minfo->dhandle, 8); - } - ++*pp; - break; - - case 'f': /* float */ - if (ptype != NULL) - { - *ptype = debug_find_named_type (minfo->dhandle, "float"); - if (*ptype == DEBUG_TYPE_NULL) - *ptype = debug_make_float_type (minfo->dhandle, 4); - } - ++*pp; - break; - - case 'G': - ++*pp; - if (! isdigit ((unsigned char) **pp)) - { - stab_bad_demangle (orig); - return false; - } - /* Fall through. */ - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - { - const char *hold; - - if (! stab_demangle_class (minfo, pp, &hold)) - return false; - if (ptype != NULL) - { - char *name; - - name = savestring (hold, *pp - hold); - *ptype = debug_find_named_type (minfo->dhandle, name); - if (*ptype == DEBUG_TYPE_NULL) - { - /* FIXME: It is probably incorrect to assume that - undefined types are tagged types. */ - *ptype = stab_find_tagged_type (minfo->dhandle, minfo->info, - hold, *pp - hold, - DEBUG_KIND_ILLEGAL); - } - free (name); - } - } - break; - - case 't': - if (! stab_demangle_template (minfo, pp)) - return false; - if (ptype != NULL) - { - debug_type t; - - /* FIXME: I really don't know how a template should be - represented in the current type system. Perhaps the - template should be demangled into a string, and the type - should be represented as a named type. However, I don't - know what the base type of the named type should be. */ - t = debug_make_void_type (minfo->dhandle); - t = debug_make_pointer_type (minfo->dhandle, t); - t = debug_name_type (minfo->dhandle, "TEMPLATE", t); - *ptype = t; - } - break; - - default: - stab_bad_demangle (orig); - return false; - } - - if (ptype != NULL) - { - if (constp) - *ptype = debug_make_const_type (minfo->dhandle, *ptype); - if (volatilep) - *ptype = debug_make_volatile_type (minfo->dhandle, *ptype); - } - - return true; -} - -/* Remember a type string in a demangled string. */ - -static boolean -stab_demangle_remember_type (minfo, p, len) - struct stab_demangle_info *minfo; - const char *p; - int len; -{ - if (minfo->typestring_count >= minfo->typestring_alloc) - { - minfo->typestring_alloc += 10; - minfo->typestrings = ((struct stab_demangle_typestring *) - xrealloc (minfo->typestrings, - (minfo->typestring_alloc - * sizeof *minfo->typestrings))); - } - - minfo->typestrings[minfo->typestring_count].typestring = p; - minfo->typestrings[minfo->typestring_count].len = (unsigned int) len; - ++minfo->typestring_count; - - return true; -} diff --git a/sql/Makefile.am b/sql/Makefile.am index 1bc195a2981..8d933b83d8d 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -81,7 +81,6 @@ mysqld_DEPENDENCIES= @mysql_plugin_libs@ $(SUPPORTING_LIBS) libndb.la LDADD = $(SUPPORTING_LIBS) @ZLIB_LIBS@ @NDB_SCI_LIBS@ mysqld_LDADD = libndb.la \ @MYSQLD_EXTRA_LDFLAGS@ \ - @pstack_libs@ \ @mysql_plugin_libs@ \ $(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ \ $(yassl_libs) $(openssl_libs) @MYSQLD_EXTRA_LIBS@ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index af98ed91adf..3e8f699bbd9 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -97,13 +97,6 @@ #define mysqld_charset &my_charset_latin1 -/* stack traces are only supported on linux intel */ -#if defined(__linux__) && defined(__i386__) && defined(USE_PSTACK) -#define HAVE_STACK_TRACE_ON_SEGV -#include "../pstack/pstack.h" -char pstack_file_name[80]; -#endif /* __linux__ */ - /* We have HAVE_purify below as this speeds up the shutdown of MySQL */ #if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ) || defined(HAVE_purify) && defined(__linux__) @@ -650,9 +643,6 @@ char *opt_logname, *opt_slow_logname; /* Static variables */ static bool kill_in_progress, segfaulted; -#ifdef HAVE_STACK_TRACE_ON_SEGV -static my_bool opt_do_pstack; -#endif /* HAVE_STACK_TRACE_ON_SEGV */ static my_bool opt_bootstrap, opt_myisam_log; static int cleanup_done; static ulong opt_specialflag; @@ -2686,14 +2676,6 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused))) if (!opt_bootstrap) create_pid_file(); -#ifdef HAVE_STACK_TRACE_ON_SEGV - if (opt_do_pstack) - { - sprintf(pstack_file_name,"mysqld-%lu-%%d-%%d.backtrace", (ulong)getpid()); - pstack_install_segv_action(pstack_file_name); - } -#endif /* HAVE_STACK_TRACE_ON_SEGV */ - /* signal to start_signal_handler that we are ready This works by waiting for start_signal_handler to free mutex, @@ -5740,11 +5722,6 @@ struct my_option my_long_options[]= &disconnect_slave_event_count, &disconnect_slave_event_count, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif /* HAVE_REPLICATION */ -#ifdef HAVE_STACK_TRACE_ON_SEGV - {"enable-pstack", 0, "Print a symbolic stack trace on failure.", - &opt_do_pstack, &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0, - 0, 0, 0, 0}, -#endif /* HAVE_STACK_TRACE_ON_SEGV */ {"exit-info", 'T', "Used for debugging. Use at your own risk.", 0, 0, 0, GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},