TMUDF: A TMUDF with nonexisting external name crashes sqlci with a core

Bug #1430438 reported by Weishiun Tsai
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Trafodion
Fix Released
High
Hans Zeller

Bug Description

As shown in the following example, 2 TMUDFs were defined. qa_tmudf1() was defined with a valid external name from the so file, while qa_tmudf2() was defined with an external name that does not exist. Invoking qa_tmudf2() crashes sqlci with a core at bindRowValues()

It’s not unusual for a user to misspell the external name of a tmudf at the definition time, especially when the external name is case sensitive. This error should be handled more gracefully, either by giving a proper error message at the definition time, or at the run time, instead of crashing sqlci with a core.

This is seen on the v0305 build installed on a workstation. To reproduce it:

(1) Download the attached tar file and untar it to get the 3 files in there. Put the files in any directory <mydir>
(2) Make sure that you have run ./sqenv.sh of your Trafodion instance first as building UDF needs $MY_SQROOT for the header files.
(3) Run build.sh from <mydir> to build the UDF so file.
(4) Change the line create library qaTmudfLib file '<mydir>/qaTMUdfTest.so'; in mytest.sql and fill in <mydir>
(5) From sqlci, obey mytest.sql

-------------------------------------------------------------------------

Here is the execution output:

>>log mytest.log clear;
>>drop schema mytest cascade;

*** ERROR[1003] Schema TRAFODION.MYTEST does not exist.

--- SQL operation failed with errors.
>>create schema mytest;

--- SQL operation complete.
>>set schema mytest;

--- SQL operation complete.
>>
>>create library qaTmudfLib file '<mydir>/qaTMUdfTest.so';

--- SQL operation complete.
>>
>>create table mytable (a int, b int);

--- SQL operation complete.
>>insert into mytable values (1,1),(2,2);

--- 2 row(s) inserted.
>>
>>create table_mapping function qa_tmudf1()
+>external name 'QA_TMUDF'
+>language cpp
+>library qaTmudfLib;

--- SQL operation complete.
>>
>>select * from UDF(qa_tmudf1(TABLE(select * from mytable)));

A B
----------- -----------

          1 1
          2 2

--- 2 row(s) selected.
>>
>>create table_mapping function qa_tmudf2()
+>external name 'DONTEXIST'
+>language cpp
+>library qaTmudfLib;

--- SQL operation complete.
>>
>>select * from UDF(qa_tmudf2(TABLE(select * from mytable)));
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007fffef80a975, pid=32392, tid=140737188215328
#
# JRE version: Java(TM) SE Runtime Environment (7.0_67-b01) (build 1.7.0_67-b01)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (24.65-b04 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C [liboptimizer.so+0x3c6975] bindRowValues(BindWA*, ItemExpr*, ValueIdList&, RelExpr*, int)+0x475
#
# Core dump written. Default location: <my_dir>/core or core.32392
#
# An error report file with more information is saved as:
# <my_dir>/hs_err_pid32392.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
Aborted (core dumped)

-------------------------------------------------------------------------

Here is the stack trace of the core:

(gdb) bt
#0 0x00000039e28328a5 in raise () from /lib64/libc.so.6
#1 0x00000039e283400d in abort () from /lib64/libc.so.6
#2 0x00007ffff7122a55 in os::abort(bool) ()
   from /opt/home/tools/jdk1.7.0_67/jre/lib/amd64/server/libjvm.so
#3 0x00007ffff72a2f87 in VMError::report_and_die() ()
   from /opt/home/tools/jdk1.7.0_67/jre/lib/amd64/server/libjvm.so
#4 0x00007ffff712796f in JVM_handle_linux_signal ()
   from /opt/home/tools/jdk1.7.0_67/jre/lib/amd64/server/libjvm.so
#5 <signal handler called>
#6 0x00007fffef80a975 in bindRowValues (bindWA=0x7ffffffef860,
    exprTree=<value optimized out>, vidList=..., parent=<value optimized out>,
    inTrueRoot=1) at ../optimizer/BindRelExpr.cpp:222
#7 0x00007fffef8188fa in RelRoot::bindNode (this=0x7fffd73561d0,
    bindWA=0x7ffffffef860) at ../optimizer/BindRelExpr.cpp:5440
