Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5d6c64d

Browse files
committed
Avoid crashing when a JIT-inlined backend function throws an error.
errfinish() assumes that the __FUNC__ and __FILE__ arguments it'spassed are compile-time constant strings that can just be pointedto rather than physically copied. However, it's possible for LLVMto generate code in which those pointers point into a dynamicallyloaded code segment. If that segment gets unloaded before we'redone with the ErrorData struct, we have dangling pointers thatwill lead to SIGSEGV. In simple cases that won't happen, because wewon't unload LLVM code before end of transaction. But it's possibleto happen if the error is thrown within end-of-transaction code run by_SPI_commit or _SPI_rollback, because since commit2e51781 thosefunctions clean up by ending the transaction and starting a new one.Rather than fixing this by adding pstrdup() overhead to everyelog/ereport sequence, let's fix it by copying the risky pointersin CopyErrorData(). That solves it for _SPI_commit/_SPI_rollbackbecause they use that function to preserve the error data acrossthe transaction end/restart sequence; and it seems likely thatany other code doing something similar would need to do that too.I'm suspicious that this behavior amounts to an LLVM bug (or abug in our use of it?), because it implies that string constantreferences that should be pointer-equal according to a naiveunderstanding of C semantics will sometimes not be equal.However, even if it is a bug and someday gets fixed, we'll haveto cope with the current behavior for a long time to come.Report and patch by me. Back-patch to all supported branches.Discussion:https://postgr.es/m/1565654.1719425368@sss.pgh.pa.us
1 parentcbfbda7 commit5d6c64d

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

‎src/backend/utils/error/elog.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1743,7 +1743,21 @@ CopyErrorData(void)
17431743
newedata= (ErrorData*)palloc(sizeof(ErrorData));
17441744
memcpy(newedata,edata,sizeof(ErrorData));
17451745

1746-
/* Make copies of separately-allocated fields */
1746+
/*
1747+
* Make copies of separately-allocated strings. Note that we copy even
1748+
* theoretically-constant strings such as filename. This is because those
1749+
* could point into JIT-created code segments that might get unloaded at
1750+
* transaction cleanup. In some cases we need the copied ErrorData to
1751+
* survive transaction boundaries, so we'd better copy those strings too.
1752+
*/
1753+
if (newedata->filename)
1754+
newedata->filename=pstrdup(newedata->filename);
1755+
if (newedata->funcname)
1756+
newedata->funcname=pstrdup(newedata->funcname);
1757+
if (newedata->domain)
1758+
newedata->domain=pstrdup(newedata->domain);
1759+
if (newedata->context_domain)
1760+
newedata->context_domain=pstrdup(newedata->context_domain);
17471761
if (newedata->message)
17481762
newedata->message=pstrdup(newedata->message);
17491763
if (newedata->detail)
@@ -1756,6 +1770,8 @@ CopyErrorData(void)
17561770
newedata->context=pstrdup(newedata->context);
17571771
if (newedata->backtrace)
17581772
newedata->backtrace=pstrdup(newedata->backtrace);
1773+
if (newedata->message_id)
1774+
newedata->message_id=pstrdup(newedata->message_id);
17591775
if (newedata->schema_name)
17601776
newedata->schema_name=pstrdup(newedata->schema_name);
17611777
if (newedata->table_name)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp