Bug #18193 Server crash when assigning UDF STRING result to a variable in stored procedure
Submitted: 13 Mar 2006 16:32 Modified: 5 Apr 2006 9:14
Reporter: Hartmut Holzgraefe Email Updates:
Status: Duplicate Impact on me:
None 
Category:MySQL Server: User-defined functions ( UDF ) Severity:S1 (Critical)
Version:5.0.18 OS:Linux (linux)
Assigned to: Assigned Account CPU Architecture:Any

[13 Mar 2006 16:32] Hartmut Holzgraefe
Description:
When trying to assign the result of a UDF returning a STRING to a variable crashes the server.

How to repeat:
Using the attached simple UDF function (precompiled for linux and mysql 5.0)

  CREATE FUNCTION ex_strrev RETURNS STRING SONAME "example.so"; 

This is the simplest example (more to follow below):

  set @foo = ex_strrev("hello");

which leads to the following backtrace:

  #0  0xffffe410 in ?? ()
  #1  0x438891ec in ?? ()
  #2  0x0000000b in ?? ()  
  #3  0x0835ee11 in write_core (sig=11) at stacktrace.c:220
  #4  0x081eb113 in handle_segfault (sig=11) at mysqld.cc:2083
  #5  <signal handler called>
  #6  0x0817f2b5 in update_hash (entry=0x8ebe860, set_null=false, ptr=0x6, length=6, 
    type=STRING_RESULT, cs=0x88209a0, dv=DERIVATION_IMPLICIT) at item_func.cc:3521
  #7  0x0817f3a8 in Item_func_set_user_var::update_hash (this=0x8ec4c78, ptr=0x6, 
    length=6, type=STRING_RESULT, cs=0x88209a0, dv=DERIVATION_IMPLICIT)
    at item_func.cc:3542
  #8  0x0817fb03 in Item_func_set_user_var::update (this=0x8ec4c78) at item_func.cc:3763
  #9  0x081f71a2 in set_var_user::update (this=0x8ec5060, thd=0x8ea1240)
    at set_var.cc:3141
  #10 0x081f6b97 in sql_set_variables (thd=0x8ea1240, var_list=0x8ea1738)
    at set_var.cc:2979
  #11 0x0820a061 in mysql_execute_command (thd=0x8ea1240) at sql_parse.cc:3517
  #12 0x0820f19d in mysql_parse (thd=0x8ea1240, 
    inBuf=0x8ec4a58 "set @mw = ex_strrev(\"hallo\")", length=28) at sql_parse.cc:5612
  #13 0x0820fc19 in dispatch_command (command=COM_QUERY, thd=0x8ea1240, 
    packet=0x8eb89d1 "set @mw = ex_strrev(\"hallo\")", packet_length=29)
    at sql_parse.cc:1719
  #14 0x082111e9 in do_command (thd=0x8ea1240) at sql_parse.cc:1515
  #15 0x082115f2 in handle_one_connection (arg=0x8ea1240) at sql_parse.cc:1158
  #16 0x401beaa7 in start_thread () from /lib/tls/libpthread.so.0
  #17 0x402efc2e in clone () from /lib/tls/libc.so.6

when used within a stored procedure like this:

delimiter //
CREATE PROCEDURE `test`(in p_smiles varchar(100)) 
begin 
set @foo = ex_strrev("hello");
end;
//
call test("hallo");

the backtrace is 

