Bug 353947 - Kate crashes when project plugin autoloads GIT repos
Summary: Kate crashes when project plugin autoloads GIT repos
Status: RESOLVED FIXED
Alias: None
Product: kate
Classification: Applications
Component: application (show other bugs)
Version: 5.0.0
Platform: Debian unstable Linux
: NOR crash
Target Milestone: ---
Assignee: KWrite Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-10-16 03:39 UTC by jm.ouwerkerk
Modified: 2015-10-17 14:54 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
Working test case in C (does not crash) (659 bytes, text/x-csrc)
2015-10-17 07:49 UTC, jm.ouwerkerk
Details

Note You need to log in before you can comment on or make changes to this bug.
Description jm.ouwerkerk 2015-10-16 03:39:40 UTC
Enabling the "Autoload repositories" feature with Kate 15.08 causes the application to crash on an invalid free(), which is linked to the usage of libgit.

Backtrace obtained using gdb:

#0  0x00007ffff77bf107 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff77c04e8 in __GI_abort () at abort.c:89
#2  0x00007ffff77fd214 in __libc_message (do_abort=do_abort@entry=1, fmt=fmt@entry=0x7ffff78f0000 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
#3  0x00007ffff78029ee in malloc_printerr (action=1, str=0x7ffff78ec0be "free(): invalid pointer", ptr=<optimized out>) at malloc.c:4996
#4  0x00007ffff78036f6 in _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at malloc.c:3840
#5  0x00007fffe0ff991a in ?? () from /usr/lib/x86_64-linux-gnu/libgit2.so.23
#6  0x00007fffe0ff9a59 in ?? () from /usr/lib/x86_64-linux-gnu/libgit2.so.23
#7  0x00007fffe100c16c in ?? () from /usr/lib/x86_64-linux-gnu/libgit2.so.23
#8  0x00007fffe10521b5 in ?? () from /usr/lib/x86_64-linux-gnu/libgit2.so.23
#9  0x00007fffe1052810 in git_repository_config_snapshot () from /usr/lib/x86_64-linux-gnu/libgit2.so.23
#10 0x00007fffe1052968 in git_repository_open_ext () from /usr/lib/x86_64-linux-gnu/libgit2.so.23
#11 0x00007fffe19f1d06 in ?? () from /usr/lib/x86_64-linux-gnu/qt5/plugins/ktexteditor/kateprojectplugin.so
#12 0x00007fffe19f5216 in ?? () from /usr/lib/x86_64-linux-gnu/qt5/plugins/ktexteditor/kateprojectplugin.so
#13 0x00007fffe19f557f in ?? () from /usr/lib/x86_64-linux-gnu/qt5/plugins/ktexteditor/kateprojectplugin.so
#14 0x00007fffe19f6272 in ?? () from /usr/lib/x86_64-linux-gnu/qt5/plugins/ktexteditor/kateprojectplugin.so
#15 0x00007fffe19f66e1 in ?? () from /usr/lib/x86_64-linux-gnu/qt5/plugins/ktexteditor/kateprojectplugin.so
#16 0x00007fffe15628a0 in ThreadWeaver::Executor::run(QSharedPointer<ThreadWeaver::JobInterface> const&, ThreadWeaver::Thread*) () from /usr/lib/x86_64-linux-gnu/libKF5ThreadWeaver.so.5
#17 0x00007fffe15614e0 in ThreadWeaver::Job::execute(QSharedPointer<ThreadWeaver::JobInterface> const&, ThreadWeaver::Thread*) () from /usr/lib/x86_64-linux-gnu/libKF5ThreadWeaver.so.5
#18 0x00007fffe1560f8a in ThreadWeaver::Thread::run() () from /usr/lib/x86_64-linux-gnu/libKF5ThreadWeaver.so.5
#19 0x00007ffff382c25e in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#20 0x00007ffff049e0a4 in start_thread (arg=0x7fffd9940700) at pthread_create.c:309
#21 0x00007ffff787006d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

Reproducible: Always

Steps to Reproduce:
1. cd $project_dir
2. kate README.md
3. <boom>

Actual Results:  
A segfault due to invalid free().

Expected Results:  
I'd hoped the document would be opened.

The problem can be worked around by disabling the autoload feature for GIT repositories in the "Projects" preferences pane (Application > Projects) from the Kate settings dialog.

Please review whether or not Kate's projects plugin uses the libgit2 API correctly or whether this is a regression in libgit proper.

Version info:

kate --version
kate 15.08.1

sudo apt-cache policy libgit2-23
libgit2-23:
  Installed: 0.23.1-1
  Candidate: 0.23.1-1
Comment 1 Christoph Cullmann 2015-10-16 11:30:10 UTC
> Please review whether or not Kate's projects plugin uses the libgit2 API correctly or whether this is a regression in libgit proper.
Hi, I reviewed our code, I really don't see any error there :/
Comment 2 jm.ouwerkerk 2015-10-17 00:09:15 UTC
It turns out the same crash can also be provoked by merely having the Project plugin enabled and trying to open a document from a git project. This seems to happen when the document is not already in session.

That is:

I now have a session in which I'm happily editing away at my own GIT project which originally triggered the crash. I can save the session, open the session and open new documents from the same GIT repo inside this session.

