Re: pltcl crashes due to a syntax error

From: Pierre Forstmann <pierre(dot)forstmann(at)gmail(dot)com>
To: "a(dot)kozhemyakin" <a(dot)kozhemyakin(at)postgrespro(dot)ru>
Cc: pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: pltcl crashes due to a syntax error
Date: 2024-06-02 12:32:55
Message-ID: CAM-sOH9zC5VeycS0BFCV4CAEfDL4OLEh_41oWtVLfbOZCtxNFw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

I can also reproduce in Alma Linux 8.10 with tcl-devel 8.6.8

gdb says:

(gdb) p interp
$1 = (Tcl_Interp *) 0x288a500
(gdb) p *interp
$2 = {resultDontUse = 0x288a6d8 "", freeProcDontUse = 0x0,
errorLineDontUse = 1}
(gdb) p msg
No symbol "msg" in current context.
(gdb) p emsg
$3 = 0x27ebe48 "list element in braces followed by \")\" instead of space"

Involved PG source code is:

**********************************************************************
* throw_tcl_error - ereport an error returned from the Tcl interpreter
**********************************************************************/
static void
throw_tcl_error
<https://doxygen.postgresql.org/pltcl_8c.html#a82838fc9c33c4745329af8b74a52b27f>(Tcl_Interp
*interp, const char *proname
<https://doxygen.postgresql.org/pg__proc_8h.html#af3197a24ed757df3d91f9c41a3622b2c>
)
{
/*
* Caution is needed here because Tcl_GetVar could overwrite the
* interpreter result (even though it's not really supposed to), and we
* can't control the order of evaluation of ereport arguments. Hence, make
* real sure we have our own copy of the result string before invoking
* Tcl_GetVar.
*/
char *emsg;
char *econtext;

emsg = pstrdup
<https://doxygen.postgresql.org/mcxt_8c.html#a4c9fd325849ffd3be847d985ef319c41>
(utf_u2e
<https://doxygen.postgresql.org/pltcl_8c.html#aefb17648f789247bf5cfc5a9cd53f19c>
(Tcl_GetStringResult(interp)));
econtext = utf_u2e
<https://doxygen.postgresql.org/pltcl_8c.html#aefb17648f789247bf5cfc5a9cd53f19c>(Tcl_GetVar(interp,
"errorInfo", TCL_GLOBAL_ONLY));
ereport
<https://doxygen.postgresql.org/elog_8h.html#ae15bca8edf22ffe24b23e89348568b7c>
(ERROR
<https://doxygen.postgresql.org/elog_8h.html#a8fe83ac76edc595f6b98cd4a4127aed5>
,
(errcode
<https://doxygen.postgresql.org/elog_8c.html#ab243d4465b39d615088449de076a217d>
(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
errmsg
<https://doxygen.postgresql.org/elog_8c.html#ac15cbe2e9b7f41f40df622ac31521987>
("%s", emsg),
errcontext
<https://doxygen.postgresql.org/elog_8h.html#a26722e60709391a7cdd6e1881a220336>
("%s\nin PL/Tcl function \"%s\"",
econtext, proname
<https://doxygen.postgresql.org/pg__proc_8h.html#af3197a24ed757df3d91f9c41a3622b2c>
)));
}

I understand that Tcl_GetVar should not be used any more and should be
replaced by Tcl_GetStringResult
(but I know nothing about Tcl internals)

Following patch :
diff postgres/src/pl/tcl/pltcl.c.orig postgres/src/pl/tcl/pltcl.c
1373c1373,1376
< econtext = utf_u2e(Tcl_GetVar(interp, "errorInfo",
TCL_GLOBAL_ONLY));
---
> /*
> * econtext = utf_u2e(Tcl_GetVar(interp, "errorInfo",
TCL_GLOBAL_ONLY));
> */
> econtext = utf_u2e(Tcl_GetStringResult(interp));

gives:

pierre=# CREATE OR REPLACE PROCEDURE test_proc(INOUT a text)
AS $$
set aa [concat $1 "+" $1]
return [list $aa $aa])
$$
LANGUAGE pltcl;
CREATE PROCEDURE
pierre=# CALL test_proc('abc');
2024-06-02 14:22:45.223 CEST [61649] ERROR: list element in braces
followed by ")" instead of space
2024-06-02 14:22:45.223 CEST [61649] CONTEXT: list element in braces
followed by ")" instead of space
in PL/Tcl function "test_proc"
2024-06-02 14:22:45.223 CEST [61649] STATEMENT: CALL test_proc('abc');
ERROR: list element in braces followed by ")" instead of space
CONTEXT: list element in braces followed by ")" instead of space
in PL/Tcl function "test_proc"

PF

Le sam. 1 juin 2024 à 06:36, a.kozhemyakin <a(dot)kozhemyakin(at)postgrespro(dot)ru> a
écrit :

