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

Log caching: Crash in `Get merge logs' without access to the repository root

From: Evgeny Kotkov <evgeny.kotkov_at_visualsvn.com>
Date: Wed, 9 Mar 2016 17:24:04 +0300

The `Get merge logs' command can cause a segfault in TortoiseSVN 1.9.3.

The crash is also reproducible in trunk_at_r27234 and is caused by an access
violation (out of bounds access in an std::vector) in the implementation of
the log caching. Please note that it should be reproducible irrespectively
of whether the log caching feature is enabled or disabled in the settings.

Reproduction script:

 1. Create a repository with a /trunk folder hosted by httpd
 2. Prohibit access to the root of the repository
 3. Allow rw access to /trunk
 4. In the TortoiseSVN log viewer, click `Get merge logs' for /trunk or,
    alternatively, run the following command:
    TortoiseProc /command:log /path:"http://localhost/repository/trunk" /merge

Backtrace of the TortoiseProc.exe crash, uploaded with DumpID=7261138:

    TortoiseProc.exe!LogCache::CRevisionInfoContainer::GetAuthorID(
        index=4294967295)
    TortoiseProc.exe!CCacheLogQuery::SendToReceiver(
        revision=1, options={...}, mergeInfo=0x000000b1942fd834)
    TortoiseProc.exe!CCacheLogQuery::LogRevision(
        revision=1, options={...}, mergeInfo=0x000000b1942fd834)
    TortoiseProc.exe!CCacheLogQuery::CMergeLogger::ReceiveLog(
        changes=0x0, rev=1, stdRevProps=0x0, userRevProps=0x0,
        mergeInfo=0x000000b1942fd834)
    TortoiseProc.exe!CSVNLogQuery::LogReceiver()
    libsvn_tsvn.dll!log_closed()
    libsvn_tsvn.dll!xml_cb_end()
    libsvn_tsvn.dll!expat_end()
    libaprutil_tsvn.dll!doContent()
    libaprutil_tsvn.dll!contentProcessor()
    libaprutil_tsvn.dll!doProlog()
    libaprutil_tsvn.dll!prologProcessor()
    libaprutil_tsvn.dll!prologInitProcessor()
    libaprutil_tsvn.dll!XML_ParseBuffer()
    libaprutil_tsvn.dll!XML_Parse()
    libsvn_tsvn.dll!expat_response_handler()
    libsvn_tsvn.dll!handle_response()
    libsvn_tsvn.dll!handle_response_cb()
    libsvn_tsvn.dll!read_from_connection()
    libsvn_tsvn.dll!serf__process_connection()
    libsvn_tsvn.dll!serf_event_trigger()
    libsvn_tsvn.dll!serf_context_run()
    libsvn_tsvn.dll!svn_ra_serf__context_run()
    libsvn_tsvn.dll!svn_ra_serf__get_log()
    libsvn_tsvn.dll!svn_ra_get_log2()
    libsvn_tsvn.dll!run_ra_get_log()
    libsvn_tsvn.dll!svn_client_log5()
    TortoiseProc.exe!CSVNLogQuery::Log()
    TortoiseProc.exe!CCacheLogQuery::InternalLogWithMerge()
    TortoiseProc.exe!CCacheLogQuery::Log()
    TortoiseProc.exe!SVN::ReceiveLog()
    ...

Here is what happens over the network in this case:

  OPTIONS http://localhost/repository/trunk HTTP/1.1 (200 OK)
  OPTIONS http://localhost/repository/trunk HTTP/1.1 (200 OK)
  OPTIONS http://localhost/repository/trunk HTTP/1.1 (200 OK)
  OPTIONS http://localhost/repository/trunk HTTP/1.1 (200 OK)
  OPTIONS http://localhost/repository/trunk HTTP/1.1 (200 OK)
  OPTIONS http://localhost/repository/trunk HTTP/1.1 (200 OK)
  OPTIONS http://localhost/repository/trunk HTTP/1.1 (200 OK)
  REPORT http://localhost/repository/!svn/rvr/1/trunk HTTP/1.1 (200 OK)
      Request:
        <S:log-report xmlns:S="svn:">
          <S:start-revision>1</S:start-revision>
          <S:end-revision>0</S:end-revision>
          <S:limit>100</S:limit>
          <S:include-merged-revisions/>
          <S:all-revprops/>
          <S:path></S:path>
          <S:encode-binary-props/>
        </S:log-report>
      Response:
        <S:log-report xmlns:S="svn:" xmlns:D="DAV:">
          <S:log-item>
          <D:version-name>1</D:version-name>
          <D:creator-displayname>Author</D:creator-displayname>
          <S:date>2016-03-09T10:08:06.624980Z</S:date>
          </S:log-item>
        </S:log-report>
  OPTIONS http://localhost/repository HTTP/1.1 (403 Forbidden)

Another thing worth mentioning is the overall performance of the operation.
If I allow access to the repository root, the `Get merge logs' command does
a huge amount of REPORT requests to the server, and that can be very slow,
especially considering that every REPORT creates a new TCP connection.

Here is what happens over the network when I display a part of the log for
/branches/1.3.x in the repository containing 1455 revisions (even with the
log caching feature disabled):

  REPORT http://localhost/repository/!svn/rvr/1455/branches/1.3.x
      start: 1455, end: 0, limit: 100, { all revprops }, include merged
  REPORT http://localhost/repository/!svn/rvr/1446
      start: 1446, end: 0, limit: 100, { svn:log, svn:date, svn:author }
  REPORT http://localhost/repository/!svn/rvr/1333
      start: 1333, end: 0, limit: 100, { svn:log, svn:date, svn:author }
  REPORT http://localhost/repository/!svn/rvr/1341
      start: 1341, end: 0, limit: 100, { svn:log, svn:date, svn:author }
  REPORT http://localhost/repository/!svn/rvr/1228
      start: 1228, end: 0, limit: 100, { svn:log, svn:date, svn:author }
  REPORT http://localhost/repository/!svn/rvr/1231
      start: 1231, end: 0, limit: 100, { svn:log, svn:date, svn:author }
  REPORT http://localhost/repository/!svn/rvr/1087
      start: 1087, end: 0, limit: 100, { svn:log, svn:date, svn:author }
  REPORT http://localhost/repository/!svn/rvr/1091
      start: 1091, end: 0, limit: 100, { svn:log, svn:date, svn:author }
  REPORT http://localhost/repository/!svn/rvr/1233
      start: 1233, end: 0, limit: 100, { svn:log, svn:date, svn:author }
  REPORT http://localhost/repository/!svn/rvr/1124
      start: 1124, end: 0, limit: 100, { svn:log, svn:date, svn:author }
  REPORT http://localhost/repository/!svn/rvr/1128
      start: 1128, end: 0, limit: 100, { svn:log, svn:date, svn:author }
  REPORT http://localhost/repository/!svn/rvr/886
      start: 886, end: 0, limit: 100, { svn:log, svn:date, svn:author }
  ...

  (Compared to that, the svn log -g does only a single REPORT).

In a network with RTT=150ms, showing the same log with TortoiseSVN could
be up to 15-20 times slower than with the command-line client — something
like 2 seconds (svn.exe) vs 35 seconds (TortoiseProc.exe) in this particular
case.

Regards,
Evgeny Kotkov

------------------------------------------------------
http://tortoisesvn.tigris.org/ds/viewMessage.do?dsForumId=757&dsMessageId=3165025

To unsubscribe from this discussion, e-mail: [dev-unsubscribe_at_tortoisesvn.tigris.org].
Received on 2016-03-09 17:12:37 CET

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

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