[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

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

From: Paul Burba <ptburba_at_gmail.com>
Date: Tue, 4 Sep 2012 15:01:22 -0400

On Wed, Jul 4, 2012 at 11:40 AM, <stsp_at_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_at_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
Received on 2012-09-04 21:01:57 CEST

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.