Blair Zajac wrote on Wed, Dec 22, 2010 at 22:26:15 -0800:
> On 12/22/10 4:38 PM, Daniel Shahaf wrote:
>> Blair Zajac wrote on Wed, Dec 22, 2010 at 13:22:11 -0800:
>>> On 12/22/10 10:56 AM, Daniel Shahaf wrote:
>>>> Blair Zajac wrote on Wed, Dec 22, 2010 at 10:45:12 -0800:
>>>>> It seems the best thing is to have svn_error_purge_tracing() return a
>>>>> brand new chain that shares no links with the original chain, and then
>>>>> both need to be freed.
>>>> That makes sense; if we'll work with complete chains, there's a smaller
>>>> chance of more edge-case bugs.
>>> Thinking on this a little more, since most people won't use debugging,
>>> it'll be wasteful to have svn_error_purge_tracing() make a duplicate
>>> chain that will have no tracing errors in it.
>> IOW, duplicating in maintainer mode forces duplicating in non-maintainer
>> mode too, making the common case costlier. True.
>> However, we could have a macro that causes the dup() operation to only
>> be done in maintainer mode:
>> void svn_error_purge_tracing_shell(svn_error_t **err_p)
>> #ifdef SVN_ERR__TRACING
>> svn_error_t *err = svn_error_purge_tracing(*err_p);
>> *err_p = err;
>> #endif /* SVN_ERR__TRACING */
>>> So maybe we should have svn_error_purge_tracing() be related to the input
>>> chain and share what it can, but not be an error chain one should use
>>> svn_error_clear() on.
>> IOW, change its promise such that it's the passed-in error, not the
>> returned one, which should be cleared? And have it leave the passed-in
>> chain untouched?
>> It makes sense on a first scan, but at 3am it's too late for a full +1.
> I've attached a patch to review. It fixes both svn_error_purge_tracing()
> and the the behavior of svn_repos__post_commit_error_str().
>>>>>> For example, shouldn't the following code trigger err_abort() on the
>>>>>> outer (wrapper) link?
>>>>>> svn_error_t *in = svn_error_create(...);
>>>>>> svn_error_t *original = svn_error_quick_wrap(in, SVN_ERR__TRACED);
>>>>>> svn_error_t *purged = svn_error_purge_tracing(original);
>>>>>> Am I making sense?
>>>>> I don't think so, because if SVN_DEBUG is defined, then it finds the
>>>>> error at the end of the chain, which in this example is a non-tracing
>>>>> error, and it'll properly remove the err_abort.
>>>> You're right, I'll modify my example to this:
>>>> SVN_ERR__TRACED /* start of chain */
>>>> "non-tracing link" /* end of chain */
>>>> In this case, the middle link would be lost. Right?
>>> Both SVN_ERR__TRACED would be lost by svn_error_purge_tracing(), right?
>> Won't the inner while() loop would skip over them?
> Yes, I think it would. We should probably write a unit test for
I've made a quick sketch --- looks good?
(I'll fix the "###" comment before committing.)
--- subversion/tests/libsvn_subr/error-test.c (revision 1052215)
+++ subversion/tests/libsvn_subr/error-test.c (working copy)
@@ -78,6 +78,34 @@ test_error_root_cause(apr_pool_t *pool)
+/* ### just make ../../libsvn_subr/error.c:is_tracing_link() semi-public */
+#define is_tracing_link(err) \
+ ((err) && (err)->message && !strcmp((err)->message, SVN_ERR__TRACED))
+#define is_tracing_link(err) FALSE
+static svn_error_t *
+ svn_error_t *err, *err2, *child;
+ err = svn_error_quick_wrap(svn_error_create(SVN_ERR_BASE, NULL, "root error"),
+ err = svn_error_quick_wrap(svn_error_create(SVN_ERR_BASE, err, "other error"),
+ err2 = svn_error_purge_tracing(err);
+ for (child = err2; child; child = child->child)
+ if (is_tracing_link(child))
+ return svn_error_create(SVN_ERR_TEST_FAILED, err,
+ "Tracing link found after purging the following chain:");
+ return SVN_NO_ERROR;
/* The test table. */
@@ -86,5 +114,7 @@ struct svn_test_descriptor_t test_funcs =
+ "test svn_error_purge_tracing"),
> Index: subversion/libsvn_subr/error.c
> --- subversion/libsvn_subr/error.c (revision 1052167)
> +++ subversion/libsvn_subr/error.c (working copy)
> @@ -349,39 +349,47 @@
> svn_error_purge_tracing(svn_error_t *err)
> #ifdef SVN_ERR__TRACING
> return new_err;
> #else /* SVN_ERR__TRACING */
> return err;
> Index: subversion/mod_dav_svn/deadprops.c
> --- subversion/mod_dav_svn/deadprops.c (revision 1052167)
> +++ subversion/mod_dav_svn/deadprops.c (working copy)
> @@ -222,18 +222,22 @@
> + purged_serr->message = apr_xml_quote_string
> + (purged_serr->pool,
Our current policy is to have the '(' on the same line as the function name.
> Index: subversion/mod_dav_svn/version.c
> --- subversion/mod_dav_svn/version.c (revision 1052167)
> +++ subversion/mod_dav_svn/version.c (working copy)
> @@ -922,16 +922,16 @@
> if (serr)
> - const char *post_commit_err;
> - apr_err = serr->apr_err;
> - post_commit_err = svn_repos__post_commit_error_str
> - (serr, resource->pool);
> - serr = SVN_NO_ERROR;
> - ap_log_perror(APLOG_MARK, APLOG_ERR, apr_err, resource->pool,
> + const char *post_commit_err = svn_repos__post_commit_error_str
> + (serr, resource->pool);
> + ap_log_perror(APLOG_MARK, APLOG_ERR, serr->apr_err,
> + resource->pool,
The rest looks good. (I am assuming --- didn't check --- that you
updated all callers.)
Received on 2010-12-23 12:04:07 CET