https://bugs.kde.org/show_bug.cgi?id=446404

            Bug ID: 446404
           Summary: parser sometimes ignores custom parser options
           Product: kdevelop
           Version: 5.6.2
          Platform: Gentoo Packages
                OS: Linux
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: Language Support: CPP (Clang-based)
          Assignee: kdevelop-bugs-n...@kde.org
          Reporter: daniel.san...@pobox.com
  Target Milestone: ---

SUMMARY
16 threads and the Linux kernel sources and I sometimes end up with #include
<linux/modules.h> referencing /usr/include/linux/modules.h.  All parse jobs run
by the background parser seem correct.  But when I open a file (in the project)
and it's scheduled for immediate parsing, BANG, I see the debug spew using the
default arguments.  This essential breaks KDevelop as a usable IDE for the
Linux kernel sources, because I have to 'git grep' and use elixir.bootlin.com
to look up types and functions, since KDevelop can't find them.


STEPS TO REPRODUCE
1. KDEV_CLANG_DISPLAY_ARGS=1 KDEV_CLANG_DISPLAY_DIAGS=1 kdevelop
2. Open sources to Linux kernel
3. set custom C parser options based upon building the kernel and sucking out
the arguments.  In my particular case, I'm cross-compiling and these are my
arguments:

--target=mipsel-openwrt-linux -mno-check-zero-division -mabi=32 -mno-abicalls
-msoft-float -march=mips32r2 -mtune=34kc -std=gnu89 -nostdinc -isystem
/home/daniel/proj/embedded/openwrt/v21.02.y/staging_dir/toolchain-mipsel_24kc_gcc-10.2.0_musl/lib/gcc/mipsel-openwrt-linux-musl/10.2.0/include
-Iarch/mips/include -Iarch/mips/include/generated -Iinclude
-Iarch/mips/include/uapi -Iarch/mips/include/generated/uapi -Iinclude/uapi
-Iinclude/generated/uapi -include include/linux/kconfig.h -include
include/linux/compiler_types.h -Iarch/mips/include/asm/mach-ralink
-Iarch/mips/include/asm/mach-ralink/mt7620 -Iarch/mips/include/asm/mach-generic
-D__KERNEL__ -D__MIPSEL__ -DVMLINUX_LOAD_ADDRESS=0xffffffff80000000
-DLINKER_LOAD_ADDRESS=0x80000000 -DDATAOFFSET=0 -DGAS_HAS_SET_HARDFLOAT
-DTOOLCHAIN_SUPPORTS_VIRT -DTOOLCHAIN_SUPPORTS_XPA -DTOOLCHAIN_SUPPORTS_CRC
-DTOOLCHAIN_SUPPORTS_DSP -DTOOLCHAIN_SUPPORTS_GINV -ferror-limit=99
-fspell-checking -Wdocumentation -Wall -Wundef -Wno-trigraphs
-Wno-format-security -Wno-frame-address -Wno-address-of-packed-member
-Wframe-larger-than=1024 -Wimplicit-fallthrough -Wno-unused-const-variable
-Wdeclaration-after-statement -Wvla -Wno-pointer-sign -Wno-array-bounds 
-Wno-uninitialized -Wno-incompatible-library-redeclaration
-Wno-unknown-warning-option -Wno-implicit-fallthrough -working-directory
/home/daniel/proj/embedded/openwrt/linux-5.4.143

Actually, for this to even work, I had to hack kdvelop and stop it from
inserting a -working-directory argument, but I can probably just change all of
my include paths to absolute and not have that problem.

4. let it start parsing and notice it's correct
5. Open a file and notice that it's incorrect (it parsed with the default
options).
6. If I allow all parsing to complete before opening any files, then they are
correct until some point later after editing enough.  I haven't seen it
incorrectly parse a file after making changes (yet) only after initially
opening it (before background parsing has completed).

I don't know if this is a race or not. I'm on a 8/16 Ryzen and using 16 parsing
threads and 500ms delay.  I've tried digging into the KDevelop sources, and I
got as as finding where the job is run and where the job is scheduled.

Job run from:
(gdb) bt
#0  ParseSessionData::ParseSessionData (this=this@entry=0x7fff39085260,
unsavedFiles=..., index=index@entry=0x5555569dbb70, 
    environment=..., options=..., options@entry=...) at
../plugins/clang/duchain/parsesession.cpp:272
#1  0x00007fff47b68213 in ClangParseJob::createSessionData
(this=this@entry=0x555557c10270)
    at
/usr/src/debug/dev-util/kdevelop-5.6.2/kdevelop-5.6.2/plugins/clang/clangparsejob.cpp:394
#2  0x00007fff47b69bcc in ClangParseJob::run (this=<optimized out>)
    at
/usr/src/debug/dev-util/kdevelop-5.6.2/kdevelop-5.6.2/plugins/clang/clangparsejob.cpp:300
#3  0x00007ffff2bb8f99 in ThreadWeaver::IdDecorator::run (this=<optimized out>,
self=..., thread=0x555556ac2350)
    at
