Author Topic: Code completion using LSP and clangd  (Read 297933 times)

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6034
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Code completion using LSP and clangd
« Reply #330 on: November 12, 2023, 04:32:47 am »
Today, I got a crash when I'm editing in C::B, see the call stack here, (from the codeblocks.RPT file)

Code
Error occurred on Sunday, November 12, 2023 at 11:26:58.

codeblocks.exe caused an Access Violation at location 00007FF870B9D924 in module clangd_client.dll Reading from location FFFFFFFFFFFFFFFF.

AddrPC           Params
00007FF870B9D924 000002A835C963F0 000002A83BBBD890 000002A836EDF8A0  clangd_client.dll!ClassBrowserBuilderThread::AddMembersOf+0x2cc  [D:/code/cbsource/cb_svn_git/src/plugins/contrib/clangd_client/src/codecompletion/classbrowserbuilderthread.cpp @ 921]
00007FF870B9AABF 000002A835C963F0 0000000000000000 0000000000000000  clangd_client.dll!ClassBrowserBuilderThread::SelectGUIItem+0x2db  [D:/code/cbsource/cb_svn_git/src/plugins/contrib/clangd_client/src/codecompletion/classbrowserbuilderthread.cpp @ 472]
00007FF870B99A7D 000002A835C963F0 0000000000000001 0000000000000000  clangd_client.dll!ClassBrowserBuilderThread::Entry+0x99  [D:/code/cbsource/cb_svn_git/src/plugins/contrib/clangd_client/src/codecompletion/classbrowserbuilderthread.cpp @ 309]
00007FF8782ECFBD 0000000000000000 000002A83653DCF0 000002A835C963F0  wxmsw32u_gcc_cb.dll!wxThreadInternal::DoThreadStart+0x64d
00007FF8782ED113 000002A83653C8D0 0000000000000000 000002A83653C8D0  wxmsw32u_gcc_cb.dll!wxThreadInternal::WinThreadStart+0x43
00007FF8CC66AF5A 00007FF8CC6C06D0 000002A83653C8D0 0000000000000000  msvcrt.dll!_beginthreadex+0x12a
00007FF8CC66B02C 0000000000000000 0000000000000000 0000000000000000  msvcrt.dll!_endthreadex+0xac
00007FF8CC0F7344 0000000000000000 0000000000000000 0000000000000000  KERNEL32.DLL!BaseThreadInitThunk+0x14
00007FF8CD5C26B1 0000000000000000 0000000000000000 0000000000000000  ntdll.dll!RtlUserThreadStart+0x21

It looks like a crash from the symbol tree building thread.

I'm using the clangd_client.dll without strip the debug information. And I'm using the rev 13384, I have some own patches, but my patches don't touch the symbol tree and thread handling related code.

Thanks.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2808
Re: Code completion using LSP and clangd
« Reply #331 on: November 12, 2023, 06:53:39 am »
Today, I got a crash when I'm editing in C::B, see the call stack here, (from the codeblocks.RPT file)

Code
Error occurred on Sunday, November 12, 2023 at 11:26:58.

codeblocks.exe caused an Access Violation at location 00007FF870B9D924 in module clangd_client.dll Reading from location FFFFFFFFFFFFFFFF.

