[cfe-dev] [Bug] Wrong Exception Handling : Destructor not called immediately

suyog sarda sardask01 at gmail.com
Wed Apr 23 11:02:35 PDT 2014


Hi all,

Finally !! Some interesting findings from my side on why this issue is
happening. I will try to explain my findings with pseudo code :

Sample pseudo code and how clang process it :

Consider our code having three class a,b and c



*main(){*

*    try {*

*           b tmp1();*



*           c tmp2(b(a));      }*


*   catch {...}}*

A piece of code in clang to focus :





*void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
EnterCXXTryStmt(S);  EmitStmt(S.getTryBlock());  ExitCXXTryStmt(S);}*

There is an EHStack, which will contain entries which will be popped out to
emit cleanup code (destructor) in case of exception happening.

When try-catch block is encountered, we visit *'EmitStmt'* function, after
some more function call we visit following code for emitting code for local
variables *tmp1* and *tmp2:*





*void CodeGenFunction::EmitAutoVarDecl(const VarDecl &D) {  AutoVarEmission
emission = EmitAutoVarAlloca(D);  EmitAutoVarInit(emission);
EmitAutoVarCleanups(emission);}*

First we visit *EmitAutoVarInit *where some initialization happens by
visiting inner expression. For *tmp1* object inner expression is empty, so
next function *EmitAutoVarCleanup* will be called and entry of this object
*tmp1* will be put into EHStack. Since the scope of* tmp1* is till end of
try block, it will remain in EHStack till try block exits.

Next, We visit second object *tmp2* construction, where inner expression
consist of temporaries. We visit function *EmitAutoVarInit *where we
process inner expression. Entries of Inner temporary are added into EHStack
till all temporary entries are processed, but as soon as the processing of
all temporaries gets over i.e. their scope gets over, these entries are
popped out of EHstack and their destructor is called as a part of cleanup
code.
Please note we are yet to add entry of *tmp2 *in EHStack as we are yet to
visit *EmitAutoVarCleanups* function.

Now, The main problem starts - if any of the destructor of temporaries
throw, we visit EHStack, pop out each entry from EHStack and emit cleanup
code (destructor) for each entry. Note that, the entry of outermost local
variable is still not present in the EHStack as we are yet to visit
function *EmitAutoVarCleanups, *as a result of this, its cleanup code
(destructor) is not emitted and we land into resource leak!!

I just altered the order of function calls - first call *EmitAutoVarCleanups
*and then *EmitAutoVarInit - *which ensures that entry of auto variables
are added in EHStack before we process inner expression*. *This resolves
our original issue 'init-temp1.c', however it introduces 10 regressions all
related to location of destructors of temporaries.

This is a resource leak issue and hence i am pressing more on it (Order in
which destructors should be called is not clear, but we should eliminate
atleast the resource leak). I am not sure although if my approach to
resolve this issue is ok. Basically, we somehow need to ensure that auto
object entry gets added in EHStack (may be a call to
*EmitAutoVarCleanups* function)
before we pop out entries for temporaries.

All your suggestions/comments/rectifications are most awaited.

-- 
With regards,
Suyog Sarda
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140423/c7331b58/attachment.html>


More information about the cfe-dev mailing list