Hi pá 8. 3. 2019 v 3:44 odesílatel Alvaro Herrera <alvhe...@2ndquadrant.com> napsal:
> On 2019-Mar-07, Alvaro Herrera wrote: > > > On 2019-Feb-11, Chapman Flack wrote: > > > > > xmltable-xpath-result-processing-bugfix-6.patch includes a > regress/expected > > > output for the no-libxml case that was left out of -5. > > > > Pushed this one, with some trivial changes: I renamed and relocated > > Pavel's function to strdup-and-free and fused the new test cases to use > > less queries for the same functionality. Naturally I had to adjust the > > expected files ... I tried to do my best but there's always a little > > something that sneaks under one's nose. > > So we now have a double-free bug here or something ... Too tired right > now to do anything about it. > > > https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=grison&dt=2019-03-08%2002%3A00%3A02 > > ================== stack trace: > pgsql.build/src/test/regress/tmp_check/data/core ================== > [New LWP 20275] > > warning: Can't read pathname for load map: Input/output error. > [Thread debugging using libthread_db enabled] > Using host libthread_db library > "/lib/arm-linux-gnueabihf/libthread_db.so.1". > Core was generated by `postgres: pgbuildfarm regression [local] SELECT > '. > Program terminated with signal 11, Segmentation fault. > #0 0x76a32e04 in free () from /lib/arm-linux-gnueabihf/libc.so.6 > #0 0x76a32e04 in free () from /lib/arm-linux-gnueabihf/libc.so.6 > #1 0x76e28380 in xmlFreeNode () from > /usr/lib/arm-linux-gnueabihf/libxml2.so.2 > #2 0x00481f94 in xml_xmlnodetoxmltype (cur=<optimized out>, > xmlerrcxt=<optimized out>) at xml.c:3751 > #3 0x004823dc in XmlTableGetValue (state=0x148c370, colnum=1994818404, > typid=2124685192, typmod=0, isnull=0x7ea42117) at xml.c:4540 > #4 0x0026df60 in tfuncLoadRows (econtext=0x2, tstate=0x14a8578) at > nodeTableFuncscan.c:489 > #5 tfuncFetchRows (tstate=0x14a8578, econtext=0x2) at > nodeTableFuncscan.c:318 > #6 0x0026e248 in TableFuncNext (node=0x14a83e0) at nodeTableFuncscan.c:65 > #7 0x0023e640 in ExecScanFetch (recheckMtd=0x23e640 <ExecScan+816>, > accessMtd=0x26db1c <TableFuncRecheck>, node=0x14a83e0) at execScan.c:93 > #8 ExecScan (node=0x14a83e0, accessMtd=0x26db1c <TableFuncRecheck>, > recheckMtd=0x23e640 <ExecScan+816>) at execScan.c:143 > #9 0x0023c638 in ExecProcNodeFirst (node=0x14a83e0) at execProcnode.c:445 > #10 0x00235630 in ExecProcNode (node=0x14a83e0) at > ../../../src/include/executor/executor.h:241 > #11 ExecutePlan (execute_once=<optimized out>, dest=0x14b8d08, > direction=<optimized out>, numberTuples=0, sendTuples=<optimized out>, > operation=CMD_SELECT, use_parallel_mode=<optimized out>, > planstate=0x14a83e0, estate=0x14a82a0) at execMain.c:1643 > #12 standard_ExecutorRun (queryDesc=0x142c0e0, direction=<optimized out>, > count=0, execute_once=true) at execMain.c:362 > #13 0x003955f4 in PortalRunSelect (portal=0x13e3f48, forward=<optimized > out>, count=0, dest=<optimized out>) at pquery.c:929 > #14 0x00396a0c in PortalRun (portal=0x0, count=0, isTopLevel=<optimized > out>, run_once=<optimized out>, dest=0x14b8d08, altdest=0x14b8d08, > completionTag=0x7ea42414 "") at pquery.c:770 > #15 0x003923c8 in exec_simple_query (query_string=0x7ea42414 "") at > postgres.c:1215 > #16 0x00393e8c in PostgresMain (argc=<optimized out>, argv=<optimized > out>, dbname=0x0, username=<optimized out>) at postgres.c:4256 > #17 0x000849a8 in BackendRun (port=0x13967b8) at postmaster.c:4399 > #18 BackendStartup (port=0x13967b8) at postmaster.c:4090 > #19 ServerLoop () at postmaster.c:1703 > #20 0x0031607c in PostmasterMain (argc=<optimized out>, argv=<optimized > out>) at postmaster.c:1376 > #21 0x000864d4 in main (argc=7301080, argv=0x8) at main.c:228 > I have not any hypotheses what is reason - maybe we hit some libxml2 error in xmlCopyNode function - now it is called for larger set of node types. What I see, a error handling in original code was not probably correct. Hard to say if attached patch fix it, but probably it is more correct than now. Regards Pavel > > -- > Álvaro Herrera https://www.2ndQuadrant.com/ > PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services >
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c index 28b3eaaa20..173784da4b 100644 --- a/src/backend/utils/adt/xml.c +++ b/src/backend/utils/adt/xml.c @@ -3720,31 +3720,42 @@ xml_xmlnodetoxmltype(xmlNodePtr cur, PgXmlErrorContext *xmlerrcxt) if (cur->type != XML_ATTRIBUTE_NODE && cur->type != XML_TEXT_NODE) { - xmlBufferPtr buf; - xmlNodePtr cur_copy; + volatile xmlBufferPtr buf = NULL; + volatile xmlNodePtr cur_copy = NULL; - buf = xmlBufferCreate(); + PG_TRY(); + { + int bytes; - /* - * The result of xmlNodeDump() won't contain namespace definitions - * from parent nodes, but xmlCopyNode() duplicates a node along with - * its required namespace definitions. - */ - cur_copy = xmlCopyNode(cur, 1); + buf = xmlBufferCreate(); - if (cur_copy == NULL) - xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, - "could not copy node"); + if (buf == NULL || xmlerrcxt->err_occurred) + xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, + "could not allocate xmlBuffer"); + + /* + * The result of xmlNodeDump() won't contain namespace definitions + * from parent nodes, but xmlCopyNode() duplicates a node along with + * its required namespace definitions. + */ + cur_copy = xmlCopyNode(cur, 1); + if (cur == NULL || xmlerrcxt->err_occurred) + xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, + "could not copy node"); + + bytes = xmlNodeDump(buf, NULL, cur_copy, 0, 1); + if (bytes == -1 || xmlerrcxt->err_occurred) + xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, + "could not dump node"); - PG_TRY(); - { - xmlNodeDump(buf, NULL, cur_copy, 0, 1); result = xmlBuffer_to_xmltype(buf); } PG_CATCH(); { - xmlFreeNode(cur_copy); - xmlBufferFree(buf); + if (cur_copy) + xmlFreeNode(cur_copy); + if (buf) + xmlBufferFree(buf); PG_RE_THROW(); } PG_END_TRY();