AddrPC           Params
00007FF870B9D924 000002A835C963F0 000002A83BBBD890 000002A836EDF8A0  clangd_client.dll!ClassBrowserBuilderThread::AddMembersOf+0x2cc  [D:/code/cbsource/cb_svn_git/src/plugins/contrib/clangd_client/src/codecompletion/classbrowserbuilderthread.cpp @ 921]
00007FF870B9AABF 000002A835C963F0 0000000000000000 0000000000000000  clangd_client.dll!ClassBrowserBuilderThread::SelectGUIItem+0x2db  [D:/code/cbsource/cb_svn_git/src/plugins/contrib/clangd_client/src/codecompletion/classbrowserbuilderthread.cpp @ 472]
00007FF870B99A7D 000002A835C963F0 0000000000000001 0000000000000000  clangd_client.dll!ClassBrowserBuilderThread::Entry+0x99  [D:/code/cbsource/cb_svn_git/src/plugins/contrib/clangd_client/src/codecompletion/classbrowserbuilderthread.cpp @ 309]
00007FF8782ECFBD 0000000000000000 000002A83653DCF0 000002A835C963F0  wxmsw32u_gcc_cb.dll!wxThreadInternal::DoThreadStart+0x64d
00007FF8782ED113 000002A83653C8D0 0000000000000000 000002A83653C8D0  wxmsw32u_gcc_cb.dll!wxThreadInternal::WinThreadStart+0x43
00007FF8CC66AF5A 00007FF8CC6C06D0 000002A83653C8D0 0000000000000000  msvcrt.dll!_beginthreadex+0x12a
00007FF8CC66B02C 0000000000000000 0000000000000000 0000000000000000  msvcrt.dll!_endthreadex+0xac
00007FF8CC0F7344 0000000000000000 0000000000000000 0000000000000000  KERNEL32.DLL!BaseThreadInitThunk+0x14
00007FF8CD5C26B1 0000000000000000 0000000000000000 0000000000000000  ntdll.dll!RtlUserThreadStart+0x21

It looks like a crash from the symbol tree building thread.

I'm using the clangd_client.dll without strip the debug information. And I'm using the rev 13384, I have some own patches, but my patches don't touch the symbol tree and thread handling related code.

Thanks.

Update to at least rev 13390.
I think this is already fixed.
Thanks for the report.

Offline christo

  • Multiple posting newcomer
  • *
  • Posts: 32
Re: Code completion using LSP and clangd
« Reply #332 on: November 13, 2023, 07:32:33 pm »
Hi Pecan, I'm using a custom compiler for some projects. It is not recognised by clangd. If I change the code as below, it works fine and standard headers are parsed properly.

Code
Index: src/plugins/contrib/clangd_client/src/LSPclient/client.cpp
===================================================================
--- src/plugins/contrib/clangd_client/src/LSPclient/client.cpp (revision 13394)
+++ src/plugins/contrib/clangd_client/src/LSPclient/client.cpp (working copy)
@@ -427,11 +427,9 @@
     wxString masterPath = pCompiler ? pCompiler->GetMasterPath() : "";
 
     // get the first char of executable name from the compiler toolchain
-    CompilerPrograms toolchain = pCompiler->GetPrograms();
-    wxString toolchainCPP = toolchain.CPP.Length() ? wxString(toolchain.CPP[0]) : "";
+    const CompilerPrograms& toolchain = pCompiler->GetPrograms();
     // " --query-driver=f:\\usr\\MinGW810_64seh\\**\\g*"
-    wxString queryDriver = masterPath + fileSep + "**" + fileSep + toolchainCPP + "*";
-    if (not platform::windows) queryDriver.Replace("\\","/");
+    wxString queryDriver = masterPath + fileSep + "bin" + fileSep + toolchain.CPP;
 
     wxString pgmExec = clangd_Dir + fileSep + clangdexe;
     QuoteStringIfNeeded(pgmExec);

As per the compiler settings, compiler binary should be present in <compiler path>/bin/ , so above change looks fine.  But I'm afraid it could break some cases achieved by the original logic.  Could you please help? I use Code::Blocks svn trunk on Ubuntu 18.04 wxwidgets 3.0 .

Thanks, Christo



Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6034
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Code completion using LSP and clangd
« Reply #333 on: November 14, 2023, 11:42:36 am »
Update to at least rev 13390.
I think this is already fixed.
Thanks for the report.

I think I still catch a crash bug several minutes ago, see the call stack below, I'm using the latest rev13394.

Code
Error occurred on Tuesday, November 14, 2023 at 18:38:00.

codeblocks.exe caused an Access Violation at location 00007FF8733ED844 in module clangd_client.dll Reading from location FFFFFFFFFFFFFFFF.

