Getting server crash on Windows when using ICU collation

From: Ashutosh Sharma <ashu(dot)coek88(at)gmail(dot)com>
To: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Getting server crash on Windows when using ICU collation
Date: 2017-06-10 09:55:31
Message-ID: CAE9k0P=+30KLJp1Fmhso4P9Ep9_SqXftCXukAxg_Q5GoQ4E7Kg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi All,

I am seeing a server crash when running queries using ICU collations on
Windows. Following are the steps to reproduce the crash with the help of
patch to enable icu feature on Windows - [1],

1) psql -d postgres

2) CREATE DATABASE icu_win_test
TEMPLATE template0
ENCODING 'UTF8'
LC_CTYPE 'C'
LC_COLLATE 'C';

3) \c icu_win_test;

4) icu_win_test=# select 'B' > 'a' COLLATE "de-u-co-standard-x-icu";
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 backtrace observed in the core dump is,

> postgres.exe!varstr_cmp(char * arg1, int len1, char * arg2, int len2,
unsigned int collid) Line 1494 C
postgres.exe!text_cmp(varlena * arg1, varlena * arg2, unsigned int
collid) Line 1627 C
postgres.exe!text_gt(FunctionCallInfoData * fcinfo) Line 1738 + 0x12
bytes C
postgres.exe!ExecInterpExpr(ExprState * state, ExprContext * econtext,
char * isnull) Line 650 + 0xa bytes C
postgres.exe!evaluate_expr(Expr * expr, unsigned int result_type, int
result_typmod, unsigned int result_collation) Line 4719 C
postgres.exe!evaluate_function(unsigned int funcid, unsigned int
result_type, int result_typmod, unsigned int result_collid, unsigned int
input_collid, List * args, char funcvariadic, HeapTupleData * func_tuple,
eval_const_expressions_context * context) Line 4272 + 0x50 bytes C
postgres.exe!simplify_function(unsigned int funcid, unsigned int
result_type, int result_typmod, unsigned int result_collid, unsigned int
input_collid, List * * args_p, char funcvariadic, char process_args, char
allow_non_const, eval_const_expressions_context * context) Line 3914 +
0x44 bytes C
postgres.exe!eval_const_expressions_mutator(Node * node,
eval_const_expressions_context * context) Line 2627 C
postgres.exe!expression_tree_mutator(Node * node, Node * (void)* mutator,
void * context) Line 2735 + 0x37 bytes C
postgres.exe!expression_tree_mutator(Node * node, Node * (void)* mutator,
void * context) Line 2932 + 0x8 bytes C
postgres.exe!eval_const_expressions(PlannerInfo * root, Node * node)
Line 2413 C
postgres.exe!subquery_planner(PlannerGlobal * glob, Query * parse,
PlannerInfo * parent_root, char hasRecursion, double tuple_fraction) Line
623 + 0x2d bytes C

RCA:
====
As seen in the backtrace, the crash is basically happening in varstr_cmp()
function. AFAICU, this crash is only happening on Windows because in
varstr_cmp(), if the encoding type is UTF8, we don't even think of calling
ICU functions to compare the string. Infact, we directly attempt to call
the OS function wsccoll*().

The point is, if collation provider is ICU, then we should tryto call ICU
functions for collation support instead of calling OS functions. This thing
is being taken care inside varstr_cmp() for Linux but surprisingly it's not
handled for Windows. Please have a look at below code snippet in
varstr_cmp() to know on how it is being taken care for linux,

*#endif /* WIN32 */*
........
........

*#ifdef USE_ICU#ifdef HAVE_UCOL_STRCOLLUTF8if (GetDatabaseEncoding() ==
PG_UTF8){ UErrorCode status; status = U_ZERO_ERROR; result =
ucol_strcollUTF8(mylocale->info.icu.ucol,
arg1, len1, arg2, len2,
&status); if (U_FAILURE(status))
ereport(ERROR, (errmsg("collation failed: %s",
u_errorName(status)))); }else#endif{ int32_t ulen1, ulen2;
UChar *uchar1, *uchar2; ulen1 = icu_to_uchar(&uchar1, arg1, len1);
ulen2 = icu_to_uchar(&uchar2, arg2, len2); result =
ucol_strcoll(mylocale->info.icu.ucol,
uchar1, ulen1, uchar2, ulen2); }#else /*
not USE_ICU *//* shouldn't happen */ elog(ERROR, "unsupported collprovider:
%c", mylocale->provider); #endif /* not USE_ICU */}else{#ifdef
HAVE_LOCALE_T result = strcoll_l(a1p, a2p, mylocale->info.lt
<http://info.lt>);#else /* shouldn't happen */ elog(ERROR,
"unsupported collprovider: %c", mylocale->provider);#endif}*

Fix:
====
I am currently working on this and will try to come up with the fix asap.

[1] -
https://www.postgresql.org/message-id/CAE9k0P%3DQRjtS1a0rgTyKag_%2Bs6XCs7vovV%2BgSkUfYVASog0P8w%40mail.gmail.com

--
With Regards,
Ashutosh Sharma
EnterpriseDB:http://www.enterprisedb.com

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Alvaro Herrera 2017-06-10 13:13:32 Re: PG10 transition tables, wCTEs and multiple operations on the same table
Previous Message Ashutosh Sharma 2017-06-10 09:40:02 ICU support on Windows