#8 0x00007ffff111406e in CmpMain::compile (this=0x7fffffff2310,
    input_str=0x7fffe8baa3c0 "select * from UDF(qa_tmudf2(TABLE(select * from mytable)));", charset=15, queryExpr=@0x7fffffff2248, gen_code=0x7fffd739b4a0,
    gen_code_len=0x7fffd739b498, heap=0x7fffe9741c08, phase=CmpMain::END,
    fragmentDir=0x7fffffff2468, op=3004, useQueryCache=1,
    cacheable=0x7fffffff2258, begTime=0x7fffffff2230, shouldLog=0)
    at ../sqlcomp/CmpMain.cpp:2058
#9 0x00007ffff1116e7c in CmpMain::sqlcomp (this=0x7fffffff2310,
    input_str=0x7fffe8baa3c0 "select * from UDF(qa_tmudf2(TABLE(select * from mytable)));", charset=15, queryExpr=@0x7fffffff2248, gen_code=0x7fffd739b4a0,
    gen_code_len=0x7fffd739b498, heap=0x7fffe9741c08, phase=CmpMain::END,
    fragmentDir=0x7fffffff2468, op=3004, useQueryCache=1,
    cacheable=0x7fffffff2258, begTime=0x7fffffff2230, shouldLog=0)
    at ../sqlcomp/CmpMain.cpp:1671
#10 0x00007ffff1118180 in CmpMain::sqlcomp (this=0x7fffffff2310, input=...,
    gen_code=0x7fffd739b4a0, gen_code_len=0x7fffd739b498, heap=0x7fffe9741c08,
    phase=CmpMain::END, fragmentDir=0x7fffffff2468, op=3004)
    at ../sqlcomp/CmpMain.cpp:817
#11 0x00007ffff55c7478 in CmpStatement::process (this=0x7fffd7347d00,
    sqltext=<value optimized out>) at ../arkcmp/CmpStatement.cpp:508
#12 0x00007ffff55ba903 in CmpContext::compileDirect (this=0x7fffe8baa090,
    data=0x7fffe9750c38 "\200", data_len=192, outHeap=0x7fffea1b1128,
    charset=15, op=CmpMessageObj::SQLTEXT_COMPILE, gen_code=@0x7fffffff29f0,
    gen_code_len=@0x7fffffff29f8, parserFlags=0, diagsArea=0x7fffe9750d00)
    at ../arkcmp/CmpContext.cpp:689
#13 0x00007ffff5faf857 in CliStatement::prepare2 (this=0x7fffe974e000,
    source=0x7fffe978a210 "select * from UDF(qa_tmudf2(TABLE(select * from mytable)));", diagsArea=..., passed_gen_code=<value optimized out>,
    passed_gen_code_len=3927642408, charset=15, unpackTdbs=1, cliFlags=129)
    at ../cli/Statement.cpp:1827
#14 0x00007ffff5fafca6 in CliStatement::prepare (this=0x7fffe974e000,
    source=0x7fffe978a210 "select * from UDF(qa_tmudf2(TABLE(select * from mytable)));", diagsArea=..., passed_gen_code=<value optimized out>,
    passed_gen_code_len=<value optimized out>, charset=<value optimized out>,
    unpackTdbs=1, cliFlags=129) at ../cli/Statement.cpp:1420
#15 0x00007ffff5f5f984 in SQLCLI_Prepare2 (cliGlobals=0xb82c00,
    statement_id=0x2953e80, sql_source=0x1b11b00, gencode_ptr=0x0,
    gencode_len=0, ret_gencode_len=0x0, query_cost_info=0x7fffffff3f50,
    query_comp_stats_info=0x7fffffff2cc0, uniqueStmtId=<value optimized out>,
    uniqueStmtIdLen=0x7fffffff4008, flags=129) at ../cli/Cli.cpp:5914
#16 0x00007ffff5fbcf50 in SQL_EXEC_Prepare2 (statement_id=0x2953e80,
    sql_source=0x1b11b00, gencode_ptr=0x0, gencode_len=0, ret_gencode_len=0x0,
    query_cost_info=0x7fffffff3f50, comp_stats_info=0x7fffffff2cc0,
    uniqueStmtId=0x7fffffff3dc0 " ", uniqueStmtIdLen=0x7fffffff4008,
    flags=129) at ../cli/CliExtern.cpp:4985
