You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2012/07/04 17:40:59 UTC

svn commit: r1357313 - in /subversion/trunk/subversion/svn: cl.h notify.c update-cmd.c

Author: stsp
Date: Wed Jul  4 15:40:59 2012
New Revision: 1357313

URL: http://svn.apache.org/viewvc?rev=1357313&view=rev
Log:
When running the conflict resolver at the end of an 'svn update' operation,
resolve conflicts only on paths which got new conflicts flagged during the
update operation, rather than also resolving conflicts which were left behind
within the update targets by some other operation.

* subversion/svn/cl.h
  (svn_cl__notifier_get_conflicted_paths): Declare.

* subversion/svn/notify.c
  (notify_baton): Add conflicted_paths hash.
  (add_conflicted_path): New helper to add a conflicted path to above hash.
  (notify): Add any confliced paths to above hash.
  (svn_cl__get_notifier): Initialise the conflicted_paths hash.
  (svn_cl__notifier_get_conflicted_paths): Return a path-wise sorted array
   of confliced paths added during notification.

* subversion/svn/update-cmd.c
  (svn_cl__update): Pass the list of newly conflicted paths to the resolver,
   rather than passing the entire update target list.

Modified:
    subversion/trunk/subversion/svn/cl.h
    subversion/trunk/subversion/svn/notify.c
    subversion/trunk/subversion/svn/update-cmd.c