/usr/src/debug/kde-frameworks/threadweaver-5.85.0/threadweaver-5.85.0/src/iddecorator.cpp:50
#4  0x00007ffff2bb9597 in ThreadWeaver::Executor::run (this=<optimized out>,
job=..., thread=<optimized out>)
    at
/usr/src/debug/kde-frameworks/threadweaver-5.85.0/threadweaver-5.85.0/src/executor.cpp:33
#5  0x00007ffff2bb8580 in ThreadWeaver::Job::execute (this=<optimized out>,
self=..., th=0x555556ac2350)
    at
/usr/src/debug/kde-frameworks/threadweaver-5.85.0/threadweaver-5.85.0/src/job.cpp:64
#6  0x00007ffff2bb7d82 in ThreadWeaver::Thread::run (this=0x555556ac2350)
    at
/usr/src/debug/kde-frameworks/threadweaver-5.85.0/threadweaver-5.85.0/src/thread.cpp:98
#7  0x00007ffff6420c56 in QThreadPrivate::start (arg=0x555556ac2350)
    at
/usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/thread/qthread_unix.cpp:329
#8  0x00007ffff34e9e21 in start_thread (arg=0x7fff3ffff640) at
pthread_create.c:481
#9  0x00007ffff6066b3f in clone () at
../sysdeps/unix/sysv/linux/x86_64/clone.S:95


job schedule from:
(gdb) where
#0  ThreadWeaver::Weaver::enqueue (this=0x555555b9a450, jobs=...) at
/usr/src/debug/kde-frameworks/threadweaver-5.85.0/threadweaver-5.85.0/src/weaver.cpp:204
#1  0x00007ffff2bb3c45 in ThreadWeaver::Queue::enqueue (jobs=...,
this=0x555555dc3eb8) at
/usr/src/debug/kde-frameworks/threadweaver-5.85.0/threadweaver-5.85.0/src/queue.cpp:169
#2  ThreadWeaver::Queue::enqueue (this=this@entry=0x555555dc3eb8, job=...) at
/usr/src/debug/kde-frameworks/threadweaver-5.85.0/threadweaver-5.85.0/src/queue.cpp:174
#3  0x00007ffff4f77870 in
KDevelop::BackgroundParserPrivate::parseDocumentsInternal
(this=this@entry=0x555555dc3e40) at
../kdevplatform/language/backgroundparser/backgroundparser.cpp:331
#4  0x00007ffff4f7270c in KDevelop::BackgroundParser::parseDocuments
(this=0x555555d97d10) at
../kdevplatform/language/backgroundparser/backgroundparser.cpp:678
#5  0x00007ffff4f72a0f in QtPrivate::FunctorCall<QtPrivate::IndexesList<>,
QtPrivate::List<>, void, void (KDevelop::BackgroundParser::*)()>::call(void
(KDevelop::BackgroundParser::*)(), KDevelop::BackgroundParser*, void**)
(arg=<optimized out>, o=<optimized out>, f=<optimized out>) at
/usr/include/qt5/QtCore/qobjectdefs_impl.h:152
#6  QtPrivate::FunctionPointer<void
(KDevelop::BackgroundParser::*)()>::call<QtPrivate::List<>, void>(void
(KDevelop::BackgroundParser::*)(), KDevelop::BackgroundParser*, void**)
(arg=<optimized out>, 
    o=<optimized out>, f=<optimized out>) at
/usr/include/qt5/QtCore/qobjectdefs_impl.h:185
#7  QtPrivate::QSlotObject<void (KDevelop::BackgroundParser::*)(),
QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*,
void**, bool*) (which=<optimized out>, this_=<optimized out>, 
    r=<optimized out>, a=<optimized out>, ret=<optimized out>) at
/usr/include/qt5/QtCore/qobjectdefs_impl.h:418
#8  0x00007ffff66099b6 in QtPrivate::QSlotObjectBase::call (a=0x7fffffffccc0,
r=0x555555d97d10, this=0x555555c9af30)
    at
../../include/QtCore/../../../qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qobjectdefs_impl.h:398
#9  doActivate<false> (sender=0x555555dc3e60, signal_index=3,
argv=0x7fffffffccc0) at
/usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qobject.cpp:3886
#10 0x00007ffff6603717 in QMetaObject::activate (sender=<optimized out>,
m=m@entry=0x7ffff68afca0 <QTimer::staticMetaObject>,
local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7fffffffccc0)
    at
/usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qobject.cpp:3946
#11 0x00007ffff660db0a in QTimer::timeout (this=<optimized out>, _t1=...) at
.moc/moc_qtimer.cpp:205
#12 0x00007ffff66017bf in QObject::event (this=0x555555dc3e60,
e=0x7fffffffce10) at
/usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qobject.cpp:1336
#13 0x00007ffff7228daf in QApplicationPrivate::notify_helper (this=<optimized
out>, receiver=0x555555dc3e60, e=0x7fffffffce10)
    at