AddrPC           Params
00007FF8733ED844 000001B980D42BB0 000001B98611E480 000001B98175AC10  clangd_client.dll!ClassBrowserBuilderThread::AddMembersOf+0x2cc  [D:/code/cbsource/cb_svn_git/src/plugins/contrib/clangd_client/src/codecompletion/classbrowserbuilderthread.cpp @ 921]
00007FF8733EA9DF 000001B980D42BB0 0000000000000000 0000000000000000  clangd_client.dll!ClassBrowserBuilderThread::SelectGUIItem+0x2db  [D:/code/cbsource/cb_svn_git/src/plugins/contrib/clangd_client/src/codecompletion/classbrowserbuilderthread.cpp @ 472]
00007FF8733E999D 000001B980D42BB0 0000000000000001 0000000000000000  clangd_client.dll!ClassBrowserBuilderThread::Entry+0x99  [D:/code/cbsource/cb_svn_git/src/plugins/contrib/clangd_client/src/codecompletion/classbrowserbuilderthread.cpp @ 309]
00007FF876B7CFBD 0000000000000000 000001B980C88330 000001B980D42BB0  wxmsw32u_gcc_cb.dll!wxThreadInternal::DoThreadStart+0x64d
00007FF876B7D113 000001B980C877B0 0000000000000000 000001B980C877B0  wxmsw32u_gcc_cb.dll!wxThreadInternal::WinThreadStart+0x43
00007FF8CC66AF5A 00007FF8CC6C06D0 000001B980C877B0 0000000000000000  msvcrt.dll!_beginthreadex+0x12a
00007FF8CC66B02C 0000000000000000 0000000000000000 0000000000000000  msvcrt.dll!_endthreadex+0xac
00007FF8CC0F7344 0000000000000000 0000000000000000 0000000000000000  KERNEL32.DLL!BaseThreadInitThunk+0x14
00007FF8CD5C26B1 0000000000000000 0000000000000000 0000000000000000  ntdll.dll!RtlUserThreadStart+0x21

EDIT:

The line 921 is at this line:

