Question on ThrowErrorData - Mailing list pgsql-hackers

From 正华吕
Subject Question on ThrowErrorData
Date
Msg-id CANerzAd7KzYyOcZy2am8XJExkNaeN4-C+Y-VSeKOpBDxR5xgJA@mail.gmail.com
Whole thread Raw
Responses Re: Question on ThrowErrorData
List pgsql-hackers
Hi all,
   
    reading the source code of ThrowErrorData,
    it try to copy an ErrorData object into the correct memory context:
    
    newedata = &errordata[errordata_stack_depth];
    recursion_depth++;
    oldcontext = MemoryContextSwitchTo(newedata->assoc_context);

    /* Copy the supplied fields to the error stack entry. */
    if (edata->sqlerrcode != 0)
        newedata->sqlerrcode = edata->sqlerrcode;
    if (edata->message)
        newedata->message = pstrdup(edata->message);
    if (edata->detail)
        newedata->detail = pstrdup(edata->detail);
    if (edata->detail_log)
        newedata->detail_log = pstrdup(edata->detail_log);
     .....


     At the end of the function ThrowErrorData(), it calls
     errfinish(edata->filename, edata->lineno, edata->funcname);

     Inside errfinish, it just does a simple pointer assignment to set
     filename and funcname field (via function set_stack_entry_location()).

     So it might lead to an ErrorData object's filename, funcname are in
     different memory context from edata->assoc_context, breaks the contract
     of edata->assoc_context.

     I tried but until now not manage to build a bad case that make the pointer
     dangling. Still I feel it is a potential risk. We could also copy such two fields
     into correct memory context like:


diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 29643c51439..7859047df6a 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -820,9 +820,9 @@ set_stack_entry_location(ErrorData *edata,
                        filename = slash + 1;
        }

-       edata->filename = filename;
+       edata->filename = MemoryContextStrdup(edata->assoc_context, filename);
        edata->lineno = lineno;
-       edata->funcname = funcname;
+       edata->funcname = MemoryContextStrdup(edata->assoc_context, funcname);
 }


Any ideas? Thanks!

Best,
Zhenghua Lyu
   
   

pgsql-hackers by date:

Previous
From: Shinya Kato
Date:
Subject: Re: Fix lag columns in pg_stat_replication not advancing when replay LSN stalls
Next
From: David Rowley
Date:
Subject: Use CompactAttribute more often, when possible