> Hello hackers,
>
> When executing the following query on master branch:
>
> CREATE EXTENSION pltcl;
> CREATE or replace PROCEDURE test_proc5(INOUT a text)
> LANGUAGE pltcl
> AS $$
> set aa [concat $1 "+" $1]
> return [list $aa $aa])
> $$;
>
> CALL test_proc5('abc');
> CREATE EXTENSION
> CREATE PROCEDURE
> server closed the connection unexpectedly
> This probably means the server terminated abnormally
> before or while processing the request.
> The connection to the server was lost. Attempting reset: Failed.
>
> The connection to the server was lost. Attempting reset: Failed.
>
>
> Core was generated by `postgres: postgres postgres [loca'.
> Program terminated with signal SIGSEGV, Segmentation fault.
> #0 __strlen_sse2 () at ../sysdeps/x86_64/multiarch/strlen-sse2.S:142
> 142 ../sysdeps/x86_64/multiarch/strlen-sse2.S: No such file or
> directory.
> (gdb) bt
> #0 __strlen_sse2 () at ../sysdeps/x86_64/multiarch/strlen-sse2.S:142
> #1 0x00007f5f1353ba6a in utf_u2e (src=0x0) at pltcl.c:77
> #2 0x00007f5f1353c9f7 in throw_tcl_error (interp=0x55ec24bdaf70,
> proname=0x55ec24b6b140 "test_proc5") at pltcl.c:1373
> #3 0x00007f5f1353ed64 in pltcl_func_handler
> (fcinfo=fcinfo(at)entry=0x7ffdbfb407a0,
> call_state=call_state(at)entry=0x7ffdbfb405d0,
> pltrusted=pltrusted(at)entry=true) at pltcl.c:1029
> #4 0x00007f5f1353ee8d in pltcl_handler (fcinfo=0x7ffdbfb407a0,
> pltrusted=pltrusted(at)entry=true) at pltcl.c:765
> #5 0x00007f5f1353f1ef in pltcl_call_handler (fcinfo=<optimized out>) at
> pltcl.c:698
> #6 0x000055ec239ec64a in ExecuteCallStmt
> (stmt=stmt(at)entry=0x55ec24a9a940, params=params(at)entry=0x0,
> atomic=atomic(at)entry=false, dest=dest(at)entry=0x55ec24a6ea18) at
> functioncmds.c:2285
> #7 0x000055ec23c103a7 in standard_ProcessUtility (pstmt=0x55ec24a9a9d8,
> queryString=0x55ec24a99e68 "CALL test_proc5('abc');",
> readOnlyTree=<optimized out>, context=PROCESS_UTILITY_TOPLEVEL,
> params=0x0, queryEnv=0x0, dest=0x55ec24a6ea18,
> qc=0x7ffdbfb40f40) at utility.c:851
> #8 0x000055ec23c1081b in ProcessUtility
> (pstmt=pstmt(at)entry=0x55ec24a9a9d8, queryString=<optimized out>,
> readOnlyTree=<optimized out>,
> context=context(at)entry=PROCESS_UTILITY_TOPLEVEL, params=<optimized out>,
> queryEnv=<optimized out>,
> dest=0x55ec24a6ea18, qc=0x7ffdbfb40f40) at utility.c:523
> #9 0x000055ec23c0e04e in PortalRunUtility
> (portal=portal(at)entry=0x55ec24b18108, pstmt=0x55ec24a9a9d8,
> isTopLevel=isTopLevel(at)entry=true,
> setHoldSnapshot=setHoldSnapshot(at)entry=true,
> dest=dest(at)entry=0x55ec24a6ea18, qc=qc(at)entry=0x7ffdbfb40f40)
> at pquery.c:1158
> #10 0x000055ec23c0e3b7 in FillPortalStore
> (portal=portal(at)entry=0x55ec24b18108, isTopLevel=isTopLevel(at)entry=true)
> at pquery.c:1031
> #11 0x000055ec23c0e6ee in PortalRun (portal=portal(at)entry=0x55ec24b18108,
> count=count(at)entry=9223372036854775807, isTopLevel=isTopLevel(at)entry=true,
> run_once=run_once(at)entry=true, dest=dest(at)entry=0x55ec24a9aec8,
> altdest=altdest(at)entry=0x55ec24a9aec8,
> qc=0x7ffdbfb41130) at pquery.c:763
> #12 0x000055ec23c0acca in exec_simple_query
> (query_string=query_string(at)entry=0x55ec24a99e68 "CALL
> test_proc5('abc');") at postgres.c:1274
> #13 0x000055ec23c0caad in PostgresMain (dbname=<optimized out>,
> username=<optimized out>) at postgres.c:4680
> #14 0x000055ec23c0687a in BackendMain (startup_data=<optimized out>,
> startup_data_len=<optimized out>) at backend_startup.c:105
> #15 0x000055ec23b766bf in postmaster_child_launch
> (child_type=child_type(at)entry=B_BACKEND,
> startup_data=startup_data(at)entry=0x7ffdbfb41354 "",
> startup_data_len=startup_data_len(at)entry=4,
> client_sock=client_sock(at)entry=0x7ffdbfb41390)
> at launch_backend.c:265
> #16 0x000055ec23b7ab36 in BackendStartup
> (client_sock=client_sock(at)entry=0x7ffdbfb41390) at postmaster.c:3593
> #17 0x000055ec23b7adb0 in ServerLoop () at postmaster.c:1674
> #18 0x000055ec23b7c20c in PostmasterMain (argc=argc(at)entry=3,
> argv=argv(at)entry=0x55ec24a54030) at postmaster.c:1372
> #19 0x000055ec23aacf9f in main (argc=3, argv=0x55ec24a54030) at main.c:197
>
>
>
>

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Alexander Korotkov 2024-06-02 13:18:11 Re: POC: GROUP BY optimization
Previous Message jian he 2024-06-02 07:55:44 Re: POC: GROUP BY optimization