Code
    if (data)
    {
        switch (data->m_SpecialFolder) // line 921 **************************
        {
            case sfGFuncs  : AddChildrenOf(tree, node, -1, tkFunction, false); break;
            case sfGVars   : AddChildrenOf(tree, node, -1, tkVariable, false); break;
            case sfPreproc : AddChildrenOf(tree, node, -1, tkMacroDef, false); break;
            case sfTypedef : AddChildrenOf(tree, node, -1, tkTypedef,  false); break;
            case sfMacro   : AddChildrenOf(tree, node, -1, tkMacroUse, false); break;
            case sfToken:
            {
« Last Edit: November 14, 2023, 11:44:55 am by ollydbg »
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2808
Re: Code completion using LSP and clangd
« Reply #334 on: November 14, 2023, 07:54:22 pm »
Hi Pecan, I'm using a custom compiler for some projects. It is not recognised by clangd. If I change the code as below, it works fine and standard headers are parsed properly.

Code
Index: src/plugins/contrib/clangd_client/src/LSPclient/client.cpp
===================================================================
--- src/plugins/contrib/clangd_client/src/LSPclient/client.cpp (revision 13394)
+++ src/plugins/contrib/clangd_client/src/LSPclient/client.cpp (working copy)
@@ -427,11 +427,9 @@
     wxString masterPath = pCompiler ? pCompiler->GetMasterPath() : "";
 
     // get the first char of executable name from the compiler toolchain
-    CompilerPrograms toolchain = pCompiler->GetPrograms();
-    wxString toolchainCPP = toolchain.CPP.Length() ? wxString(toolchain.CPP[0]) : "";
+    const CompilerPrograms& toolchain = pCompiler->GetPrograms();
     // " --query-driver=f:\\usr\\MinGW810_64seh\\**\\g*"
-    wxString queryDriver = masterPath + fileSep + "**" + fileSep + toolchainCPP + "*";
-    if (not platform::windows) queryDriver.Replace("\\","/");
+    wxString queryDriver = masterPath + fileSep + "bin" + fileSep + toolchain.CPP;
 
     wxString pgmExec = clangd_Dir + fileSep + clangdexe;
     QuoteStringIfNeeded(pgmExec);

As per the compiler settings, compiler binary should be present in <compiler path>/bin/ , so above change looks fine.  But I'm afraid it could break some cases achieved by the original logic.  Could you please help? I use Code::Blocks svn trunk on Ubuntu 18.04 wxwidgets 3.0 .

Thanks, Christo

OK, I'll investigate. But after I find the reason for a ClassBrowser crash.

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2808
Re: Code completion using LSP and clangd
« Reply #335 on: November 14, 2023, 08:40:44 pm »
@ ollydbg

Are you running with Settings/Editor/Documentation Popup checked or unchecked?

If checked, uncheck it to see if the crashes go away.
I think I've found the cause, but I want to know if I'm in the ballpark.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6034
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Code completion using LSP and clangd
« Reply #336 on: November 14, 2023, 11:35:46 pm »
@ ollydbg

Are you running with Settings/Editor/Documentation Popup checked or unchecked?

If checked, uncheck it to see if the crashes go away.
I think I've found the cause, but I want to know if I'm in the ballpark.

Yes, I have the document popup option on.
I will try to turn it off to see whether such crash happens again.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2808
Re: Code completion using LSP and clangd
« Reply #337 on: November 15, 2023, 01:16:52 am »
@ ollydbg

Would you update to rev 13396 .
I found that LSP_ParseSemanticTokens could modify the TokenTree at the same time ClassBrowserBuildThread() was reading it.

After you run ./update32_64.bat, please copy the Clangd_client dll from Devel32_64 to output32_64 so that if it crashes we'll get the line numbers.

Remember to turn on Settings/Editor/Documentation popup checkbox.

Thanks

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6034
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Code completion using LSP and clangd
« Reply #338 on: November 15, 2023, 03:41:30 am »
@ ollydbg

Would you update to rev 13396 .
I found that LSP_ParseSemanticTokens could modify the TokenTree at the same time ClassBrowserBuildThread() was reading it.

After you run ./update32_64.bat, please copy the Clangd_client dll from Devel32_64 to output32_64 so that if it crashes we'll get the line numbers.

Remember to turn on Settings/Editor/Documentation popup checkbox.

Thanks

Thanks,  I will do it  in a few hours. In fact,  I use C:B as my main development environment,  so I use it every day.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline christo

  • Multiple posting newcomer
  • *
  • Posts: 32
Re: Code completion using LSP and clangd
« Reply #339 on: November 15, 2023, 06:13:25 pm »
OK, I'll investigate. But after I find the reason for a ClassBrowser crash.

Hi Pecan, please ignore issue I raised with query-driver, it happened due to an invalid compiler [YOUR ANSWER IS ALREADY THERE. SEARCH THE FORUMS!]  configuration. On correcting that everything works as expected. Thank you

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2808
Re: Code completion using LSP and clangd
« Reply #340 on: November 15, 2023, 10:14:43 pm »
@ Christo: thanks.

@ olldbg
Sorry to keep you dancing like this but...  8>}
Would you reupdate to rev 13397.

While tracing the crash, I found other code that could cause  re-entry into ClassBrowserBuildThread while it was busy.
This time, it's not a guess; I actually caught it and coded a fix that avoids the double entry.

Remember to copy Clangd_client dll from devel32_64 to output32_64 in case I'm full of (you know what); so that we can get line numbers on crashes.

TLDR:
Every time an editor is activated (happens every time the mouse moves into the text), it calls UpdateClassBrowser(). I should have known this, but my brain is old and rusting. And every 4th time a parser finishes a translation unit it invokes UpdateClassBrowserView(). Those two can happen at the same time. So I've moved busy checks just inside those functions to catch thread "busy" as soon as possible so one doesn't mod the TokenTree while the other is doing its business.

Clangd_client uses TryLocks(250 mil). If the lock fails, it was requeuing an idle time callback for the ClassBrowser update . I've remove these (for the time being) in case they were exacerbating the situation. Code now just skips the update.
I think I'll leave it that way until after the coming release.
There seems to be enough editor activating and background parsing to drive the update.
I haven't found any disadvantage so far.

Thanks !!
« Last Edit: November 15, 2023, 10:45:07 pm by Pecan »

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6034
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Code completion using LSP and clangd
« Reply #341 on: November 16, 2023, 10:09:29 am »
Hi, Pecan, thanks. I appreciate your work on the clangd_client plugin.
I'm using the rev 13397 for about 6 hours, and I haven't see a crash here till now. :)
 
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline omlk

  • Multiple posting newcomer
  • *
  • Posts: 110
Re: Code completion using LSP and clangd
« Reply #342 on: November 16, 2023, 02:15:14 pm »
Hi, Pecan, thanks. I appreciate your work on the clangd_client plugin.
I'm using the rev 13397 for about 6 hours, and I haven't see a crash here till now. :)
I came across the post, and I wonder if you were able to implement what you wrote about?
https://forums.codeblocks.org/index.php?topic=17543.0