#0  0xffffe410 in ?? ()
#1  0x43888334 in ?? ()
#2  0x0000000b in ?? ()
#3  0x0835ee11 in write_core (sig=11) at stacktrace.c:220
#4  0x081eb113 in handle_segfault (sig=11) at mysqld.cc:2083
#5  <signal handler called>
#6  0x08160337 in String::set_charset (this=0x0, charset=0x88209a0) at sql_string.h:82
#7  0x081541d4 in Item_field::val_str (this=0x8ec1ce0, str=0x0) at item.cc:1627
#8  0x081523db in Item_sp_variable::val_str (this=0x8eea320, sp=0x0) at item.cc:843
#9  0x0817d031 in udf_handler::fix_fields (this=0x8eea45c, thd=0x8ea1248, func=0x8eea3f0, arg_count=1, arguments=0x8eea438) at item_func.cc:2609
#10 0x08185032 in Item_udf_func::fix_fields (this=0x8eea3f0, thd=0x8ea1248, ref=0x8eea528) at item_func.h:923
#11 0x08174d32 in Item_func::fix_fields (this=0x8eea4e0, thd=0x8ea1248, ref=0x0) at item_func.cc:163
#12 0x0817efae in Item_func_set_user_var::fix_fields (this=0x8eea4e0, thd=0x8ea1248, ref=0x0) at item_func.cc:3416
#13 0x081f7131 in set_var_user::check (this=0x8eea8c8, thd=0x8ea1248) at set_var.cc:3113
#14 0x081f6b0f in sql_set_variables (thd=0x8ea1248, var_list=0x8ef2ac8) at set_var.cc:2972
#15 0x0820a061 in mysql_execute_command (thd=0x8ea1248) at sql_parse.cc:3517
#16 0x08379751 in sp_instr_stmt::exec_core (this=0x8eea8d8, thd=0x8ea1248, nextp=0x43889530) at sp_head.cc:2329
#17 0x0837953c in sp_lex_keeper::reset_lex_and_exec_core (this=0x8eea900, thd=0x8ea1248, nextp=0x43889530, open_tables=false, instr=0x8eea8d8)
    at sp_head.cc:2208
#18 0x0837c60f in sp_instr_stmt::execute (this=0x8eea8d8, thd=0x8ea1248, nextp=0x43889530) at sp_head.cc:2282
#19 0x083760d9 in sp_head::execute (this=0x8ee9e98, thd=0x8ea1248) at sp_head.cc:1059
#20 0x083773d8 in sp_head::execute_procedure (this=0x8ee9e98, thd=0x8ea1248, args=0x8ea171c) at sp_head.cc:1499
#21 0x0820cfc2 in mysql_execute_command (thd=0x8ea1248) at sql_parse.cc:4309
#22 0x0820f19d in mysql_parse (thd=0x8ea1248, inBuf=0x8ec0a38 "call test('hallo')", length=18) at sql_parse.cc:5612
#23 0x0820fc19 in dispatch_command (command=COM_QUERY, thd=0x8ea1248, packet=0x8eb89d9 "call test('hallo')", packet_length=19)
    at sql_parse.cc:1719
#24 0x082111e9 in do_command (thd=0x8ea1248) at sql_parse.cc:1515
#25 0x082115f2 in handle_one_connection (arg=0x8ea1248) at sql_parse.cc:1158
#26 0x401beaa7 in start_thread () from /lib/tls/libpthread.so.0
#27 0x402efc2e in clone () from /lib/tls/libc.so.6

Suggested fix:
the 2nd backtrace seems to suggest that this is an issue due to UDFs not being aware of charset handling yet?
[13 Mar 2006 17:38] Hartmut Holzgraefe
the crash in a simple assignment was due to an error in my test UDF,
but the crashes in stored procedures are for real, i tried both

  delimiter //
  CREATE PROCEDURE `test6`(in p_smiles varchar(100)) 
  begin 
    SET @my = my_strcpy(p_smiles);
  end;
  //
  delimiter ;

and

  delimiter //
  CREATE PROCEDURE `test7`(in p_smiles varchar(100)) 
  begin 
    declare foo varchar(100);
    SELECT ex_strrev(p_smiles) into foo;
    SELECT foo; 
  end;
  //
  delimiter ;

which both lead to crashes with an otherwise working UDF
[13 Mar 2006 19:39] Hartmut Holzgraefe
test UDF that just returns its 1st argument as a string

Attachment: my_strcpy.tar.bz2 (application/x-tar, text), 196.19 KiB.

[13 Mar 2006 19:40] Hartmut Holzgraefe
precompiled linux / mysql 5.0 UDF module

Attachment: my_strcpy.so (application/octet-stream, text), 8.80 KiB.

[5 Apr 2006 9:13] Alexander Nozdrin
This is a duplicate of BUG#17261.
[5 Apr 2006 9:13] Magnus BlÄudd
Hartmut, please see latest bk version of 5.0. There is now a test case for udf's(it's in mysql-test/udf.test) that load's the udf_example.so from sql/ directory.

Also, I recently fixed a bug related to passing strings  to udf's. See BUG#17261. So this should already be fixed. :)