/usr/src/debug/dev-qt/qtwidgets-5.15.2-r11/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/widgets/kernel/qapplication.cpp:3632
#14 0x00007ffff65d6008 in QCoreApplication::notifyInternal2
(receiver=0x555555dc3e60, event=0x7fffffffce10)
    at
/usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qcoreapplication.cpp:1064
#15 0x00007ffff662748b in QTimerInfoList::activateTimers (this=0x5555555ebcb0)
    at
/usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qtimerinfo_unix.cpp:643
#16 0x00007ffff6627d91 in timerSourceDispatch (source=<optimized out>)
    at
/usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qeventdispatcher_glib.cpp:183
#17 idleTimerSourceDispatch (source=source@entry=0x5555555fd670) at
/usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qeventdispatcher_glib.cpp:230
#18 0x00007ffff2c20065 in g_main_dispatch (context=0x7fffdc005000) at
../glib-2.68.4/glib/gmain.c:3337
#19 g_main_context_dispatch (context=0x7fffdc005000) at
../glib-2.68.4/glib/gmain.c:4055
#20 0x00007ffff2c20408 in g_main_context_iterate
(context=context@entry=0x7fffdc005000, block=block@entry=1,
dispatch=dispatch@entry=1, self=<optimized out>) at
../glib-2.68.4/glib/gmain.c:4131
#21 0x00007ffff2c204bf in g_main_context_iteration (context=0x7fffdc005000,
may_block=1) at ../glib-2.68.4/glib/gmain.c:4196
#22 0x00007ffff6628164 in QEventDispatcherGlib::processEvents
(this=0x55555561b7f0, flags=...)
    at
/usr/src/debug/dev-qt/qtcore-5.15.2-r10/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/kernel/qeventdispatcher_glib.cpp:423
#23 0x00007ffff65d49fb in QEventLoop::exec (this=this@entry=0x7fffffffd050,
flags=..., flags@entry=...)
    at
../../include/QtCore/../../../qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/global/qflags.h:69
#24 0x00007ffff65dd02d in QCoreApplication::exec () at
../../include/QtCore/../../../qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/corelib/global/qflags.h:121
#25 0x00007ffff6ae2f7c in QGuiApplication::exec () at
/usr/src/debug/dev-qt/qtgui-5.15.2-r13/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/gui/kernel/qguiapplication.cpp:1867
#26 0x00007ffff7228d25 in QApplication::exec () at
/usr/src/debug/dev-qt/qtwidgets-5.15.2-r11/qtbase-a4f9e56975fa6ab4a1f63a9b34a4d77b1cfe4acd/src/widgets/kernel/qapplication.cpp:2824
#27 0x000055555556198e in main (argc=<optimized out>, argv=<optimized out>) at
../app/main.cpp:850
(gdb) frame
#3  0x00007ffff4f77870 in
KDevelop::BackgroundParserPrivate::parseDocumentsInternal
(this=this@entry=0x555555dc3e40) at
../kdevplatform/language/backgroundparser/backgroundparser.cpp:331
331                     m_parseJobs.insert(url, decorator);


I was examining the ClangParseJob ctor, as that seems to be where the
m_environment data is read from one place and passed to another, but I'm out of
time and I have to get back to fixing kernel code w/o a good IDE / parser :(

I'm probably just going to build a hacked version of kdvelop that has my
settings hard-coded so that I can resume with my job (which right now is to fix
a silly OpenWRT/kernel bug).  Then I'll only run that version for kernel
hacking.


OBSERVED RESULT
Some files parsed with incorrect settings, making it 92% useless as a code
navigator.

EXPECTED RESULT
Never look at /usr/include when I have -nostdinc -isystem/my/path, etc. (Linux
kernel implements it's own subset of standard C library, so there's never an
external libc.)

SOFTWARE/OS VERSIONS
Windows:  sucks
macOS: 
Linux/KDE Plasma: 5.6.2
(available in About System)
KDE Plasma Version: 
KDE Frameworks Version: 
Qt Version: 

ADDITIONAL INFORMATION
Caveats:
I should probably open an additional bug report for:
1. Do not add -working-directory to clang parser arguments when the argument is
already present.  Alternatively, allow user to select if cwd will be the
project root or the directory of the file being parsed.

I should probably open a new feature requests for:
1. Option to suppress clang parser from adding "-nostdinc -isystem/usr/include"
(very important for kernel hacking)
2. Option to suppress or override clang parser from adding
"-isystem/path/to/clang/headers" (less important)
3. Facilitate relative paths so that a kdevelop project file can be put in
source control and work in different directories.

If any developers are interested, I am willing to tar up my entire working tree
for experimentation.  Thanks!

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to