And I also wonder how much faster the clang_client works compared to the standard codecompletion (because my codecompletion in some cases does not see the classes, I changed the order of the included header files and disabled others, but there are still problems)?

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2808
Re: Code completion using LSP and clangd
« Reply #343 on: November 16, 2023, 07:20:44 pm »
Hi, Pecan, thanks. I appreciate your work on the clangd_client plugin.
I'm using the rev 13397 for about 6 hours, and I haven't see a crash here till now. :)
I came across the post, and I wonder if you were able to implement what you wrote about?
https://forums.codeblocks.org/index.php?topic=17543.0

And I also wonder how much faster the clang_client works compared to the standard codecompletion (because my codecompletion in some cases does not see the classes, I changed the order of the included header files and disabled others, but there are still problems)?

ollydbg will have to answer your question about COW strings.
It applies to legacy CodeCompletion but not so much to Clangd_Cllient.

Clangd_client only references the TokenTree with a mutex trylock. If it cannot obtain the lock it reschedules access to the TokenTree until it can obtain the lock.

Clangd_client works slightly slower than lagacy CC in that it uses the a Clangd LSP server to do all parsing of translation units (TU). It does no language parsing itself.
Its advantage is that it supports C++ versions as fast as the Clangd LLVM team can release Clangd support for that new C/C++ version.

The  TU information is available to the user, for each activated (referenced) TU, about as fast as your cpu can run the Clangd parser. My Win10 system (an Intel i7/8 core) parses most TUs in 2 seconds or less. Giving Clangd more than 1 core makes for a speedy throughput since that allows Clangd to parse multiple TUs in parallel. I seldom have to wait for info.

For inistallation info see https://wiki.codeblocks.org/index.php/CB_Clangd_Client
« Last Edit: November 16, 2023, 07:42:06 pm by Pecan »

Offline omlk

  • Multiple posting newcomer
  • *
  • Posts: 110
Re: Code completion using LSP and clangd
« Reply #344 on: November 16, 2023, 07:59:27 pm »
The  TU information is available to the user, for each activated (referenced) TU, about as fast as your cpu can run the Clangd parser. My Win10 system (an Intel i7/8 core) parses most TUs in 2 seconds or less. Giving Clangd more than 1 core makes for a speedy throughput since that allows Clangd to parse multiple TUs in parallel. I seldom have to wait for info.
clangd use local network? If that's the case, then clang can't run faster than the native way.
Google gave a result in the search, to what extent do you agree with what is described there about the negative facts of clang use.
https://www.eclipsecon.org/sites/default/files/slides/EclipseCon2018-cpp-lsp_0.pdf