On 06.02.2015 19:58, Dmitry Yemanov wrote:

> At the first glance, one might think that all we need is to change
> stuff_exception() to append instead of overwriting. But it's not really
> so. Given how many times we may catch and re-throw within the call
> stack, I'd expect lots of duplicated items inside the status vector. And
> proper duplication checking (with strcmp for string args) looks like an
> overkill.

I do not see too big trouble with full checks of string args. But what 
about keeping legacy dup check present in ERR_post()? Taking into an 
account that string once made permanent will remain the same per thread 
suppose it will be enough for most cases.

> There may be other unexpected side effects in this solution too.
>
> A long-term solution would include:
>
> - fixing all direct tdbb_status_vector checks
> - removing tdbb_status_vector completely
> - removing stuff_exception too

Completely removing tdbb_status_vector will break warnings delivery. And 
on my mind merging tdbb_status_vector with new error in stuffException 
is better way compared with adding try/catch block to catch blocks.

> But that's surely for another day. For v3, I can think only about the
> following approach:
>
> catch (const Exception& ex)
> {
>     Arg::StatusVector error(ex);
>
>     try
>     {
>       <some code>
>     }
>     catch (const Exception& ex2)
>     {
>       error.append(ex2);
>     }
>
>     error.raise();
> }
>
> Of course, in many cases it's unnecessary and would just pollute the
> code. So we need to carefully analyze every catch() block for possible
> side effects like throwing exceptions from inside. Fortunately, most of
> them are not really important in practice, so it's not a showstopper.

That's very dangerous approach. Imagine the following catch block:

catch (const Exception& ex)
{
     Arg::StatusVector error(ex);

     a += b;

     error.raise();
}

As long as 'a' and 'b' are trivial numeric types we do not add try/catch 
around it. Later they become some classes (with increased precision for 
example) that can throw errors. Certainly one doing that change does not 
care about try/catch and hops - we have initial error lost.

I.e. if we decide to go this way we should do this with all catch blocks 
which is a change not differing much in volume of changes from changing 
tdbb_status_vector to something capable to store unlimited length vectors.

>
> A more complex case is the looper which holds an active exception inside
> tdbb_status_vector for the whole duration of the unwinding process, but
> it also looks solvable.
>
> I have draftly implemented this approach for the looper and it seems to
> work, now I see both original and backout errors reported. This resolves
> the mostly visible reason of the problem.
>
> But maybe someone can suggest a better solution?
>

I think that merging errors in stuffException() is both simpler and more 
efficient.


------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
Firebird-Devel mailing list, web interface at 
https://lists.sourceforge.net/lists/listinfo/firebird-devel

Reply via email to