#17 0x00007ffff79cedaf in SqlCmd::do_prepare (sqlci_env=0xb819b0,
    prep_stmt=0xc5cb90,
    sqlStmt=0xee9aa0 "select * from UDF(qa_tmudf2(TABLE(select * from mytable)));", resetLastExecStmt=1, rsIndex=-49728, prepcode=0x7fffffff40dc,
    statisticsType=0x7fffffff40d8) at ../sqlci/SqlCmd.cpp:893
#18 0x00007ffff79ce1b0 in DML::process (this=0x295ba10, sqlci_env=0xb819b0)
    at ../sqlci/SqlCmd.cpp:2803
#19 0x00007ffff79b4a84 in Obey::process (this=0x29504c0,
    sqlci_env=<value optimized out>) at ../sqlci/Obey.cpp:264
#20 0x00007ffff79bcf14 in SqlciEnv::run (this=0xb819b0,
    in_filename=<value optimized out>, input_string=<value optimized out>)
    at ../sqlci/SqlciEnv.cpp:726
#21 0x00000000004019c2 in main (argc=3, argv=0x7fffffff43a8)
    at ../bin/SqlciMain.cpp:326

Tags: sql-cmp
Revision history for this message
Weishiun Tsai (wei-shiun-tsai) wrote :
Changed in trafodion:
assignee: nobody → Hans Zeller (hans-zeller)
Revision history for this message
Hans Zeller (hans-zeller) wrote :

Thanks, yes, I see two things wrong here. First, the CREATE FUNCTION should fail with an error, because we didn't find the entry point. Second, the SELECT needs to give a good error message, also saying that it cannot find the entry point.

Changed in trafodion:
status: New → In Progress
Revision history for this message
Hans Zeller (hans-zeller) wrote :

Am going to fix the SELECT part, but would like to defer the check at create function time, because it has security problems. Once we have isolated libraries and UDFs, it would not be safe to load such an isolated library to check for the existence of an entry point, we would need to go through udrserv. So, I don't want to introduce new code that adds even more security issues. Right now, the language manager does not validate any C routines.

Revision history for this message
Hans Zeller (hans-zeller) wrote :

Fix was delivered on March 18 as part of https://review.trafodion.org/1329

Changed in trafodion:
status: In Progress → Fix Committed
Revision history for this message
Weishiun Tsai (wei-shiun-tsai) wrote :

Verified on the v0330 build installed on a workstation. This problem is now fixed and the select statement returns a proper 11246 error.

>>create schema mytest;

--- SQL operation complete.
>>set schema mytest;

--- SQL operation complete.
>>
>>create library qaTmudfLib file '/designs/seaquest/wtsai/udf_bugs/udf_bug_LP1430438/qaTMUdfTest.so';

--- SQL operation complete.
>>
>>create table mytable (a int, b int);

--- SQL operation complete.
>>insert into mytable values (1,1),(2,2);

--- 2 row(s) inserted.
>>
>>create table_mapping function qa_tmudf1()
+>external name 'QA_TMUDF'
+>language cpp
+>library qaTmudfLib;

--- SQL operation complete.
>>
>>select * from UDF(qa_tmudf1(TABLE(select * from mytable)));

A B
----------- -----------

          1 1
          2 2

--- 2 row(s) selected.
>>
>>create table_mapping function qa_tmudf2()
+>external name 'DONTEXIST'
+>language cpp
+>library qaTmudfLib;

--- SQL operation complete.
>>
>>select * from UDF(qa_tmudf2(TABLE(select * from mytable)));

*** ERROR[11246] An error occurred locating function 'DONTEXIST' in library 'qaTMUdfTest.so'.

*** ERROR[8822] The statement was not prepared.

>>
>>drop schema mytest cascade;

*** ERROR[1069] Schema TRAFODION.MYTEST could not be dropped.

--- SQL operation failed with errors.

Changed in trafodion:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Bug attachments

Remote bug watches

Bug watches keep track of this bug in other bug trackers.