But when I try to open, say, CMakeLists.txt from a recently updated copy of the Kate source repo itself inside a fresh new session (another Kate instance) then I get the crash. Disabling the Project plugin entirely circumvents this.
Comment 3 jm.ouwerkerk 2015-10-17 00:18:31 UTC
Scratch that last bit: the crash in Kate repos seems directly linked to the .kateproject file (which I hadn't noticed because hidden file). So the bug manifests itself when loading a file from a git repo which generated either an auto-loaded a KateProject instance or is explicitly configured with a .kateproject file.
Comment 4 jm.ouwerkerk 2015-10-17 07:49:52 UTC
Created attachment 95017 [details]
Working test case in C (does not crash)

It seems libgit2 is not to blame, since the attached simple test case in C does not produce the same crash. 

The test case simply opens a GIT repo using the ***_open_ext() call (same as the projects plugin) and closes it again with added printf() messages to track each step.

Maybe the bug is caused by the Kate project plugin's use of threading (ThreadWeaver) ?
Comment 5 Christoph Cullmann 2015-10-17 12:06:19 UTC
You need to keep in mind: we use libgit2 in different threads, that might lead to different race conditions in libgit2 than the singled threaded test case ;=)
Comment 6 jm.ouwerkerk 2015-10-17 13:44:23 UTC
Yeah, the test case merely verifies whether the problem is one for the libgit2 devs to fix or for Kate to work around. It seems to be the latter.

Note that threading support in libgit2 is not exactly... out of beta?

Also, what exactly are the guarantees made by ThreadWeaver? Is it merely a frontend to a thread pool which dispatches jobs to the worker/slave threads? In which case: what is the guarantee that a git_libgit2_init() call executed in Thread A is valid for a GIT job running in the context of Thread B?

I'm not too sure how one would go about implementing this, but would it be possible for the Kate project plugin to 'pin' all its GIT operations to a single specific QThread?
Comment 7 Christoph Cullmann 2015-10-17 13:59:59 UTC
I think you point to the right issue: we miss to call the init functions in the threads :/
The good thing: KTextEditor uses it only in the main thread an calls it there.
Kate can call it in the plugin inside the right thread, as it is "OK" to stack that calls:
https://libgit2.github.com/libgit2/#HEAD/group/libgit2/git_libgit2_init
Comment 8 Christoph Cullmann 2015-10-17 14:10:02 UTC
Git commit 4de75478b35d65b597742cc5192de14648bc1e47 by Christoph Cullmann.
Committed on 17/10/2015 at 14:09.
Pushed by cullmann into branch 'master'.

init libgit2 in right thread
avoid too much configure magic, we require recent enough libgit anyways

M  +2    -4    addons/project/CMakeLists.txt
M  +0    -26   addons/project/kateprojectplugin.cpp
M  +9    -2    addons/project/kateprojectworker.cpp
D  +0    -3    addons/project/libgit2_config.h.cmake

http://commits.kde.org/kate/4de75478b35d65b597742cc5192de14648bc1e47
Comment 9 jm.ouwerkerk 2015-10-17 14:16:30 UTC
Actually I hit on a different way to fix the issue. I'll try and post a patch through reviewboard. It's a less invasive change and I tested it (i.e. works for me).
Comment 10 Christoph Cullmann 2015-10-17 14:23:23 UTC
Git commit 567128d28249969e57c0ec770073b3f703e491a1 by Christoph Cullmann.
Committed on 17/10/2015 at 14:22.
Pushed by cullmann into branch 'master'.

simplify git2 init, given we require recent enough version

M  +1    -1    CMakeLists.txt
M  +2    -6    src/CMakeLists.txt
M  +0    -2    src/document/katedocument.cpp
D  +0    -3    src/libgit2_config.h.cmake
M  +3    -14   src/utils/kateglobal.cpp

http://commits.kde.org/ktexteditor/567128d28249969e57c0ec770073b3f703e491a1
Comment 11 Christoph Cullmann 2015-10-17 14:25:08 UTC
> Actually I hit on a different way to fix the issue. I'll try and post a patch through reviewboard. It's a less invasive change and I tested it (i.e. works for me).
Hi, if you have some other fix, happy to see it ;=)
I still think the last two changes I made make it easier, given we no longer check for functions the library version we require no longer has and we init the stuff in the right thread now, always,
Comment 12 Christoph Cullmann 2015-10-17 14:35:26 UTC
Git commit 1a56451ea0d7d7cbc8d8e06ddfa033063d0e825b by Christoph Cullmann.
Committed on 17/10/2015 at 14:34.
Pushed by cullmann into branch 'master'.

use constData

M  +2    -1    src/document/katedocument.cpp

http://commits.kde.org/ktexteditor/1a56451ea0d7d7cbc8d8e06ddfa033063d0e825b
Comment 13 Christoph Cullmann 2015-10-17 14:41:23 UTC
Git commit df08e724d8d83d821a2d6ceb0bb41f231dbdd451 by Christoph Cullmann.
Committed on 17/10/2015 at 14:40.
Pushed by cullmann into branch 'master'.

use constData and cleanup the code a bit
REVIEW: 125674

M  +10   -10   addons/project/kateprojectworker.cpp

http://commits.kde.org/kate/df08e724d8d83d821a2d6ceb0bb41f231dbdd451
Comment 14 Christoph Cullmann 2015-10-17 14:47:01 UTC
Please try out the latest project plugin patch ;=)
I think the object on the stack should not actually help, but it makes the code a bit cleaner.
constData() is more nice, too.
I still think the missing _init stuff was the main problem and all other things just "good luck" ;)
Comment 15 jm.ouwerkerk 2015-10-17 14:53:48 UTC
I've recompiled my Kate using kdesrc-build from current master. The issue appears to be fixed now.
Comment 16 Christoph Cullmann 2015-10-17 14:54:57 UTC
Yeah!

Thanks btw. for:

a) the report
b) the help to resolve this

I only all bugs would work out that way ;=)