Bug #33618 Crash in sp_rcontext
Submitted: 2 Jan 2008 6:16 Modified: 25 Jan 2008 19:41
Reporter: Adam Dixon Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Stored Routines Severity:S1 (Critical)
Version:5.0.34, 5.0.52, 5.1.22, 6.0.3 OS:Any
Assigned to: Marc ALFF CPU Architecture:Any

[2 Jan 2008 6:16] Adam Dixon
Description:
Getting Signal 11 crash;

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1162185024 (LWP 8945)]
sp_rcontext::find_handler (this=0x198fc68, sql_errno=1213, level=WARN_LEVEL_ERROR) at sp_rcontext.cc:216
216         switch (cond->type)

How to repeat:
See Private comments.
[2 Jan 2008 7:30] MySQL Verification Team
i confirm the server crashes as described by adam.

Attachment: bug33618-5.0.52-stacktrace.txt (text/plain), 2.77 KiB.

[2 Jan 2008 8:07] MySQL Verification Team
5.1.22 also crashes after a while

Attachment: bug33618-5.1.22-stacktrace.txt (text/plain), 1.03 KiB.

[2 Jan 2008 11:17] MySQL Verification Team
testcase1 to crash, just paste into command line client

Attachment: bug33618_testcase1.sql (application/unknown, text), 1.24 KiB.

[2 Jan 2008 11:46] MySQL Verification Team
testcase2 to crash, that doesn't loop infinately :)

Attachment: bug33618_testcase2.sql (application/unknown, text), 1.15 KiB.

[2 Jan 2008 15:04] MySQL Verification Team
made a small typo in the delimiter in the second testcase. just change ; to be // after the insert.
[9 Jan 2008 23:48] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/40811

ChangeSet@1.2583, 2008-01-09 16:48:32-07:00, malff@lambda.hsd1.co.comcast.net. +9 -0
  Bug#33618 (Crash in sp_rcontext)
  
  There are several layers of issues that caused this crash.
  
  1)
  The server crash in sp_rcontext, due to a stack overflow in the sp_rcontext
  handler stack.
  
  2)
  The stack overflow was caused by incorrect generated code, where a hpop
  instruction was missing for a LEAVE. Repeated execution of this LEAVE
  statement in a loop caused wide spread memory corruption.
  
  3)
  (See the bug report for the code exposing the bug)
  The missing hpop was caused by the call to sp_head::diff_handlers(),
  which considered that there is no handler to pop since exclusive is true.
  Code generation for the LEAVE statement assumed that the handler will be
  removed by the code generated at the end of a begin-end block,
  which did not happen when jumping to a REPEAT-UNTIL "rep1:" label.
  
  4)
  Resolution of forward jumps with the backpacth list (sp_head::backpatch)
  was not working properly, and generated jumps to the wrong instruction.
  This is because backpatches for begin-end blocks label were resolved
  *twice*, and pointed to different locations:
  - before the end hpop/cpop instructions ending a block
  - after the end hpop/cpop instructions ending a block
  This caused the jump for the LEAVE statement to the "rep1:" label to
  point *after* the hpop instruction.
  
  5)
  Issue 4) in the code itself was hidden by a poor implementation
  of sp_instr_jump:backpatch(), which accepted multiple destination for the
  same instruction.
  
  6)
  Iteration labels like "rep1:" were initially typed as SP_LAB_ITER,
  but later corrupted to SP_LAB_BEGIN in the parser grammar rules,
  adding to the confusion when generating code.
  
  With this fix,
  
  (1) is fixed by enforcing integrity of every internal stack in sp_rcontext
  with DBUG_ASSERT statements.
  
  (2) and (3) are fixed by this line of code:
    bool exclusive= (lab->type == SP_LAB_BEGIN);
  
  (4) is fixed by implementing the following grammar rules in the parser:
  - sp_unlabeled_block
  - sp_labeled_block
  these rules resolve the sp_head::backpatch() *inside* sp_block_content,
  while rules for control flow operations do that *ousdide*
  sp_unlabeled_control
  In all cases, backpatch is done only once for a given label.
  
  (5) is fixed in sp_instr_jump:backpatch() with a DBUG_ASSERT.
  
  (6) is fixed by assigning SP_LAB_BEGIN only to block labels
[23 Jan 2008 20:27] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/41168

ChangeSet@1.2583, 2008-01-23 13:26:41-07:00, malff@lambda.hsd1.co.comcast.net. +11 -0
  Bug#33618 (Crash in sp_rcontext)
  Bug 33983 (Stored Procedures: wrong end <label> syntax is accepted)
  
  The server used to crash when REPEAT or another control instruction
  was used in conjunction with labels and a LEAVE instruction.
  
  The crash was caused by a missing "pop" of handlers or cursors in the
  code representing the stored program. When executing the code in a loop,
  this missing "pop" would result in a stack overflow, corrupting memory.
  
  Code generation has been fixed to produce the missing h_pop/c_pop
  instructions.
  
  Also, the logic checking that labels at the beginning and the end of a
  statement are matched was incorrect, causing Bug 33983.
  End labels, when used, must match the label used at the beginning of a block.
[25 Jan 2008 12:34] Bugs System
Pushed into 5.0.56
[25 Jan 2008 12:36] Bugs System
Pushed into 5.1.24-rc
[25 Jan 2008 12:40] Bugs System
Pushed into 6.0.5-alpha
[25 Jan 2008 19:41] Paul DuBois
Noted in 5.0.56, 5.1.23, 6.0.5 changelogs.
[25 Jan 2008 19:43] Paul DuBois
Correction: Noted in 5.1.24 (not 5.1.23) changelog.
[6 Mar 2008 15:48] Jon Stephens
Also documented for 5.1.23-ndb-6.2.14.
[2 Apr 2008 16:15] Jon Stephens
Also noted in the 5.1.23-ndb-6.3.11 changelog.