Modified: subversion/trunk/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl.h?rev=1357313&r1=1357312&r2=1357313&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/cl.h (original)
+++ subversion/trunk/subversion/svn/cl.h Wed Jul  4 15:40:59 2012
@@ -607,6 +607,10 @@ svn_cl__notifier_mark_wc_to_repos_copy(v
 svn_boolean_t
 svn_cl__notifier_check_conflicts(void *baton);
 
+/* Return a sorted array of conflicted paths detected during notification. */
+apr_array_header_t *
+svn_cl__notifier_get_conflicted_paths(void *baton, apr_pool_t *result_pool);
+
 /* Baton for use with svn_cl__check_externals_failed_notify_wrapper(). */
 struct svn_cl__check_externals_failed_notify_baton
 {

Modified: subversion/trunk/subversion/svn/notify.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/notify.c?rev=1357313&r1=1357312&r2=1357313&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/notify.c (original)
+++ subversion/trunk/subversion/svn/notify.c Wed Jul  4 15:40:59 2012
@@ -35,6 +35,7 @@
 #include "svn_pools.h"
 #include "svn_dirent_uri.h"
 #include "svn_path.h"
+#include "svn_sorts.h"
 #include "cl.h"
 
 #include "svn_private_config.h"
@@ -57,6 +58,7 @@ struct notify_baton
   unsigned int prop_conflicts;
   unsigned int tree_conflicts;
   unsigned int skipped_paths;
+  apr_hash_t *conflicted_paths;
 
   /* The cwd, for use in decomposing absolute paths. */
   const char *path_prefix;
@@ -100,6 +102,16 @@ svn_cl__print_conflict_stats(void *notif
   return SVN_NO_ERROR;
 }
 
+/* Add a conflicted path to the list of conflicted paths stored
+ * in the notify baton. */
+static void
+add_conflicted_path(struct notify_baton *nb, const char *path)
+{
+  apr_hash_set(nb->conflicted_paths,
+               apr_pstrdup(apr_hash_pool_get(nb->conflicted_paths), path),
+               APR_HASH_KEY_STRING, "");
+}
+
 /* This implements `svn_wc_notify_func2_t'.
  * NOTE: This function can't fail, so we just ignore any print errors. */
 static void
@@ -213,6 +225,7 @@ notify(void *baton, const svn_wc_notify_
       if (n->content_state == svn_wc_notify_state_conflicted)
         {
           nb->text_conflicts++;
+          add_conflicted_path(nb, n->path);
           if ((err = svn_cmdline_printf(pool, "C    %s\n", path_local)))
             goto print_error;
         }
@@ -228,6 +241,7 @@ notify(void *baton, const svn_wc_notify_
       if (n->content_state == svn_wc_notify_state_conflicted)
         {
           nb->text_conflicts++;
+          add_conflicted_path(nb, n->path);
           statchar_buf[0] = 'C';
         }
       else
@@ -236,6 +250,7 @@ notify(void *baton, const svn_wc_notify_
       if (n->prop_state == svn_wc_notify_state_conflicted)
         {
           nb->prop_conflicts++;
+          add_conflicted_path(nb, n->path);
           statchar_buf[1] = 'C';
         }
       else if (n->prop_state == svn_wc_notify_state_merged)
@@ -302,6 +317,7 @@ notify(void *baton, const svn_wc_notify_
         if (n->content_state == svn_wc_notify_state_conflicted)
           {
             nb->text_conflicts++;
+            add_conflicted_path(nb, n->path);
             statchar_buf[0] = 'C';
           }
         else if (n->kind == svn_node_file)
@@ -315,6 +331,7 @@ notify(void *baton, const svn_wc_notify_
         if (n->prop_state == svn_wc_notify_state_conflicted)
           {
             nb->prop_conflicts++;
+            add_conflicted_path(nb, n->path);
             statchar_buf[1] = 'C';
           }
         else if (n->prop_state == svn_wc_notify_state_changed)
@@ -508,6 +525,7 @@ notify(void *baton, const svn_wc_notify_
         if (n->content_state == svn_wc_notify_state_conflicted)
           {
             nb->text_conflicts++;
+            add_conflicted_path(nb, n->path);
             statchar_buf[0] = 'C';
           }
         else if (n->kind == svn_node_file)
@@ -521,6 +539,7 @@ notify(void *baton, const svn_wc_notify_
         if (n->prop_state == svn_wc_notify_state_conflicted)
           {
             nb->prop_conflicts++;
+            add_conflicted_path(nb, n->path);
             statchar_buf[1] = 'C';
           }
         else if (n->prop_state == svn_wc_notify_state_merged)
@@ -898,6 +917,7 @@ notify(void *baton, const svn_wc_notify_
 
     case svn_wc_notify_tree_conflict:
       nb->tree_conflicts++;
+      add_conflicted_path(nb, n->path);
       if ((err = svn_cmdline_printf(pool, "   C %s\n", path_local)))
         goto print_error;
       break;
@@ -1038,6 +1058,7 @@ svn_cl__get_notifier(svn_wc_notify_func2
   nb->prop_conflicts = 0;
   nb->tree_conflicts = 0;
   nb->skipped_paths = 0;
+  nb->conflicted_paths = apr_hash_make(pool);
   SVN_ERR(svn_dirent_get_absolute(&nb->path_prefix, "", pool));
 
   *notify_func_p = notify;
@@ -1093,3 +1114,13 @@ svn_cl__notifier_check_conflicts(void *b
 
   return (nb->text_conflicts || nb->prop_conflicts || nb->tree_conflicts);
 }
+
+apr_array_header_t *
+svn_cl__notifier_get_conflicted_paths(void *baton, apr_pool_t *result_pool)
+{
+  struct notify_baton *nb = baton;
+
+  return svn_sort__hash(nb->conflicted_paths,
+                        svn_sort_compare_items_as_paths,
+                        result_pool);
+}

Modified: subversion/trunk/subversion/svn/update-cmd.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/update-cmd.c?rev=1357313&r1=1357312&r2=1357313&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/update-cmd.c (original)
+++ subversion/trunk/subversion/svn/update-cmd.c Wed Jul  4 15:40:59 2012
@@ -183,7 +183,10 @@ svn_cl__update(apr_getopt_t *os,
     {
       ctx->conflict_func2 = conflict_func2;
       ctx->conflict_baton2 = conflict_baton2;
-      SVN_ERR(svn_cl__resolve_conflicts(targets, depth, ctx, scratch_pool));
+      SVN_ERR(svn_cl__resolve_conflicts(
+                svn_cl__notifier_get_conflicted_paths(nwb.wrapped_baton,
+                                                      scratch_pool),
+                depth, ctx, scratch_pool));
     }
 
   if (nwb.had_externals_error)



RE: svn commit: r1357313 - in /subversion/trunk/subversion/svn: cl.h notify.c update-cmd.c

Posted by Bert Huijben <be...@qqmail.nl>.

> -----Original Message-----
> From: Paul Burba [mailto:ptburba@gmail.com]
> Sent: woensdag 5 september 2012 23:25
> To: Julian Foad
> Cc: Stefan Sperling; dev@subversion.apache.org
> Subject: Re: svn commit: r1357313 - in /subversion/trunk/subversion/svn:
> cl.h notify.c update-cmd.c
> 
> On Wed, Sep 5, 2012 at 11:11 AM, Julian Foad
> <ju...@btopenworld.com> wrote:
> > Stefan Sperling wrote:
> >
> >> On Tue, Sep 04, 2012 at 03:01:22PM -0400, Paul Burba wrote:
> >>>  I just noticed that this causes a segfault when updating with
> >>> the quiet option:
> >>
> >> Thanks for digging into this and explaining the problem, Paul.
> >>
> >> I cannot think of a better way to fix this than recording in
> >> opt_state whether the notifier is being used. That way we
> >> have a way of telling whether it is safe to ask the notifier
> >> for a list of conflicted paths.

So now -q changes the behavior of the conflict resolver?

Sounds like an ugly hack, to me.

I think we should install an old style interactive conflict handler to collect the conflicted paths and make it jusr postpone all conflicts. That will give us the list for resolving after the operation.

Another option is making the true notifications optional in the notification handler and always installing it just to collect the conflicted paths, but installing a conflict handler for that seems like a cleaner solution to me?

The conflict handler might be extendable to handle --accept theirs-full and some others directly, while postponing the conflicts that must be handled interactive later.

	Bert


Re: svn commit: r1357313 - in /subversion/trunk/subversion/svn: cl.h notify.c update-cmd.c

Posted by Paul Burba <pt...@gmail.com>.
On Wed, Sep 5, 2012 at 11:11 AM, Julian Foad <ju...@btopenworld.com> wrote:
> Stefan Sperling wrote:
>
>> On Tue, Sep 04, 2012 at 03:01:22PM -0400, Paul Burba wrote:
>>>  I just noticed that this causes a segfault when updating with
>>> the quiet option:
>>
>> Thanks for digging into this and explaining the problem, Paul.
>>
>> I cannot think of a better way to fix this than recording in
>> opt_state whether the notifier is being used. That way we
>> have a way of telling whether it is safe to ask the notifier
>> for a list of conflicted paths.
>>
>> What you do think?
>
> Just a drive-by comment: isn't "ctx->notify_func2 != NULL" a good "notifier is in use" flag?

I think you mean ctx->notify_func?  Because
libsvn_client/ctx.c:svn_client_create_context unconditionally sets the
notify_func2 member to libsvn_client/ctx.c:call_notify_func, which
calls...ctx->notify_func.  So the latter would work, but it seems a
bit dubious since svn_client_ctx_t->notify_func is deprecated:

  typedef struct svn_client_ctx_t
  {
    /** main authentication baton. */
    svn_auth_baton_t *auth_baton;

    /** notification callback function.
     * This will be called by notify_func2() by default.
     * @deprecated Provided for backward compatibility with the 1.1 API.
     * Use @c notify_func2 instead. */
    svn_wc_notify_func_t notify_func;

I think Stefan's suggested patch is the clearer solution.

-- 
Paul T. Burba
CollabNet, Inc. -- www.collab.net -- Enterprise Cloud Development
Skype: ptburba

> (And I removed 'commits@' from the CC.)
>
> - Julian

Re: svn commit: r1357313 - in /subversion/trunk/subversion/svn: cl.h notify.c update-cmd.c

Posted by Julian Foad <ju...@btopenworld.com>.
Stefan Sperling wrote:

> On Tue, Sep 04, 2012 at 03:01:22PM -0400, Paul Burba wrote:
>>  I just noticed that this causes a segfault when updating with
>> the quiet option:
> 
> Thanks for digging into this and explaining the problem, Paul.
> 
> I cannot think of a better way to fix this than recording in
> opt_state whether the notifier is being used. That way we
> have a way of telling whether it is safe to ask the notifier
> for a list of conflicted paths.
> 
> What you do think?

Just a drive-by comment: isn't "ctx->notify_func2 != NULL" a good "notifier is in use" flag?

(And I removed 'commits@' from the CC.)

- Julian

Re: svn commit: r1357313 - in /subversion/trunk/subversion/svn: cl.h notify.c update-cmd.c

Posted by Stefan Sperling <st...@apache.org>.
On Tue, Sep 04, 2012 at 03:01:22PM -0400, Paul Burba wrote:
> I just noticed that this causes a segfault when updating with the quiet option:
> 
> [[[
> 
> C:\SVN\src-trunk>svn up
> Updating '.':
> At revision 1380738.
> 
> C:\SVN\src-trunk>svn up -q
> This application has halted due to an unexpected error.

Thanks for digging into this and explaining the problem, Paul.

I cannot think of a better way to fix this than recording in
opt_state whether the notifier is being used. That way we
have a way of telling whether it is safe to ask the notifier
for a list of conflicted paths.

What you do think?

Index: subversion/svn/cl.h
===================================================================
--- subversion/svn/cl.h	(revision 1381156)
+++ subversion/svn/cl.h	(working copy)
@@ -238,6 +238,8 @@ typedef struct svn_cl__opt_state_t
   svn_boolean_t include_externals; /* Recurses (in)to file & dir externals */
   const char *search_pattern;     /* pattern argument for --search */
   svn_boolean_t case_insensitive_search; /* perform case-insensitive search */
+  svn_boolean_t use_notifier;   /* notifier is being used (depends on --quiet,
+                                   --xml, and subcommand being run) */
 
   svn_wc_conflict_resolver_func2_t conflict_func;
   void *conflict_baton;
Index: subversion/svn/main.c
===================================================================
--- subversion/svn/main.c	(revision 1381156)
+++ subversion/svn/main.c	(working copy)
@@ -2578,6 +2578,7 @@ sub_main(int argc, const char *argv[], apr_pool_t
       SVN_INT_ERR(svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2,
                                        pool));
     }
+  opt_state.use_notifier = use_notifier;
 
   /* Set up our cancellation support. */
   ctx->cancel_func = svn_cl__check_cancel;
Index: subversion/svn/merge-cmd.c
===================================================================
--- subversion/svn/merge-cmd.c	(revision 1381156)
+++ subversion/svn/merge-cmd.c	(working copy)
@@ -525,7 +525,7 @@ svn_cl__merge(apr_getopt_t *os,
     err = svn_cl__print_conflict_stats(ctx->notify_baton2, pool);
 
   if (!err
-      && opt_state->conflict_func
+      && opt_state->conflict_func && opt_state->use_notifier
       && svn_cl__notifier_check_conflicts(ctx->notify_baton2))
     {
       err = svn_cl__resolve_conflicts(
Index: subversion/svn/switch-cmd.c
===================================================================
--- subversion/svn/switch-cmd.c	(revision 1381156)
+++ subversion/svn/switch-cmd.c	(working copy)
@@ -192,7 +192,7 @@ svn_cl__switch(apr_getopt_t *os,
         return svn_error_compose_create(externals_err, err);
     }
 
-  if (opt_state->conflict_func
+  if (opt_state->conflict_func && opt_state->use_notifier
       && svn_cl__notifier_check_conflicts(nwb.wrapped_baton))
     {
       err = svn_cl__resolve_conflicts(
Index: subversion/svn/update-cmd.c
===================================================================
--- subversion/svn/update-cmd.c	(revision 1381156)
+++ subversion/svn/update-cmd.c	(working copy)
@@ -189,7 +189,7 @@ svn_cl__update(apr_getopt_t *os,
         return svn_error_compose_create(externals_err, err);
     }
 
-  if (opt_state->conflict_func
+  if (opt_state->conflict_func && opt_state->use_notifier
       && svn_cl__notifier_check_conflicts(nwb.wrapped_baton))
     {
       ctx->conflict_func2 = conflict_func2;

Re: svn commit: r1357313 - in /subversion/trunk/subversion/svn: cl.h notify.c update-cmd.c

Posted by Stefan Sperling <st...@apache.org>.
On Tue, Sep 04, 2012 at 03:01:22PM -0400, Paul Burba wrote:
> I just noticed that this causes a segfault when updating with the quiet option:
> 
> [[[
> 
> C:\SVN\src-trunk>svn up
> Updating '.':
> At revision 1380738.
> 
> C:\SVN\src-trunk>svn up -q
> This application has halted due to an unexpected error.

Thanks for digging into this and explaining the problem, Paul.

I cannot think of a better way to fix this than recording in
opt_state whether the notifier is being used. That way we
have a way of telling whether it is safe to ask the notifier
for a list of conflicted paths.

What you do think?

Index: subversion/svn/cl.h
===================================================================
--- subversion/svn/cl.h	(revision 1381156)
+++ subversion/svn/cl.h	(working copy)
@@ -238,6 +238,8 @@ typedef struct svn_cl__opt_state_t
   svn_boolean_t include_externals; /* Recurses (in)to file & dir externals */
   const char *search_pattern;     /* pattern argument for --search */
   svn_boolean_t case_insensitive_search; /* perform case-insensitive search */
+  svn_boolean_t use_notifier;   /* notifier is being used (depends on --quiet,
+                                   --xml, and subcommand being run) */
 
   svn_wc_conflict_resolver_func2_t conflict_func;
   void *conflict_baton;
Index: subversion/svn/main.c
===================================================================
--- subversion/svn/main.c	(revision 1381156)
+++ subversion/svn/main.c	(working copy)
@@ -2578,6 +2578,7 @@ sub_main(int argc, const char *argv[], apr_pool_t
       SVN_INT_ERR(svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2,
                                        pool));
     }
+  opt_state.use_notifier = use_notifier;
 
   /* Set up our cancellation support. */
   ctx->cancel_func = svn_cl__check_cancel;
Index: subversion/svn/merge-cmd.c
===================================================================
--- subversion/svn/merge-cmd.c	(revision 1381156)
+++ subversion/svn/merge-cmd.c	(working copy)
@@ -525,7 +525,7 @@ svn_cl__merge(apr_getopt_t *os,
     err = svn_cl__print_conflict_stats(ctx->notify_baton2, pool);
 
   if (!err
-      && opt_state->conflict_func
+      && opt_state->conflict_func && opt_state->use_notifier
       && svn_cl__notifier_check_conflicts(ctx->notify_baton2))
     {
       err = svn_cl__resolve_conflicts(
Index: subversion/svn/switch-cmd.c
===================================================================
--- subversion/svn/switch-cmd.c	(revision 1381156)
+++ subversion/svn/switch-cmd.c	(working copy)
@@ -192,7 +192,7 @@ svn_cl__switch(apr_getopt_t *os,
         return svn_error_compose_create(externals_err, err);
     }
 
-  if (opt_state->conflict_func
+  if (opt_state->conflict_func && opt_state->use_notifier
       && svn_cl__notifier_check_conflicts(nwb.wrapped_baton))
     {
       err = svn_cl__resolve_conflicts(
Index: subversion/svn/update-cmd.c
===================================================================
--- subversion/svn/update-cmd.c	(revision 1381156)
+++ subversion/svn/update-cmd.c	(working copy)
@@ -189,7 +189,7 @@ svn_cl__update(apr_getopt_t *os,
         return svn_error_compose_create(externals_err, err);
     }
 
-  if (opt_state->conflict_func
+  if (opt_state->conflict_func && opt_state->use_notifier
       && svn_cl__notifier_check_conflicts(nwb.wrapped_baton))
     {
       ctx->conflict_func2 = conflict_func2;

Re: svn commit: r1357313 - in /subversion/trunk/subversion/svn: cl.h notify.c update-cmd.c

Posted by Paul Burba <pt...@gmail.com>.
On Wed, Jul 4, 2012 at 11:40 AM,  <st...@apache.org> wrote:
> Author: stsp
> Date: Wed Jul  4 15:40:59 2012
> New Revision: 1357313
>
> URL: http://svn.apache.org/viewvc?rev=1357313&view=rev
> Log:
> When running the conflict resolver at the end of an 'svn update' operation,
> resolve conflicts only on paths which got new conflicts flagged during the
> update operation, rather than also resolving conflicts which were left behind
> within the update targets by some other operation.
>
> * subversion/svn/cl.h
>   (svn_cl__notifier_get_conflicted_paths): Declare.
>
> * subversion/svn/notify.c
>   (notify_baton): Add conflicted_paths hash.
>   (add_conflicted_path): New helper to add a conflicted path to above hash.
>   (notify): Add any confliced paths to above hash.
>   (svn_cl__get_notifier): Initialise the conflicted_paths hash.
>   (svn_cl__notifier_get_conflicted_paths): Return a path-wise sorted array
>    of confliced paths added during notification.
>
> * subversion/svn/update-cmd.c
>   (svn_cl__update): Pass the list of newly conflicted paths to the resolver,
>    rather than passing the entire update target list.
>
> Modified:
>     subversion/trunk/subversion/svn/cl.h
>     subversion/trunk/subversion/svn/notify.c
>     subversion/trunk/subversion/svn/update-cmd.c
>
> Modified: subversion/trunk/subversion/svn/cl.h
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl.h?rev=1357313&r1=1357312&r2=1357313&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/svn/cl.h (original)
> +++ subversion/trunk/subversion/svn/cl.h Wed Jul  4 15:40:59 2012
> @@ -607,6 +607,10 @@ svn_cl__notifier_mark_wc_to_repos_copy(v
>  svn_boolean_t
>  svn_cl__notifier_check_conflicts(void *baton);
>
> +/* Return a sorted array of conflicted paths detected during notification. */
> +apr_array_header_t *
> +svn_cl__notifier_get_conflicted_paths(void *baton, apr_pool_t *result_pool);
> +
>  /* Baton for use with svn_cl__check_externals_failed_notify_wrapper(). */
>  struct svn_cl__check_externals_failed_notify_baton
>  {
>
> Modified: subversion/trunk/subversion/svn/notify.c
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/notify.c?rev=1357313&r1=1357312&r2=1357313&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/svn/notify.c (original)
> +++ subversion/trunk/subversion/svn/notify.c Wed Jul  4 15:40:59 2012
> @@ -35,6 +35,7 @@
>  #include "svn_pools.h"
>  #include "svn_dirent_uri.h"
>  #include "svn_path.h"
> +#include "svn_sorts.h"
>  #include "cl.h"
>
>  #include "svn_private_config.h"
> @@ -57,6 +58,7 @@ struct notify_baton
>    unsigned int prop_conflicts;
>    unsigned int tree_conflicts;
>    unsigned int skipped_paths;
> +  apr_hash_t *conflicted_paths;
>
>    /* The cwd, for use in decomposing absolute paths. */
>    const char *path_prefix;
> @@ -100,6 +102,16 @@ svn_cl__print_conflict_stats(void *notif
>    return SVN_NO_ERROR;
>  }
>
> +/* Add a conflicted path to the list of conflicted paths stored
> + * in the notify baton. */
> +static void
> +add_conflicted_path(struct notify_baton *nb, const char *path)
> +{
> +  apr_hash_set(nb->conflicted_paths,
> +               apr_pstrdup(apr_hash_pool_get(nb->conflicted_paths), path),
> +               APR_HASH_KEY_STRING, "");
> +}
> +
>  /* This implements `svn_wc_notify_func2_t'.
>   * NOTE: This function can't fail, so we just ignore any print errors. */
>  static void
> @@ -213,6 +225,7 @@ notify(void *baton, const svn_wc_notify_
>        if (n->content_state == svn_wc_notify_state_conflicted)
>          {
>            nb->text_conflicts++;
> +          add_conflicted_path(nb, n->path);
>            if ((err = svn_cmdline_printf(pool, "C    %s\n", path_local)))
>              goto print_error;
>          }
> @@ -228,6 +241,7 @@ notify(void *baton, const svn_wc_notify_
>        if (n->content_state == svn_wc_notify_state_conflicted)
>          {
>            nb->text_conflicts++;
> +          add_conflicted_path(nb, n->path);
>            statchar_buf[0] = 'C';
>          }
>        else
> @@ -236,6 +250,7 @@ notify(void *baton, const svn_wc_notify_
>        if (n->prop_state == svn_wc_notify_state_conflicted)
>          {
>            nb->prop_conflicts++;
> +          add_conflicted_path(nb, n->path);
>            statchar_buf[1] = 'C';
>          }
>        else if (n->prop_state == svn_wc_notify_state_merged)
> @@ -302,6 +317,7 @@ notify(void *baton, const svn_wc_notify_
>          if (n->content_state == svn_wc_notify_state_conflicted)
>            {
>              nb->text_conflicts++;
> +            add_conflicted_path(nb, n->path);
>              statchar_buf[0] = 'C';
>            }
>          else if (n->kind == svn_node_file)
> @@ -315,6 +331,7 @@ notify(void *baton, const svn_wc_notify_
>          if (n->prop_state == svn_wc_notify_state_conflicted)
>            {
>              nb->prop_conflicts++;
> +            add_conflicted_path(nb, n->path);
>              statchar_buf[1] = 'C';
>            }
>          else if (n->prop_state == svn_wc_notify_state_changed)
> @@ -508,6 +525,7 @@ notify(void *baton, const svn_wc_notify_
>          if (n->content_state == svn_wc_notify_state_conflicted)
>            {
>              nb->text_conflicts++;
> +            add_conflicted_path(nb, n->path);
>              statchar_buf[0] = 'C';
>            }
>          else if (n->kind == svn_node_file)
> @@ -521,6 +539,7 @@ notify(void *baton, const svn_wc_notify_
>          if (n->prop_state == svn_wc_notify_state_conflicted)
>            {
>              nb->prop_conflicts++;
> +            add_conflicted_path(nb, n->path);
>              statchar_buf[1] = 'C';
>            }
>          else if (n->prop_state == svn_wc_notify_state_merged)
> @@ -898,6 +917,7 @@ notify(void *baton, const svn_wc_notify_
>
>      case svn_wc_notify_tree_conflict:
>        nb->tree_conflicts++;
> +      add_conflicted_path(nb, n->path);
>        if ((err = svn_cmdline_printf(pool, "   C %s\n", path_local)))
>          goto print_error;
>        break;
> @@ -1038,6 +1058,7 @@ svn_cl__get_notifier(svn_wc_notify_func2
>    nb->prop_conflicts = 0;
>    nb->tree_conflicts = 0;
>    nb->skipped_paths = 0;
> +  nb->conflicted_paths = apr_hash_make(pool);
>    SVN_ERR(svn_dirent_get_absolute(&nb->path_prefix, "", pool));
>
>    *notify_func_p = notify;
> @@ -1093,3 +1114,13 @@ svn_cl__notifier_check_conflicts(void *b
>
>    return (nb->text_conflicts || nb->prop_conflicts || nb->tree_conflicts);
>  }
> +
> +apr_array_header_t *
> +svn_cl__notifier_get_conflicted_paths(void *baton, apr_pool_t *result_pool)
> +{
> +  struct notify_baton *nb = baton;
> +
> +  return svn_sort__hash(nb->conflicted_paths,
> +                        svn_sort_compare_items_as_paths,
> +                        result_pool);
> +}

Hi Stefan,

I just noticed that this causes a segfault when updating with the quiet option:

[[[

C:\SVN\src-trunk>svn up
Updating '.':
At revision 1380738.

C:\SVN\src-trunk>svn up -q
This application has halted due to an unexpected error.
A crash report and minidump file were saved to disk, you can find them here:
C:\Users\pburba\AppData\Local\Temp\svn-crash-log20120904125027.log
C:\Users\pburba\AppData\Local\Temp\svn-crash-log20120904125027.dmp
Please send the log file to users@subversion.apache.org to help us analyze
and solve this problem.

NOTE: The crash report and minidump files can contain some sensitive information
(filenames, partial file content, usernames and passwords etc.)

C:\SVN\src-trunk>type
C:\Users\pburba\AppData\Local\Temp\svn-crash-log20120904125027.log

Process info:
Cmd line: svn  up -q
Working Dir: C:\SVN\src-trunk
Version:  1.8.0-dev (under development), compiled Aug 13 2012, 09:00:28
Platform: Windows OS version 6.1 build 7601 Service Pack 1

Exception: ACCESS_VIOLATION

Registers:
eax=00000000 ebx=7efde000 ecx=00eb5840 edx=00000000 esi=0098f6f8 edi=0098f7ac
eip=6eedbef6 esp=0098f6ec ebp=0098f6ec efl=00010206
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b

Stacktrace:
#1  0x6eedbef6 in apr_hash_pool_get(thehash=(apr_hash_t *) 0x00000000)
at c:\svn\httpd-2.2.22\srclib\apr\tables\apr_hash.c:529
        thehash = (apr_hash_t *) 0x00000000
#2  0x002e989d in
svn_cl__notifier_get_conflicted_paths(baton=0x00eb5840,
result_pool=(apr_pool_t *) 0x00eb5148) at
c:\svn\src-trunk\subversion\svn\notify.c:113
4
        baton = 0x00eb5840
        result_pool = (apr_pool_t *) 0x00eb5148
        nb = (notify_baton *) 0x00eb5840
        result_array = (apr_array_header_t *) 0xcccccccc
        sorted_array = (apr_array_header_t *) 0xcccccccc
        i = -858993460
#3  0x002f2b2a in svn_cl__update(os=(apr_getopt_t *) 0x00eb52f8,
baton=0x0098f990, scratch_pool=(apr_pool_t *) 0x00eb5148) at
c:\svn\src-trunk\subversion\svn\up
date-cmd.c:200
        os = (apr_getopt_t *) 0x00eb52f8
        baton = 0x0098f990
        scratch_pool = (apr_pool_t *) 0x00eb5148
        targets = (apr_array_header_t *) 0x00f0f898
        depth = -2
        conflict_func2 = 0x00000000
        err = (svn_error_t *) 0x00000000
        externals_err = (svn_error_t *) 0x00000000
        nwb = (svn_cl__check_externals_failed_notify_baton) 0x0098f780
        result_revs = (apr_array_header_t *) 0x00f0f8b8
        ctx = (svn_client_ctx_t *) 0x00eb5840
        depth_is_sticky = 0
        conflict_baton2 = 0x00000000
        opt_state = (svn_cl__opt_state_t *) 0x0098f9c0
#4  0x002e3f23 in sub_main(argc=3, argv=0x02941fc0, pool=(apr_pool_t
*) 0x00eb5148) at c:\svn\src-trunk\subversion\svn\main.c:2680
        argc = 3
        argv = 0x02941fc0
        pool = (apr_pool_t *) 0x00eb5148
        os = (apr_getopt_t *) 0x00eb52f8
        err = (svn_error_t *) 0x00000000
        dash_m_arg = 0x00000000 "(null)"
        cfg_config = (svn_config_t *) 0x00eb62f0
        descend = 1
        use_notifier = 0
        ctx = (svn_client_ctx_t *) 0x00eb5840
        subcommand = (svn_opt_subcommand_desc2_t *) 0x00654030
        ab = (svn_auth_baton_t *) 0x00f0f4b0
        opt_id = 113
        i = 1
        dash_F_arg = 0x00000000 "(null)"
        changelists = (apr_hash_t *) 0x00eb5268
        received_opts = (apr_array_header_t *) 0x00eb5188
        command_baton = (svn_cl__cmd_baton_t) 0x0098f990
        interactive_conflicts = 1
        opt_state = (svn_cl__opt_state_t) 0x0098f9c0
#5  0x002e18ae in main(argc=3, argv=0x02941fc0) at
c:\svn\src-trunk\subversion\svn\main.c:2735
        argc = 3
        argv = 0x02941fc0
        pool = (apr_pool_t *) 0x00eb5148
        exit_code = -858993460
#6  0x004b01c8 in __tmainCRTStartup() at
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c:586
        lock_free = 0x00000000
        fiberid = 0x00990000
        nested = 0
#7  0x004b000f in mainCRTStartup() at
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c:403
#8  0x76b7339a in BaseThreadInitThunk()
#9  0x778e9ef2 in RtlInitializeExceptionChain()
#10  0x778e9ec5 in RtlInitializeExceptionChain()


Loaded modules:
0x00140000  C:\SVN\src-trunk\Debug\subversion\svn\svn.exe (1.8.0.0,
6832128 bytes)
0x778b0000  C:\Windows\SysWOW64\ntdll.dll (6.1.7601.17725, 1572864 bytes)
0x76b60000  C:\Windows\SysWOW64\kernel32.dll (6.1.7601.17651, 1114112 bytes)
0x76610000  C:\Windows\SysWOW64\KERNELBASE.dll (6.1.7601.17651, 286720 bytes)
0x6eec0000  C:\SVN\httpd-2.2.22\srclib\apr\Debug\libapr-1.dll
(1.4.6.0, 208896 bytes)
0x76160000  C:\Windows\SysWOW64\ws2_32.dll (6.1.7601.17514, 217088 bytes)
0x762e0000  C:\Windows\SysWOW64\msvcrt.dll (7.0.7601.17744, 704512 bytes)
0x752c0000  C:\Windows\SysWOW64\rpcrt4.dll (6.1.7601.17514, 983040 bytes)
0x74f90000  C:\Windows\SysWOW64\sspicli.dll (6.1.7601.17856, 393216 bytes)
0x74f80000  C:\Windows\SysWOW64\CRYPTBASE.dll (6.1.7600.16385, 49152 bytes)
0x76e00000  C:\Windows\SysWOW64\sechost.dll (6.1.7600.16385, 102400 bytes)
0x761d0000  C:\Windows\SysWOW64\nsi.dll (6.1.7600.16385, 24576 bytes)
0x72800000  C:\Windows\System32\mswsock.dll (6.1.7601.17514, 245760 bytes)
0x76c70000  C:\Windows\SysWOW64\user32.dll (6.1.7601.17514, 1048576 bytes)
0x76d70000  C:\Windows\SysWOW64\gdi32.dll (6.1.7601.17514, 589824 bytes)
0x75160000  C:\Windows\SysWOW64\lpk.dll (6.1.7600.16385, 40960 bytes)
0x750c0000  C:\Windows\SysWOW64\usp10.dll (1.626.7601.17514, 643072 bytes)
0x761e0000  C:\Windows\SysWOW64\advapi32.dll (6.1.7601.17514, 655360 bytes)
0x753b0000  C:\Windows\SysWOW64\shell32.dll (6.1.7601.17859, 12886016 bytes)
0x76520000  C:\Windows\SysWOW64\shlwapi.dll (6.1.7601.17514, 356352 bytes)
0x71eb0000  C:\Windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_2a4f639a55563668\msvcr90d.dll
(9.0.30729.6161, 1191936 bytes)
0x6ee60000  C:\SVN\httpd-2.2.22\srclib\apr-util\Debug\libaprutil-1.dll
(1.4.1.0, 290816 bytes)
0x6ee50000  C:\SVN\httpd-2.2.22\srclib\apr-iconv\Debug\libapriconv-1.dll
(1.2.1.0, 45056 bytes)
0x73810000  C:\Windows\System32\shfolder.dll (6.1.7600.16385, 20480 bytes)
0x76000000  C:\Windows\SysWOW64\ole32.dll (6.1.7601.17514, 1425408 bytes)
0x75170000  C:\Windows\SysWOW64\crypt32.dll (6.1.7601.17827, 1171456 bytes)
0x766f0000  C:\Windows\SysWOW64\msasn1.dll (6.1.7601.17514, 49152 bytes)
0x74d50000  C:\Windows\System32\version.dll (6.1.7600.16385, 36864 bytes)
0x77880000  C:\Windows\SysWOW64\psapi.dll (6.1.7600.16385, 20480 bytes)
0x10000000  C:\SVN\openssl\out32dll\libeay32.dll (0.9.8.17, 1044480 bytes)
0x74d40000  C:\Windows\System32\wsock32.dll (6.1.7600.16385, 28672 bytes)
0x72520000  C:\Windows\winsxs\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_50934f2ebcb7eb57\msvcr90.dll
(9.0.30729.6161, 667648 bytes)
0x007d0000  C:\SVN\openssl\out32dll\ssleay32.dll (0.9.8.17, 221184 bytes)
0x73b10000  C:\Windows\System32\secur32.dll (6.1.7601.17856, 32768 bytes)
0x00cb0000  C:\SVN\bdb\bin\libdb48d.dll (4.0.8.30, 1904640 bytes)
0x71dd0000  C:\Windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_2a4f639a55563668\msvcp90d.dll
(9.0.30729.6161, 880640 bytes)
0x764c0000  C:\Windows\System32\imm32.dll (6.1.7601.17514, 393216 bytes)
0x74ff0000  C:\Windows\SysWOW64\msctf.dll (6.1.7600.16385, 835584 bytes)
0x74a60000  C:\Windows\System32\profapi.dll (6.1.7600.16385, 45056 bytes)
0x6af90000  C:\Windows\System32\nlaapi.dll (6.1.7601.17514, 65536 bytes)
0x6af80000  C:\Windows\System32\NapiNSP.dll (6.1.7600.16385, 65536 bytes)
0x6aed0000  C:\Windows\System32\pnrpnsp.dll (6.1.7600.16385, 73728 bytes)
0x6af70000  C:\Windows\System32\wshbth.dll (6.1.7601.17514, 53248 bytes)
0x73da0000  C:\Windows\System32\dnsapi.dll (6.1.7601.17570, 278528 bytes)
0x6aec0000  C:\Windows\System32\winrnr.dll (6.1.7600.16385, 32768 bytes)
0x73b70000  C:\Program Files (x86)\Bonjour\mdnsNSP.dll (3.0.0.10, 135168 bytes)
0x72410000  C:\Windows\System32\IPHLPAPI.DLL (6.1.7601.17514, 114688 bytes)
0x72400000  C:\Windows\System32\winnsi.dll (6.1.7600.16385, 28672 bytes)
0x73b20000  C:\Windows\System32\FWPUCLNT.DLL (6.1.7601.17514, 229376 bytes)
0x73b60000  C:\Windows\System32\rasadhlp.dll (6.1.7600.16385, 24576 bytes)
0x72440000  C:\Windows\System32\WSHTCPIP.DLL (6.1.7600.16385, 20480 bytes)
0x74ab0000  C:\Windows\System32\cryptsp.dll (6.1.7600.16385, 90112 bytes)
0x74a70000  C:\Windows\System32\rsaenh.dll (6.1.7600.16385, 241664 bytes)
0x72610000  C:\Windows\System32\userenv.dll (6.1.7601.17514, 94208 bytes)
0x725f0000  C:\Windows\System32\gpapi.dll (6.1.7600.16385, 90112 bytes)
0x72690000  C:\Windows\System32\ncrypt.dll (6.1.7601.17856, 229376 bytes)
0x72670000  C:\Windows\System32\bcrypt.dll (6.1.7600.16385, 94208 bytes)
0x72630000  C:\Windows\SysWOW64\bcryptprimitives.dll (6.1.7600.16385,
249856 bytes)
0x725d0000  C:\Windows\System32\cryptnet.dll (6.1.7601.17827, 114688 bytes)
0x76950000  C:\Windows\SysWOW64\Wldap32.dll (6.1.7601.17514, 282624 bytes)
0x72510000  C:\Windows\System32\SensApi.dll (6.1.7600.16385, 24576 bytes)
0x74af0000  C:\Windows\System32\dbghelp.dll (6.1.7601.17514, 962560 bytes)
0x74c70000  C:\Windows\System32\powrprof.dll (6.1.7600.16385, 151552 bytes)
0x76e50000  C:\Windows\SysWOW64\setupapi.dll (6.1.7601.17514, 1691648 bytes)
0x75290000  C:\Windows\SysWOW64\cfgmgr32.dll (6.1.7601.17621, 159744 bytes)
0x76700000  C:\Windows\SysWOW64\oleaut32.dll (6.1.7601.17676, 585728 bytes)
0x76790000  C:\Windows\SysWOW64\devobj.dll (6.1.7601.17621, 73728 bytes)
]]]

What's happening is this:

In main.c:sub_main if local variable use_notifier is FALSE, then
svn_cl__get_notifier is never called and the svn_wc_notify_func2_t and
the its corresponding struct notify_baton are never
allocated/initialized.  The --quiet option is one way in which
use_notifier gets set to FALSE.  However it gets set to FALSE, later,
in update-cmd.c:svn_cl__update, we pass the unallocated/uninitialized
baton to svn_cl__notifier_check_conflicts:

  if (opt_state->conflict_func
      && svn_cl__notifier_check_conflicts(nwb.wrapped_baton))
    {
      ctx->conflict_func2 = conflict_func2;
      ctx->conflict_baton2 = conflict_baton2;
      err = svn_cl__resolve_conflicts(
              svn_cl__notifier_get_conflicted_paths(nwb.wrapped_baton,
                                                    scratch_pool),
              depth, opt_state, ctx, scratch_pool);
      if (err)
        return svn_error_compose_create(externals_err, err);
    }

Which can easily return true as it references baton members pointing
who knows where:

svn_boolean_t
svn_cl__notifier_check_conflicts(void *baton)
{
  struct notify_baton *nb = baton;

  return (nb->text_conflicts || nb->prop_conflicts || nb->tree_conflicts);
}

If svn_cl__notifier_check_conflicts does return true, then we segfault
when svn_cl__notifier_get_conflicted_paths tries to call
apr_hash_pool_get on an uninitialized baton member:

apr_array_header_t *
svn_cl__notifier_get_conflicted_paths(void *baton, apr_pool_t *result_pool)
{
  struct notify_baton *nb = baton;
  apr_array_header_t *sorted_array;
  apr_array_header_t *result_array;
  int i;

  sorted_array = svn_sort__hash(nb->conflicted_paths,
                                svn_sort_compare_items_as_paths,
                                apr_hash_pool_get(nb->conflicted_paths));
                                                  ^^^^^
                                                  Uh-oh
-- 
Paul T. Burba
CollabNet, Inc. -- www.collab.net -- Enterprise Cloud Development
Skype: ptburba

Re: svn commit: r1357313 - in /subversion/trunk/subversion/svn: cl.h notify.c update-cmd.c

Posted by Paul Burba <pt...@gmail.com>.
On Wed, Jul 4, 2012 at 11:40 AM,  <st...@apache.org> wrote:
> Author: stsp
> Date: Wed Jul  4 15:40:59 2012
> New Revision: 1357313
>
> URL: http://svn.apache.org/viewvc?rev=1357313&view=rev
> Log:
> When running the conflict resolver at the end of an 'svn update' operation,
> resolve conflicts only on paths which got new conflicts flagged during the
> update operation, rather than also resolving conflicts which were left behind
> within the update targets by some other operation.
>
> * subversion/svn/cl.h
>   (svn_cl__notifier_get_conflicted_paths): Declare.
>
> * subversion/svn/notify.c
>   (notify_baton): Add conflicted_paths hash.
>   (add_conflicted_path): New helper to add a conflicted path to above hash.
>   (notify): Add any confliced paths to above hash.
>   (svn_cl__get_notifier): Initialise the conflicted_paths hash.
>   (svn_cl__notifier_get_conflicted_paths): Return a path-wise sorted array
>    of confliced paths added during notification.
>
> * subversion/svn/update-cmd.c
>   (svn_cl__update): Pass the list of newly conflicted paths to the resolver,
>    rather than passing the entire update target list.
>
> Modified:
>     subversion/trunk/subversion/svn/cl.h
>     subversion/trunk/subversion/svn/notify.c
>     subversion/trunk/subversion/svn/update-cmd.c
>
> Modified: subversion/trunk/subversion/svn/cl.h
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl.h?rev=1357313&r1=1357312&r2=1357313&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/svn/cl.h (original)
> +++ subversion/trunk/subversion/svn/cl.h Wed Jul  4 15:40:59 2012
> @@ -607,6 +607,10 @@ svn_cl__notifier_mark_wc_to_repos_copy(v
>  svn_boolean_t
>  svn_cl__notifier_check_conflicts(void *baton);
>
> +/* Return a sorted array of conflicted paths detected during notification. */
> +apr_array_header_t *
> +svn_cl__notifier_get_conflicted_paths(void *baton, apr_pool_t *result_pool);
> +
>  /* Baton for use with svn_cl__check_externals_failed_notify_wrapper(). */
>  struct svn_cl__check_externals_failed_notify_baton
>  {
>
> Modified: subversion/trunk/subversion/svn/notify.c
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/notify.c?rev=1357313&r1=1357312&r2=1357313&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/svn/notify.c (original)
> +++ subversion/trunk/subversion/svn/notify.c Wed Jul  4 15:40:59 2012
> @@ -35,6 +35,7 @@
>  #include "svn_pools.h"
>  #include "svn_dirent_uri.h"
>  #include "svn_path.h"
> +#include "svn_sorts.h"
>  #include "cl.h"
>
>  #include "svn_private_config.h"
> @@ -57,6 +58,7 @@ struct notify_baton
>    unsigned int prop_conflicts;
>    unsigned int tree_conflicts;
>    unsigned int skipped_paths;
> +  apr_hash_t *conflicted_paths;
>
>    /* The cwd, for use in decomposing absolute paths. */
>    const char *path_prefix;
> @@ -100,6 +102,16 @@ svn_cl__print_conflict_stats(void *notif
>    return SVN_NO_ERROR;
>  }
>
> +/* Add a conflicted path to the list of conflicted paths stored
> + * in the notify baton. */
> +static void
> +add_conflicted_path(struct notify_baton *nb, const char *path)
> +{
> +  apr_hash_set(nb->conflicted_paths,
> +               apr_pstrdup(apr_hash_pool_get(nb->conflicted_paths), path),
> +               APR_HASH_KEY_STRING, "");
> +}
> +
>  /* This implements `svn_wc_notify_func2_t'.
>   * NOTE: This function can't fail, so we just ignore any print errors. */
>  static void
> @@ -213,6 +225,7 @@ notify(void *baton, const svn_wc_notify_
>        if (n->content_state == svn_wc_notify_state_conflicted)
>          {
>            nb->text_conflicts++;
> +          add_conflicted_path(nb, n->path);
>            if ((err = svn_cmdline_printf(pool, "C    %s\n", path_local)))
>              goto print_error;
>          }
> @@ -228,6 +241,7 @@ notify(void *baton, const svn_wc_notify_
>        if (n->content_state == svn_wc_notify_state_conflicted)
>          {
>            nb->text_conflicts++;
> +          add_conflicted_path(nb, n->path);
>            statchar_buf[0] = 'C';
>          }
>        else
> @@ -236,6 +250,7 @@ notify(void *baton, const svn_wc_notify_
>        if (n->prop_state == svn_wc_notify_state_conflicted)
>          {
>            nb->prop_conflicts++;
> +          add_conflicted_path(nb, n->path);
>            statchar_buf[1] = 'C';
>          }
>        else if (n->prop_state == svn_wc_notify_state_merged)
> @@ -302,6 +317,7 @@ notify(void *baton, const svn_wc_notify_
>          if (n->content_state == svn_wc_notify_state_conflicted)
>            {
>              nb->text_conflicts++;
> +            add_conflicted_path(nb, n->path);
>              statchar_buf[0] = 'C';
>            }
>          else if (n->kind == svn_node_file)
> @@ -315,6 +331,7 @@ notify(void *baton, const svn_wc_notify_
>          if (n->prop_state == svn_wc_notify_state_conflicted)
>            {
>              nb->prop_conflicts++;
> +            add_conflicted_path(nb, n->path);
>              statchar_buf[1] = 'C';
>            }
>          else if (n->prop_state == svn_wc_notify_state_changed)
> @@ -508,6 +525,7 @@ notify(void *baton, const svn_wc_notify_
>          if (n->content_state == svn_wc_notify_state_conflicted)
>            {
>              nb->text_conflicts++;
> +            add_conflicted_path(nb, n->path);
>              statchar_buf[0] = 'C';
>            }
>          else if (n->kind == svn_node_file)
> @@ -521,6 +539,7 @@ notify(void *baton, const svn_wc_notify_
>          if (n->prop_state == svn_wc_notify_state_conflicted)
>            {
>              nb->prop_conflicts++;
> +            add_conflicted_path(nb, n->path);
>              statchar_buf[1] = 'C';
>            }
>          else if (n->prop_state == svn_wc_notify_state_merged)
> @@ -898,6 +917,7 @@ notify(void *baton, const svn_wc_notify_
>
>      case svn_wc_notify_tree_conflict:
>        nb->tree_conflicts++;
> +      add_conflicted_path(nb, n->path);
>        if ((err = svn_cmdline_printf(pool, "   C %s\n", path_local)))
>          goto print_error;
>        break;
> @@ -1038,6 +1058,7 @@ svn_cl__get_notifier(svn_wc_notify_func2
>    nb->prop_conflicts = 0;
>    nb->tree_conflicts = 0;
>    nb->skipped_paths = 0;
> +  nb->conflicted_paths = apr_hash_make(pool);
>    SVN_ERR(svn_dirent_get_absolute(&nb->path_prefix, "", pool));
>
>    *notify_func_p = notify;
> @@ -1093,3 +1114,13 @@ svn_cl__notifier_check_conflicts(void *b
>
>    return (nb->text_conflicts || nb->prop_conflicts || nb->tree_conflicts);
>  }
> +
> +apr_array_header_t *
> +svn_cl__notifier_get_conflicted_paths(void *baton, apr_pool_t *result_pool)
> +{
> +  struct notify_baton *nb = baton;
> +
> +  return svn_sort__hash(nb->conflicted_paths,
> +                        svn_sort_compare_items_as_paths,
> +                        result_pool);
> +}

Hi Stefan,

I just noticed that this causes a segfault when updating with the quiet option:

[[[

C:\SVN\src-trunk>svn up
Updating '.':
At revision 1380738.

C:\SVN\src-trunk>svn up -q
This application has halted due to an unexpected error.
A crash report and minidump file were saved to disk, you can find them here:
C:\Users\pburba\AppData\Local\Temp\svn-crash-log20120904125027.log
C:\Users\pburba\AppData\Local\Temp\svn-crash-log20120904125027.dmp
Please send the log file to users@subversion.apache.org to help us analyze
and solve this problem.

NOTE: The crash report and minidump files can contain some sensitive information
(filenames, partial file content, usernames and passwords etc.)

C:\SVN\src-trunk>type
C:\Users\pburba\AppData\Local\Temp\svn-crash-log20120904125027.log

Process info:
Cmd line: svn  up -q
Working Dir: C:\SVN\src-trunk
Version:  1.8.0-dev (under development), compiled Aug 13 2012, 09:00:28
Platform: Windows OS version 6.1 build 7601 Service Pack 1

Exception: ACCESS_VIOLATION

Registers:
eax=00000000 ebx=7efde000 ecx=00eb5840 edx=00000000 esi=0098f6f8 edi=0098f7ac
eip=6eedbef6 esp=0098f6ec ebp=0098f6ec efl=00010206
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b

Stacktrace:
#1  0x6eedbef6 in apr_hash_pool_get(thehash=(apr_hash_t *) 0x00000000)
at c:\svn\httpd-2.2.22\srclib\apr\tables\apr_hash.c:529
        thehash = (apr_hash_t *) 0x00000000
#2  0x002e989d in
svn_cl__notifier_get_conflicted_paths(baton=0x00eb5840,
result_pool=(apr_pool_t *) 0x00eb5148) at
c:\svn\src-trunk\subversion\svn\notify.c:113
4
        baton = 0x00eb5840
        result_pool = (apr_pool_t *) 0x00eb5148
        nb = (notify_baton *) 0x00eb5840
        result_array = (apr_array_header_t *) 0xcccccccc
        sorted_array = (apr_array_header_t *) 0xcccccccc
        i = -858993460
#3  0x002f2b2a in svn_cl__update(os=(apr_getopt_t *) 0x00eb52f8,
baton=0x0098f990, scratch_pool=(apr_pool_t *) 0x00eb5148) at
c:\svn\src-trunk\subversion\svn\up
date-cmd.c:200
        os = (apr_getopt_t *) 0x00eb52f8
        baton = 0x0098f990
        scratch_pool = (apr_pool_t *) 0x00eb5148
        targets = (apr_array_header_t *) 0x00f0f898
        depth = -2
        conflict_func2 = 0x00000000
        err = (svn_error_t *) 0x00000000
        externals_err = (svn_error_t *) 0x00000000
        nwb = (svn_cl__check_externals_failed_notify_baton) 0x0098f780
        result_revs = (apr_array_header_t *) 0x00f0f8b8
        ctx = (svn_client_ctx_t *) 0x00eb5840
        depth_is_sticky = 0
        conflict_baton2 = 0x00000000
        opt_state = (svn_cl__opt_state_t *) 0x0098f9c0
#4  0x002e3f23 in sub_main(argc=3, argv=0x02941fc0, pool=(apr_pool_t
*) 0x00eb5148) at c:\svn\src-trunk\subversion\svn\main.c:2680
        argc = 3
        argv = 0x02941fc0
        pool = (apr_pool_t *) 0x00eb5148
        os = (apr_getopt_t *) 0x00eb52f8
        err = (svn_error_t *) 0x00000000
        dash_m_arg = 0x00000000 "(null)"
        cfg_config = (svn_config_t *) 0x00eb62f0
        descend = 1
        use_notifier = 0
        ctx = (svn_client_ctx_t *) 0x00eb5840
        subcommand = (svn_opt_subcommand_desc2_t *) 0x00654030
        ab = (svn_auth_baton_t *) 0x00f0f4b0
        opt_id = 113
        i = 1
        dash_F_arg = 0x00000000 "(null)"
        changelists = (apr_hash_t *) 0x00eb5268
        received_opts = (apr_array_header_t *) 0x00eb5188
        command_baton = (svn_cl__cmd_baton_t) 0x0098f990
        interactive_conflicts = 1
        opt_state = (svn_cl__opt_state_t) 0x0098f9c0
#5  0x002e18ae in main(argc=3, argv=0x02941fc0) at
c:\svn\src-trunk\subversion\svn\main.c:2735
        argc = 3
        argv = 0x02941fc0
        pool = (apr_pool_t *) 0x00eb5148
        exit_code = -858993460
#6  0x004b01c8 in __tmainCRTStartup() at
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c:586
        lock_free = 0x00000000
        fiberid = 0x00990000
        nested = 0
#7  0x004b000f in mainCRTStartup() at
f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c:403
#8  0x76b7339a in BaseThreadInitThunk()
#9  0x778e9ef2 in RtlInitializeExceptionChain()
#10  0x778e9ec5 in RtlInitializeExceptionChain()


Loaded modules:
0x00140000  C:\SVN\src-trunk\Debug\subversion\svn\svn.exe (1.8.0.0,
6832128 bytes)
0x778b0000  C:\Windows\SysWOW64\ntdll.dll (6.1.7601.17725, 1572864 bytes)
0x76b60000  C:\Windows\SysWOW64\kernel32.dll (6.1.7601.17651, 1114112 bytes)
0x76610000  C:\Windows\SysWOW64\KERNELBASE.dll (6.1.7601.17651, 286720 bytes)
0x6eec0000  C:\SVN\httpd-2.2.22\srclib\apr\Debug\libapr-1.dll
(1.4.6.0, 208896 bytes)
0x76160000  C:\Windows\SysWOW64\ws2_32.dll (6.1.7601.17514, 217088 bytes)
0x762e0000  C:\Windows\SysWOW64\msvcrt.dll (7.0.7601.17744, 704512 bytes)
0x752c0000  C:\Windows\SysWOW64\rpcrt4.dll (6.1.7601.17514, 983040 bytes)
0x74f90000  C:\Windows\SysWOW64\sspicli.dll (6.1.7601.17856, 393216 bytes)
0x74f80000  C:\Windows\SysWOW64\CRYPTBASE.dll (6.1.7600.16385, 49152 bytes)
0x76e00000  C:\Windows\SysWOW64\sechost.dll (6.1.7600.16385, 102400 bytes)
0x761d0000  C:\Windows\SysWOW64\nsi.dll (6.1.7600.16385, 24576 bytes)
0x72800000  C:\Windows\System32\mswsock.dll (6.1.7601.17514, 245760 bytes)
0x76c70000  C:\Windows\SysWOW64\user32.dll (6.1.7601.17514, 1048576 bytes)
0x76d70000  C:\Windows\SysWOW64\gdi32.dll (6.1.7601.17514, 589824 bytes)
0x75160000  C:\Windows\SysWOW64\lpk.dll (6.1.7600.16385, 40960 bytes)
0x750c0000  C:\Windows\SysWOW64\usp10.dll (1.626.7601.17514, 643072 bytes)
0x761e0000  C:\Windows\SysWOW64\advapi32.dll (6.1.7601.17514, 655360 bytes)
0x753b0000  C:\Windows\SysWOW64\shell32.dll (6.1.7601.17859, 12886016 bytes)
0x76520000  C:\Windows\SysWOW64\shlwapi.dll (6.1.7601.17514, 356352 bytes)
0x71eb0000  C:\Windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_2a4f639a55563668\msvcr90d.dll
(9.0.30729.6161, 1191936 bytes)
0x6ee60000  C:\SVN\httpd-2.2.22\srclib\apr-util\Debug\libaprutil-1.dll
(1.4.1.0, 290816 bytes)
0x6ee50000  C:\SVN\httpd-2.2.22\srclib\apr-iconv\Debug\libapriconv-1.dll
(1.2.1.0, 45056 bytes)
0x73810000  C:\Windows\System32\shfolder.dll (6.1.7600.16385, 20480 bytes)
0x76000000  C:\Windows\SysWOW64\ole32.dll (6.1.7601.17514, 1425408 bytes)
0x75170000  C:\Windows\SysWOW64\crypt32.dll (6.1.7601.17827, 1171456 bytes)
0x766f0000  C:\Windows\SysWOW64\msasn1.dll (6.1.7601.17514, 49152 bytes)
0x74d50000  C:\Windows\System32\version.dll (6.1.7600.16385, 36864 bytes)
0x77880000  C:\Windows\SysWOW64\psapi.dll (6.1.7600.16385, 20480 bytes)
0x10000000  C:\SVN\openssl\out32dll\libeay32.dll (0.9.8.17, 1044480 bytes)
0x74d40000  C:\Windows\System32\wsock32.dll (6.1.7600.16385, 28672 bytes)
0x72520000  C:\Windows\winsxs\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_50934f2ebcb7eb57\msvcr90.dll
(9.0.30729.6161, 667648 bytes)
0x007d0000  C:\SVN\openssl\out32dll\ssleay32.dll (0.9.8.17, 221184 bytes)
0x73b10000  C:\Windows\System32\secur32.dll (6.1.7601.17856, 32768 bytes)
0x00cb0000  C:\SVN\bdb\bin\libdb48d.dll (4.0.8.30, 1904640 bytes)
0x71dd0000  C:\Windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_2a4f639a55563668\msvcp90d.dll
(9.0.30729.6161, 880640 bytes)
0x764c0000  C:\Windows\System32\imm32.dll (6.1.7601.17514, 393216 bytes)
0x74ff0000  C:\Windows\SysWOW64\msctf.dll (6.1.7600.16385, 835584 bytes)
0x74a60000  C:\Windows\System32\profapi.dll (6.1.7600.16385, 45056 bytes)
0x6af90000  C:\Windows\System32\nlaapi.dll (6.1.7601.17514, 65536 bytes)
0x6af80000  C:\Windows\System32\NapiNSP.dll (6.1.7600.16385, 65536 bytes)
0x6aed0000  C:\Windows\System32\pnrpnsp.dll (6.1.7600.16385, 73728 bytes)
0x6af70000  C:\Windows\System32\wshbth.dll (6.1.7601.17514, 53248 bytes)
0x73da0000  C:\Windows\System32\dnsapi.dll (6.1.7601.17570, 278528 bytes)
0x6aec0000  C:\Windows\System32\winrnr.dll (6.1.7600.16385, 32768 bytes)
0x73b70000  C:\Program Files (x86)\Bonjour\mdnsNSP.dll (3.0.0.10, 135168 bytes)
0x72410000  C:\Windows\System32\IPHLPAPI.DLL (6.1.7601.17514, 114688 bytes)
0x72400000  C:\Windows\System32\winnsi.dll (6.1.7600.16385, 28672 bytes)
0x73b20000  C:\Windows\System32\FWPUCLNT.DLL (6.1.7601.17514, 229376 bytes)
0x73b60000  C:\Windows\System32\rasadhlp.dll (6.1.7600.16385, 24576 bytes)
0x72440000  C:\Windows\System32\WSHTCPIP.DLL (6.1.7600.16385, 20480 bytes)
0x74ab0000  C:\Windows\System32\cryptsp.dll (6.1.7600.16385, 90112 bytes)
0x74a70000  C:\Windows\System32\rsaenh.dll (6.1.7600.16385, 241664 bytes)
0x72610000  C:\Windows\System32\userenv.dll (6.1.7601.17514, 94208 bytes)
0x725f0000  C:\Windows\System32\gpapi.dll (6.1.7600.16385, 90112 bytes)
0x72690000  C:\Windows\System32\ncrypt.dll (6.1.7601.17856, 229376 bytes)
0x72670000  C:\Windows\System32\bcrypt.dll (6.1.7600.16385, 94208 bytes)
0x72630000  C:\Windows\SysWOW64\bcryptprimitives.dll (6.1.7600.16385,
249856 bytes)
0x725d0000  C:\Windows\System32\cryptnet.dll (6.1.7601.17827, 114688 bytes)
0x76950000  C:\Windows\SysWOW64\Wldap32.dll (6.1.7601.17514, 282624 bytes)
0x72510000  C:\Windows\System32\SensApi.dll (6.1.7600.16385, 24576 bytes)
0x74af0000  C:\Windows\System32\dbghelp.dll (6.1.7601.17514, 962560 bytes)
0x74c70000  C:\Windows\System32\powrprof.dll (6.1.7600.16385, 151552 bytes)
0x76e50000  C:\Windows\SysWOW64\setupapi.dll (6.1.7601.17514, 1691648 bytes)
0x75290000  C:\Windows\SysWOW64\cfgmgr32.dll (6.1.7601.17621, 159744 bytes)
0x76700000  C:\Windows\SysWOW64\oleaut32.dll (6.1.7601.17676, 585728 bytes)
0x76790000  C:\Windows\SysWOW64\devobj.dll (6.1.7601.17621, 73728 bytes)
]]]

What's happening is this:

In main.c:sub_main if local variable use_notifier is FALSE, then
svn_cl__get_notifier is never called and the svn_wc_notify_func2_t and
the its corresponding struct notify_baton are never
allocated/initialized.  The --quiet option is one way in which
use_notifier gets set to FALSE.  However it gets set to FALSE, later,
in update-cmd.c:svn_cl__update, we pass the unallocated/uninitialized
baton to svn_cl__notifier_check_conflicts:

  if (opt_state->conflict_func
      && svn_cl__notifier_check_conflicts(nwb.wrapped_baton))
    {
      ctx->conflict_func2 = conflict_func2;
      ctx->conflict_baton2 = conflict_baton2;
      err = svn_cl__resolve_conflicts(
              svn_cl__notifier_get_conflicted_paths(nwb.wrapped_baton,
                                                    scratch_pool),
              depth, opt_state, ctx, scratch_pool);
      if (err)
        return svn_error_compose_create(externals_err, err);
    }

Which can easily return true as it references baton members pointing
who knows where:

svn_boolean_t
svn_cl__notifier_check_conflicts(void *baton)
{
  struct notify_baton *nb = baton;

  return (nb->text_conflicts || nb->prop_conflicts || nb->tree_conflicts);
}

If svn_cl__notifier_check_conflicts does return true, then we segfault
when svn_cl__notifier_get_conflicted_paths tries to call
apr_hash_pool_get on an uninitialized baton member:

apr_array_header_t *
svn_cl__notifier_get_conflicted_paths(void *baton, apr_pool_t *result_pool)
{
  struct notify_baton *nb = baton;
  apr_array_header_t *sorted_array;
  apr_array_header_t *result_array;
  int i;

  sorted_array = svn_sort__hash(nb->conflicted_paths,
                                svn_sort_compare_items_as_paths,
                                apr_hash_pool_get(nb->conflicted_paths));
                                                  ^^^^^
                                                  Uh-oh
-- 
Paul T. Burba
CollabNet, Inc. -- www.collab.net -- Enterprise Cloud Development
Skype: ptburba