#13401 closed defect (fixed)
crash in apr_pool_destroy when accessing non-existing file in version control browser
Reported by: | Owned by: | Jun Omae | |
---|---|---|---|
Priority: | normal | Milestone: | 1.5.3 |
Component: | version control/browser | Version: | 1.5.2 |
Severity: | normal | Keywords: | svn114, python3, crash, patch |
Cc: | Branch: | log:jomae.git@t13401 | |
Release Notes: |
Avoid crashing when apr memory pools (parent and child) are destroyed by cyclic garbage collector. |
||
API Changes: | |||
Internal Changes: |
Description
When I run tracd and request a non-existing file from the repository, the application crashes:
Server:
$ cat <<EOF > gdbcmds.txt set height 0 set breakpoint pending on run trac/web/standalone.py -p 8000 --base-path /trac -e ~/tracenvs backtrace quit EOF PYTHONPATH=. gdb /usr/local/bin/python3.8 -x gdbcmds.txt -batch
Client:
ab -n3 http://172.26.128.54:8000/trac/bar/export/1/second.txt
Coredump (full log in attachment:typescript-coredump-backtrace.txt)
Server starting in PID 77461. Serving on 0.0.0.0:8000 view at http://127.0.0.1:8000/trac Using HTTP/1.1 protocol version [New LWP 101056 of process 77461] 172.26.140.136 - - [27/Apr/2021 00:29:10] "GET /trac/bar/export/1/second.txt HTTP/1.0" 404 - [LWP 101056 of process 77461 exited] [New LWP 101058 of process 77461] 172.26.140.136 - - [27/Apr/2021 00:29:16] "GET /trac/bar/export/1/second.txt HTTP/1.0" 404 - [LWP 101058 of process 77461 exited] [New LWP 101057 of process 77461] Thread 4 received signal SIGSEGV, Segmentation fault. [Switching to LWP 101057 of process 77461] 0x00000008043b6478 in run_cleanups (cref=<error reading variable: Cannot access memory at address 0x7fffdf3fbff8>) at memory/unix/apr_pools.c:2624 2624 { #0 0x00000008043b6478 in run_cleanups (cref=<error reading variable: Cannot access memory at address 0x7fffdf3fbff8>) at memory/unix/apr_pools.c:2624 #1 0x00000008043b5e6e in apr_pool_destroy (pool=0x8044f5028) at memory/unix/apr_pools.c:987 #2 0x00000008043b5ea8 in apr_pool_destroy (pool=0x8044f5028) at memory/unix/apr_pools.c:997 #3 0x00000008043b5ea8 in apr_pool_destroy (pool=0x8044f5028) at memory/unix/apr_pools.c:997 #4 0x00000008043b5ea8 in apr_pool_destroy (pool=0x8044f5028) at memory/unix/apr_pools.c:997 #5 0x00000008043b5ea8 in apr_pool_destroy (pool=0x8044f5028) at memory/unix/apr_pools.c:997 #6 0x00000008043b5ea8 in apr_pool_destroy (pool=0x8044f5028) at memory/unix/apr_pools.c:99
If I compile apr with --enable-pool-concurrency-check
the following error is shown when I request the URL (first hit) (full log in attachment:typescript-with-apr-pool-concurrenty-check.txt]:
Server starting in PID 58551. Serving on 0.0.0.0:8000 view at http://127.0.0.1:8000/trac Using HTTP/1.1 protocol version [New LWP 100421 of process 58551] 172.26.140.136 - - [27/Apr/2021 00:26:51] "GET /trac/bar/export/1/second.txt HTTP/1.0" 404 - pool concurrency check: pool 0x8044f5028((null)), thread cur 802d09c00 in use by 802d09c00, state destroyed -> in use Thread 2 received signal SIGABRT, Aborted. [Switching to LWP 100421 of process 58551] 0x00000008008d5c2a in thr_kill () from /lib/libc.so.7 #0 0x00000008008d5c2a in thr_kill () from /lib/libc.so.7 #1 0x00000008008d4084 in raise () from /lib/libc.so.7 #2 0x000000080084a279 in abort () from /lib/libc.so.7 #3 0x00000008043b7cb1 in pool_concurrency_abort (pool=0x8044f5028, new=1, old=2) at memory/unix/apr_pools.c:768 #4 0x00000008043b6433 in pool_concurrency_set_used (pool=0x8044f5028) at memory/unix/apr_pools.c:778 #5 0x00000008043b5fb7 in apr_pool_destroy (pool=0x8044f5028) at memory/unix/apr_pools.c:989 #6 0x0000000804619097 in _wrap_apr_pool_destroy (self=<module at remote 0x805449b30>, args=(<apr_pool_t(this=<SwigPyObject at remote 0x80388a210>, _parent_pool=<apr_pool_t(this=<SwigPyObject at remote 0x80388a540>, _weakparent=<weakref at remote 0x803884680>, _apr_pool_destroy=<built-in method apr_pool_destroy of module object at remote 0x805449b30>, _svn_swig_py_clear_application_pool=<built-in method svn_swig_py_clear_application_pool of module object at remote 0x805449b30>) at remote 0x80388a3d0>, _weakparent=<weakref at remote 0x805437680>, _is_valid=<function at remote 0x804b6adc0>, _apr_pool_destroy=<built-in method apr_pool_destroy of module object at remote 0x805449b30>, _svn_swig_py_clear_application_pool=<built-in method svn_swig_py_clear_application_pool of module object at remote 0x805449b30>) at remote 0x80564faf0>,)) at subversion/bindings/swig/python/core.c:4034 ...
I was able to find a work-around to prevent it from happening, how-ever I do not know why this actually fixes it and whether this is the correct place to fix it:
Index: tracopt/versioncontrol/svn/svn_fs.py =================================================================== --- tracopt/versioncontrol/svn/svn_fs.py (revision 17527) +++ tracopt/versioncontrol/svn/svn_fs.py (working copy) @@ -686,6 +686,7 @@ raise NoSuchNode(path, rev, exception_to_unicode(e)) from e node_type = fs.check_path(self.root, self._scoped_path_utf8, pool) if node_type not in _kindmap: + pool.destroy() raise NoSuchNode(path, rev) cp_utf8 = fs.node_created_path(self.root, self._scoped_path_utf8, pool) cp = _from_svn(cp_utf8)
Version information of my development system:
$ svn --version svn, version 1.14.1 (r1886195) compiled Apr 21 2021, 12:19:02 on amd64-portbld-freebsd12.2 $ python --version Python 3.8.9 $ pkg info | grep -e apr -e serf -e subversion -e python apr-1.7.0.1.6.1_1 Apache Portability Library py38-subversion-1.14.1_2 Python bindings for version control system python-3.8_3,2 "meta-port" for the default version of Python interpreter python3-3_3 The "meta-port" for version 3 of the Python interpreter python38-3.8.9 Interpreted object-oriented programming language serf-1.3.9_6 Serf HTTP client library subversion-1.14.1 Version control system $ uname -a FreeBSD hbsd122 12.2-RELEASE FreeBSD 12.2-RELEASE r366954 GENERIC amd64
Attachments (2)
Change History (7)
by , 4 years ago
Attachment: | typescript-coredump-backtrace.txt added |
---|
by , 4 years ago
Attachment: | typescript-with-apr-pool-concurrenty-check.txt added |
---|
comment:1 by , 4 years ago
Keywords: | svn114 added; svn removed |
---|---|
Milestone: | → 1.5.3 |
Owner: | set to |
Status: | new → assigned |
comment:2 by , 4 years ago
Branch: | trunk@17527 → log:jomae.git@t13401 |
---|
Proposed changes in [e3d93c09/jomae.git] (jomae.git@t13401).
The pool of SubversionNode
should be marked as invalid when the pool of SubversionRepository
is destroyed via gc.collect()
, however it is destroyed doubly due to not marked.
In the changes, SubversionNode.__del__
destroys explicitly the pool in order to avoid the issue.
comment:5 by , 4 years ago
Keywords: | python3 added |
---|---|
Release Notes: | modified (diff) |
Resolution: | → fixed |
Status: | assigned → closed |
Thanks for the testing. Committed in [17529].
The issue has been fixed in subversion@trunk and @1.14.x.
See also:
- https://svn.apache.org/r1889487 -
subversion@trunk
- https://svn.apache.org/r1889654 -
subversion@1.14.x
- https://bugs.python.org/issue40312
Thanks for the reporting and investigating! Reproduced it on my environment (Python 3.9.4, Linux).
I try to verify the patch and fix it.