Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

100% CPU usage when there's a symlink to a different disk drive on Linux #7218

Open
sean-mcmanus opened this issue Mar 23, 2021 · 52 comments
Open
Assignees
Milestone

Comments

@sean-mcmanus
Copy link
Contributor

I am experiencing this exact same issue.
What I have also noticed is that when I run htop, I see a single thread of the C/C++ extension constantly at 100% cpu usage. This happens anytime I compile the code and lasts until I close VSCode.

SW Versions:

  • Manjaro 5.10.7
  • VSCode 1.54.3
  • C/C++ 1.2.2

The output window only has a single 'instance' for the C/C++ extension: "C/C++ Configuration Warnings". In this window it seems to be switching between IntelliSense modes willy-nilly. A small excerpt of the logs (in reality it is quite lengthy, but a lot of them are duplicate entries):

[3/23/2021, 3:06:10 PM] For C source files, IntelliSenseMode was changed from "linux-clang-x64" to "linux-gcc-x64" based on compiler args and querying compilerPath: "/usr/bin/gcc"
[3/23/2021, 3:06:10 PM] For C++ source files, IntelliSenseMode was changed from "linux-clang-x64" to "linux-gcc-x64" based on compiler args and querying compilerPath: "/usr/bin/gcc"
[3/23/2021, 3:06:14 PM] For C source files, IntelliSenseMode was changed from "linux-clang-x64" to "linux-gcc-arm" based on compiler args and querying compilerPath: "/usr/bin/arm-none-eabi-gcc"
[3/23/2021, 3:06:14 PM] For C++ source files, IntelliSenseMode was changed from "linux-clang-x64" to "linux-gcc-x64" based on compiler args and querying compilerPath: "/usr/bin/gcc"

If I manually specify for it to use any of these compilerPaths, it will warn about changing to clang (effectively printing the same, but reversed). This doesn't fix the issue however.

Originally posted by @dimitry-boersma in #7197 (comment)

@sean-mcmanus sean-mcmanus self-assigned this Mar 23, 2021
@sean-mcmanus sean-mcmanus added Language Service more info needed The issue report is not actionable in its current state labels Mar 23, 2021
@sean-mcmanus
Copy link
Contributor Author

@dimitry-boersma Which process is using CPU? cpptools or cpptools-srv?

@dimitry-boersma
Copy link

dimitry-boersma commented Mar 23, 2021

The htop mentions ~/.vscode/extensions/ms-vscode.cpptools-1.2.2/bin/cpptools as the command which is running at 100% cpu, so I would guess the first one :)

@sean-mcmanus
Copy link
Contributor Author

Do you see "tag parsing" messages in the C/C++ output pane when you set C_Cpp.loggingLevel to "Debug"? If so, that would be normal CPU usage. Or is there a database icon in the status bar?

@dimitry-boersma
Copy link

It will print these messages until it has finished parsing some files, then it will print Database safe to open, after which, no logs are printed until I open a different file or make changes to the current file. The CPU thread will keep at 100% regardless however.

I am not sure I understand what you mean with a "database icon in the status bar", could you explain that please?

@sean-mcmanus
Copy link
Contributor Author

Hmm, it sounds like it might be stuck in some infinite loop. Can you attach a debugger to cpptools to get a call stack (https://github.com/microsoft/vscode-cpptools/wiki/Attaching-debugger-to-cpptools-or-cpptools%E2%80%90srv)? You can ignore the threads that appear to have small call stacks that are blocked waiting for work.

The database icon is:
image

@dimitry-boersma
Copy link

dimitry-boersma commented Mar 23, 2021

There are quite a few threads, and I'm not quite sure what I am looking for. I did find this thread, which mentions parsing a file. I've pasted the call stack below:

sqlite3BtreeMovetoUnpacked (Unknown Source:0)
sqlite3VdbeExec (Unknown Source:0)
sqlite3_step (Unknown Source:0)
code_store::a_statement::step(bool) (Unknown Source:0)
code_store::a_results_statement<code_store::a_full_code_items_set, code_store::schema::code_items::a_read_statement, code_store::full_code_items_set>::move_next() (Unknown Source:0)
browse_engine::query_cik_in_file(code_store::a_code_item_kind, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<code_store::a_full_code_item_record, std::allocator<code_store::a_full_code_item_record> >&) (Unknown Source:0)
browse_engine::parse_file(unsigned long, char const*, code_store::a_record_id<code_store::a_file_tag> const&, std::unordered_set<code_store::a_record_id<code_store::a_file_tag>, std::hash<code_store::a_record_id<code_store::a_file_tag> >, std::equal_to<code_store::a_record_id<code_store::a_file_tag> >, std::allocator<code_store::a_record_id<code_store::a_file_tag> > >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, parser&, std::function<void ()>, std::shared_ptr<include_paths>, bool) (Unknown Source:0)
browse_engine::parse_file(unsigned long, char const*, bool, std::function<void ()>, std::shared_ptr<include_paths>, bool) (Unknown Source:0)
vscode::message_handler::parse_file(unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, std::function<void ()>, std::shared_ptr<vscode::message_handler::optional_parse_file_args>) (Unknown Source:0)
std::_Function_handler<void (), vscode::message_handler::main_loop()::$_9>::_M_invoke(std::_Any_data const&) (Unknown Source:0)
execute_native_thread_routine (Unknown Source:0)
libpthread.so.0!start_thread (Unknown Source:0)
libc.so.6!clone (Unknown Source:0)

All of the other threads seem to be in a waiting state, as you mentioned. These threads all end on a lib call (in a few different forms)

I indeed see that database icon in the status bar

@sean-mcmanus
Copy link
Contributor Author

That call stack appears to be normal parsing (from an open file...if you don't open a file you shouldn't get that call stack...i.e. is the CPU usage issue only after you open a file?). If the database icon is there what does it show when you hover over it? It looks like it's still trying to parse stuff in the workspace.

@dimitry-boersma
Copy link

When I hover over the database icon I see the popup "Parsing open files". I've tried pausing/playing the debugger a little and I do seem to get a different call stack for the thread I mentioned, so it might not necessarily be stuck on a single statement. Are you aware if it is possible to find the Process ID for the threads found in the call stack so I can make sure I am looking at the right one? I am able to identify the Process ID of the 100% CPU thread in htop.

@dimitry-boersma
Copy link

dimitry-boersma commented Mar 23, 2021

Perhaps interesting to note is that the following subset of the call stack seems to be persistent:

browse_engine::parse_file(unsigned long, char const*, code_store::a_record_id<code_store::a_file_tag> const&, std::unordered_set<code_store::a_record_id<code_store::a_file_tag>, std::hash<code_store::a_record_id<code_store::a_file_tag> >, std::equal_to<code_store::a_record_id<code_store::a_file_tag> >, std::allocator<code_store::a_record_id<code_store::a_file_tag> > >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, parser&, std::function<void ()>, std::shared_ptr<include_paths>, bool) (Unknown Source:0)
browse_engine::parse_file(unsigned long, char const*, bool, std::function<void ()>, std::shared_ptr<include_paths>, bool) (Unknown Source:0)
vscode::message_handler::parse_file(unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, std::function<void ()>, std::shared_ptr<vscode::message_handler::optional_parse_file_args>) (Unknown Source:0)
std::_Function_handler<void (), vscode::message_handler::main_loop()::$_9>::_M_invoke(std::_Any_data const&) (Unknown Source:0)
execute_native_thread_routine (Unknown Source:0)
libpthread.so.0!start_thread (Unknown Source:0)
libc.so.6!clone (Unknown Source:0)

The calls below this level update every time I play/pause the debugger

@sean-mcmanus
Copy link
Contributor Author

Yeah, it seems like it's parsing the include dependencies from the open file...I would assume you would see "tag parsing" messages for those?

@dimitry-boersma
Copy link

I'm not sure how to answer your question, where should I look for these "tag parsing" messages?

@sean-mcmanus
Copy link
Contributor Author

The "C/C++" pane in the Output window is expected to show those (with C_Cpp.loggingLevel set to "Debug").

@dimitry-boersma
Copy link

dimitry-boersma commented Mar 25, 2021

I don't see those, the only related thing I could find was:
IntelliSense client not available, using Tag Parser for quick info.

Edit: for clarification, I have set "C_Cpp.loggingLevel": "Debug", in my settings.json

@sean-mcmanus
Copy link
Contributor Author

sean-mcmanus commented Mar 25, 2021

Hmm, that code hasn't changed in a long time and is not known to have any infinite loop issues. One thing you could try is to remove all the recursive includes "**" from your includePath to see if that fixes your issue, since that'll cause the parse_file to execute a different code path that might not have the bug. You could also try temporarily setting the C_Cpp.loggingLevel to the hidden value of "7" and see if it gives more info on what it is trying to parse, e.g. "resolving include" messages.

It's possible that something is unusual with your database. You may want to try using the C/C++: Reset IntelliSense Database command. Or if this issue only repros when opening a particular file there could be something special in that file that is causing our code to loop incorrectly as it tries to parse the dependent include files. Are you able to provide any sample repro code that exhibits the bug?

If there's no "tag parsing" messages, that implies that the files are already parsed, in which case, it's expected that it shouldn't take that long to finish, since it's basically just checking the database for the include files it needs to parse for dependencies.

@dimitry-boersma
Copy link

If I put the logging level to 7, I do see some "tag parsing file: " messages passing by. Though most of them are followed by thousands of lines (nearly 10 thousand in fact) containing "update_file_if_needed:", not sure if that is intended?

@sean-mcmanus
Copy link
Contributor Author

10k update_file_if_needed messages would mean those header files were potentially being used by the opened file or its dependencies so it checked if needed to be tag parsed, but determined that it did not. Do the update_file_if_needed files appear to be valid headers? It's not processing the same files repeatedly or it hasn't been searching in some invalid place, right?

@dimitry-boersma
Copy link

It doesn't appear to repeatedly be processing the same files, nor do the paths look incorrect to me. I don't think it is trying to parse invalid headers either

@sean-mcmanus
Copy link
Contributor Author

Do you have any guess why it's taking so long to finish?

@dimitry-boersma
Copy link

Perhaps it is the sheer volume of files that it is trying to weed through? Combine that with the fact that it will check for updates on all of the dependencies for each edit or context (window) change, I think it would have a lot of processing to do.

I have noticed that sometimes it will actually finish its processing, though I'm not sure how to reproduce that scenario

@plafer
Copy link

plafer commented Apr 13, 2021

I'm having a similar issue when loading the mediapipe project. After I build it once in a VSCode terminal (e.g. bazel build -c opt --define MEDIAPIPE_DISABLE_GPU=1 mediapipe/examples/desktop/hand_tracking:hand_tracking_cpu as described here), ~/.vscode/extensions/ms-vscode.cpptools-1.3.0-insiders5/bin/cpptools is stuck at 100% cpu, even after the build is done.

Hope this helps somehow.

@sean-mcmanus
Copy link
Contributor Author

@plafer When you set C_Cpp.loggingLevel to "Debug" what does it show in the "C/C++" output? You may want to add a folder to files.exclude or C_Cpp.files.exclude if it's showing tag parsing messages for files that don't need to be parsed. Otherwise, are you able to get a call stack (https://github.com/microsoft/vscode-cpptools/wiki/Attaching-debugger-to-cpptools-or-cpptools%E2%80%90srv) or perf logs (https://github.com/microsoft/vscode-cpptools/wiki/Troubleshooting-Performance-Issues).

@plafer
Copy link

plafer commented Apr 15, 2021

I was not able to make gdb attach work from inside VS Code, so I did it in a terminal. The call stack I got was:

#0 __GI___libc_read (nbytes=4096, buf=0x3093a10, fd=0) at ../sysdeps/unix/sysv/linux/read.c:26
#1 __GI___libc_read (fd=0, buf=0x3093a10, nbytes=4096) at ../sysdeps/unix/sysv/linux/read.c:24
#2 0x00007f6b7913ad1f in _IO_new_file_underflow (fp=0x7f6b79292980 <IO_2_1_stdin>) at libioP.h:948
#3 0x00007f6b7913c106 in __GI__IO_default_uflow (fp=0x7f6b79292980 <IO_2_1_stdin>) at libioP.h:948
#4 0x00007f6b79135678 in _IO_getc (fp=0x7f6b79292980 <IO_2_1_stdin>) at getc.c:38
#5 0x0000000000ec90cd in __gnu_cxx::stdio_sync_filebuf<char, std::char_traits >::underflow() ()
#6 0x0000000000e8c9ba in std::basic_istream<char, std::char_traits >& std::getline<char, std::char_traits, std::allocator >(std::basic_istream<char, std::char_traits >&, std::__cxx11::basic_string<char, std::char_traits, std::allocator >&, char) ()
#7 0x000000000072677c in vscode::message_handler::main_loop() ()
#8 0x0000000000721f38 in main ()

I ran it a couple of times, and it's always stuck in the same place.

I also noticed that there were 2 copies of ~/.vscode/extensions/ms-vscode.cpptools-1.3.0-insiders5/bin/cpptools running. Not sure if that's expected.

@sean-mcmanus
Copy link
Contributor Author

That call stack is just the main loop waiting for input. Can you look for a call stack in other threads? The call stack would probably be deeper than all the others and not blocked by a mutex or read operation (at least not usually).

@plafer
Copy link

plafer commented Apr 17, 2021

I inspected the call stack a few times for a different thread. Hopefully that gives you enough information.

First time

#0 0x00000000008bb8ba in btreeParseCellPtr ()
#1 0x00000000008dc098 in sqlite3BtreeMovetoUnpacked ()
#2 0x00000000008e0b7c in handleDeferredMoveto ()
#3 0x00000000008d076d in sqlite3VdbeExec ()
#4 0x000000000089716f in sqlite3_step ()
#5 0x0000000000860ec0 in code_store::a_statement::step(bool) ()
#6 0x00000000008748df in code_store::a_results_statement<code_store::a_full_code_items_set, code_store::schema::code_items::a_read_statement, code_store::full_code_items_set>::move_next() ()
#7 0x00000000007f85ab in browse_engine::query_cik_in_file(code_store::a_code_item_kind, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, std::vector<code_store::a_full_code_item_record, std::allocator<code_store::a_full_code_item_record> >&)
()
#8 0x00000000007f0eb2 in browse_engine::parse_file(unsigned long, char const*, code_store::a_record_id<code_store::a_file_tag> const&, std::unordered_set<code_store::a_record_id<code_store::a_file_tag>, std::hash<code_store::a_record_id<code_store::a_file_tag> >, std::equal_to<code_store::a_record_id<code_store::a_file_tag> >, std::allocator<code_store::a_record_id<code_store::a_file_tag> > >&, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, std::set<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::less<std::__cxx11::basic_string<char, std::char_traits, std::allocator > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > > const&, parser&, std::function<void ()>, std::shared_ptr<include_paths>, bool) ()
#9 0x00000000007f6f41 in browse_engine::parse_file(unsigned long, char const*, bool, std::function<void ()>, std::shared_ptr<include_paths>, bool) ()
#10 0x00000000007642af in vscode::message_handler::parse_file(unsigned long, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, bool, std::function<void ()>, std::shared_ptrvscode::message_handler::optional_parse_file_args) ()
#11 0x000000000077d12d in std::_Function_handler<void (), vscode::message_handler::main_loop()::$_10>::_M_invoke(std::_Any_data const&) ()
#12 0x0000000000f0abb0 in execute_native_thread_routine ()
#13 0x00007f307a0ea609 in start_thread (arg=) at pthread_create.c:477
#14 0x00007f307a011293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Second time

0x0000000000896180 in sqlite3VdbeMemSetStr ()
(gdb) bt
#0 0x0000000000896180 in sqlite3VdbeMemSetStr ()
#1 0x0000000000916035 in sqlite3Select ()
#2 0x00000000008facd9 in yy_reduce ()
#3 0x00000000008a3a00 in sqlite3RunParser ()
#4 0x00000000008a0d74 in sqlite3LockAndPrepare ()
#5 0x00000000008a204c in sqlite3_prepare_v3 ()
#6 0x000000000083abc0 in code_store::a_statement::prepare(code_store::a_connection&, char const*, bool) ()
#7 0x000000000087273e in code_store::a_results_statement<code_store::a_files_set, code_store::schema::files::a_read_statement, code_store::files_set>::open(std::shared_ptr<code_store::a_store::a_thread_impl>, std::__cxx11::basic_stringstream<char, std::char_traits, std::allocator > const&) ()
#8 0x000000000085f914 in code_store::a_results_statement<code_store::a_files_set, code_store::schema::files::a_read_statement, code_store::files_set>::create_statement(std::shared_ptr<code_store::a_store::a_thread_impl>, std::__cxx11::basic_stringstream<char, std::char_traits, std::allocator >&, std::shared_ptr<code_store::files_set>&) ()
#9 0x0000000000846392 in code_store::a_store::get_files(code_store::a_query_filter<code_store::a_record_id<code_store::a_config_tag> >, code_store::a_query_filter<code_store::a_record_id<code_store::a_file_tag> >, char const*, code_store::a_query_option, code_store::a_file_order, std::shared_ptr<code_store::files_set>&) ()
#10 0x00000000008011d2 in browse_engine::query_include_files(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, std::vector<code_store::a_file_record, std::allocator<code_store::a_file_record> >&) ()
#11 0x00000000007ff3bd in browse_engine::query_include_path_suggestions_impl(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, std::set<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::less<std::__cxx11::basic_string<char, std::char_traits, std::allocator > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > >&, bool, std::map<code_store::a_record_id<code_store::a_file_tag>, std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::less<code_store::a_record_id<code_store::a_file_tag> >, std::allocator<std::pair<code_store::a_record_id<code_store::a_file_tag> const, std::__cxx11::basic_string<char, std::char_traits, std::allocator > > > >) ()
#12 0x00000000007f20e9 in browse_engine::parse_file(unsigned long, char const
, code_store::a_record_id<code_store::a_file_tag> const&, std::unordered_set<code_store::a_record_id<code_store::a_file_tag>, std::hash<code_store::a_record_id<code_store::a_file_tag> >, std::equal_to<code_store::a_record_id<code_store::a_file_tag> >, std::allocator<code_store::a_record_id<code_store::a_file_tag> > >&, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, std::set<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::less<std::__cxx11::basic_string<char, std::char_traits, std::allocator > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > > const&, parser&, std::function<void ()>, std::shared_ptr<include_paths>, bool) ()
#13 0x00000000007f6f41 in browse_engine::parse_file(unsigned long, char const*, bool, std::function<void ()>, std::shared_ptr<include_paths>, bool) ()
#14 0x00000000007642af in vscode::message_handler::parse_file(unsigned long, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, bool, std::function<void ()>, std::shared_ptrvscode::message_handler::optional_parse_file_args) ()
#15 0x000000000077d12d in std::_Function_handler<void (), vscode::message_handler::main_loop()::$_10>::_M_invoke(std::_Any_data const&) ()
#16 0x0000000000f0abb0 in execute_native_thread_routine ()
#17 0x00007f307a0ea609 in start_thread (arg=) at pthread_create.c:477
#18 0x00007f307a011293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Third time

#0 0x00000000008facc0 in yy_reduce ()
#1 0x00000000008a3a00 in sqlite3RunParser ()
#2 0x00000000008a0d74 in sqlite3LockAndPrepare ()
#3 0x00000000008a204c in sqlite3_prepare_v3 ()
#4 0x000000000083abc0 in code_store::a_statement::prepare(code_store::a_connection&, char const*, bool) ()
#5 0x000000000087273e in code_store::a_results_statement<code_store::a_files_set, code_store::schema::files::a_read_statement, code_store::files_set>::open(std::shared_ptr<code_store::a_store::a_thread_impl>, std::__cxx11::basic_stringstream<char, std::char_traits, std::allocator > const&) ()
#6 0x000000000085f914 in code_store::a_results_statement<code_store::a_files_set, code_store::schema::files::a_read_statement, code_store::files_set>::create_statement(std::shared_ptr<code_store::a_store::a_thread_impl>, std::__cxx11::basic_stringstream<char, std::char_traits, std::allocator >&, std::shared_ptr<code_store::files_set>&) ()
#7 0x0000000000846392 in code_store::a_store::get_files(code_store::a_query_filter<code_store::a_record_id<code_store::a_config_tag> >, code_store::a_query_filter<code_store::a_record_id<code_store::a_file_tag> >, char const*, code_store::a_query_option, code_store::a_file_order, std::shared_ptr<code_store::files_set>&) ()
#8 0x00000000008011d2 in browse_engine::query_include_files(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, std::vector<code_store::a_file_record, std::allocator<code_store::a_file_record> >&) ()
#9 0x00000000007ff3bd in browse_engine::query_include_path_suggestions_impl(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, std::set<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::less<std::__cxx11::basic_string<char, std::char_traits, std::allocator > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > >&, bool, std::map<code_store::a_record_id<code_store::a_file_tag>, std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::less<code_store::a_record_id<code_store::a_file_tag> >, std::allocator<std::pair<code_store::a_record_id<code_store::a_file_tag> const, std::__cxx11::basic_string<char, std::char_traits, std::allocator > > > >) ()
#10 0x00000000007f20e9 in browse_engine::parse_file(unsigned long, char const
, code_store::a_record_id<code_store::a_file_tag> const&, std::unordered_set<code_store::a_record_id<code_store::a_file_tag>, std::hash<code_store::a_record_id<code_store::a_file_tag> >, std::equal_to<code_store::a_record_id<code_store::a_file_tag> >, std::allocator<code_store::a_record_id<code_store::a_file_tag> > >&, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, std::set<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::less<std::__cxx11::basic_string<char, std::char_traits, std::allocator > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > > const&, parser&, std::function<void ()>, std::shared_ptr<include_paths>, bool) ()
#11 0x00000000007f6f41 in browse_engine::parse_file(unsigned long, char const*, bool, std::function<void ()>, std::shared_ptr<include_paths>, bool) ()
#12 0x00000000007642af in vscode::message_handler::parse_file(unsigned long, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, bool, std::function<void ()>, std::shared_ptrvscode::message_handler::optional_parse_file_args) ()
#13 0x000000000077d12d in std::_Function_handler<void (), vscode::message_handler::main_loop()::$_10>::_M_invoke(std::_Any_data const&) ()
#14 0x0000000000f0abb0 in execute_native_thread_routine ()
#15 0x00007f307a0ea609 in start_thread (arg=) at pthread_create.c:477
#16 0x00007f307a011293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Fourth time

_int_free (av=0x7f302c000020, p=0x7f2ff3198c80, have_lock=0) at malloc.c:4220
4220 malloc.c: No such file or directory.
(gdb) bt
#0 _int_free (av=0x7f302c000020, p=0x7f2ff3198c80, have_lock=0) at malloc.c:4220
#1 0x0000000000800035 in browse_engine::query_include_path_suggestions_impl(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, std::set<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::less<std::__cxx11::basic_string<char, std::char_traits, std::allocator > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > >&, bool, std::map<code_store::a_record_id<code_store::a_file_tag>, std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::less<code_store::a_record_id<code_store::a_file_tag> >, std::allocator<std::pair<code_store::a_record_id<code_store::a_file_tag> const, std::__cxx11::basic_string<char, std::char_traits, std::allocator > > > >) ()
#2 0x00000000007f20e9 in browse_engine::parse_file(unsigned long, char const
, code_store::a_record_id<code_store::a_file_tag> const&, std::unordered_set<code_store::a_record_id<code_store::a_file_tag>, std::hash<code_store::a_record_id<code_store::a_file_tag> >, std::equal_to<code_store::a_record_id<code_store::a_file_tag> >, std::allocator<code_store::a_record_id<code_store::a_file_tag> > >&, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, std::set<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, std::less<std::__cxx11::basic_string<char, std::char_traits, std::allocator > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits, std::allocator > > > const&, parser&, std::function<void ()>, std::shared_ptr<include_paths>, bool) ()
#3 0x00000000007f6f41 in browse_engine::parse_file(unsigned long, char const*, bool, std::function<void ()>, std::shared_ptr<include_paths>, bool) ()
#4 0x00000000007642af in vscode::message_handler::parse_file(unsigned long, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, bool, std::function<void ()>, std::shared_ptrvscode::message_handler::optional_parse_file_args) ()
#5 0x000000000077d12d in std::_Function_handler<void (), vscode::message_handler::main_loop()::$_10>::_M_invoke(std::_Any_data const&) ()
#6 0x0000000000f0abb0 in execute_native_thread_routine ()
#7 0x00007f307a0ea609 in start_thread (arg=) at pthread_create.c:477
#8 0x00007f307a011293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

@sean-mcmanus
Copy link
Contributor Author

@plafer That looks like normal behavior. It appears to searching the #include dependencies for files to parse for global symbols. Do you see "tag parsing" messages in the C/C++ logging with C_Cpp.loggingLevel set to "Debug"? Does this CPU usage occur if no file is opened? After opening a file, does it eventually stop that processing? This code hasn't changed in a long time so infinite processing would not be expected. Are you using any recursive includes, i.e. include paths that end with "**? If you do, that can cause a different code path to be executed. You may want to try doing a C/C++: Reset IntelliSense Database in case there's some issue with your database.

@plafer
Copy link

plafer commented Apr 20, 2021

You're right! I was getting was a bunch of tag parsing messages of the many protobuf generated files that MediaPipe generates. I reset my Intellisense cache, it reparsed everything, and eventually stopped. Maybe my database was corrupted before the reset?

Thanks for the help!

EDIT: Actually I get the same problem again when opening files that their dependencies were not compiled. C/C++ output shows no new output. I built those dependencies, which made the include errors disappear. However there's still one last issue which Intellisense returns as an error (A line similar to std::wstring = "some_str";), but somehow when I run the file with Bazel, it runs fine, which makes me suspect Bazel uses different compiler settings than Intellisense. I don't have time to investigate now, but I'll try to investigate more in the next few days. To reproduce, download mediapipe, and view the file mediapipe/calculators/core/side_packet_to_stream_calculator_test.cc. If nothing happens, try running bazel run --define MEDIAPIPE_DISABLE_GPU=1 mediapipe/examples/desktop/hello_world:hello_world in any shell from the root of the mediapipe directory.

@davidwin
Copy link

davidwin commented Jun 3, 2021

I have also seen this high CPU usage in cpptools for some time now, and it's still there in 1.4.0. I can't say what triggers it, but I don't need to have any source files open for it to happen, and it doesn't even happen on all projects. This can go on for days, but also only for a couple of minutes. Killing the process causes a new to be restarted, which will often lock up that too.
I don't have a stack dump yet, but strace shows that the process isn't doing any I/O besides reading from an IPC socket every second (this is on Remote SSH on a Linux host).

@inaciose
Copy link

After a recent update I also got this high cpu usage every time vscode start.
After a few minutes its stop.

@BillDenton
Copy link

BillDenton commented Jun 24, 2021

I'm also seeing a whole core being used by the c/c++ extension. I've had this problem for a long time. Sometimes it stops but then it seems to come back. My .vscode\c_cpp_properties.json is:

{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${default}",
                "${workspaceFolder}/**"
            ],
            "windowsSdkVersion": "10.0.17134.0",
            "compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/Tools/MSVC/14.15.26726/bin/Hostx64/x64/cl.exe",
            "defines": [
                <removed 9 lines of "DEFINE" as proprietary>
            ],
            "cStandard": "c99",
            "cppStandard": "c++03"
        }
    ],
    "version": 4
}

With:

            "includePath": [
                "${default}",
                "${workspaceFolder}/**"
            ],

my symbol lookup nearly always works. This is a very large project folder.

@sean-mcmanus
Copy link
Contributor Author

@BillDenton Have you tried adding folders to files.exclude or C_Cpp.files.exclude? We fixed directory iteration so that subdirectories of excluded folders won't be iterated over, which I assumed would fix your issue.

@jeannekamikaze
Copy link

One thing that appears to cause 100% cpu usage forever with cpptools is graph cycles by means of soft links. This is the setup that reproduces the issue for me:

  1. Two physicsl disks on the system, one where /home is, and another at /mnt/disk2. My source is physically at /mnt/disk2/src, but I link from /home to it with ln -s /mnt/disk2/src /home/user/src. (Main disk is small, so I put the source on the larger disk2.)
  2. Within src/, there are some internal soft links. For example, src/foo/bar links to src/bar.

Now, open vscode, select File -> Open Folder, and open /home/user/src (the soft link). Then, open any c/c++ file to trigger cpptools, and watch it "Discovering files 1237128931236" to infinity consuming 100% cpu usage.

It almost looks like cpptools follows soft links in loops with no cycle detection.

To address the problem on my setup, I undid part (1) above. i.e. I just moved /mnt/disk2/src physically to /home/user/src.

@BillDenton
Copy link

BillDenton commented Jun 27, 2021

@sean-mcmanus I've added a few (4) top-level folders to the exclude in "C_Cpp.files.exclude". As soon as a added one or two folders (which didn't contain that many files) the CPU load dropped to negligible. So it seems that there is an upper limit after which it falls over. I'll give it a few days until I believe this has resolved it.

Update: Next day. After resuming from hibernating all was OK. Then updating files (git merge of latest code into my development branch) and build, the C/C++ extension went back to using a whole core. Not sure exactly when it started. It seems that there is something that triggers it other than just the number of files/directories. The developer reload window makes no difference. I guess that doesn't affect the extensions. Restarting VS Code gives a high load (one core) for a short while followed by 0% of the extension (note: I haven't started editing, building, reference searching etc since the restart).

Second update: After a few edits the extension was back to using a core. Restarting VS Code fixed it. After the restart, a few edits and another build was OK. ~~Then a bit later after another edit and build it was back to using a whole core. ~~ (Update: It went quickly back to 0%. I didn't notice because the laptop fans were noisy, which is usually the first sign that is using a core all the time.)
As it isn't there all the time, it the number of directories or is there something else triggering it?

All our header files are stored in directories ending in one of two names. Is there any way I can restrict the header include search to any directory path ending in one of those two words?

Probably an unrelated problem:
query_goto_def: looking for symbol ''
[rc=0x80640065] (code_store::a_store::get_code_item) SQLite Error 1: SQL logic error: not an error
SQL text: SELECT id, file_id, parent_id, kind, attributes, name, type, start_column, start_line, end_column, end_line, name_start_column, name_start_line, name_end_column, name_end_line, param_default_value, param_default_value_start_column, param_default_value_start_line, param_default_value_end_column, param_default_value_end_line, param_number FROM code_items WHERE id = ?1 LIMIT 1

query_goto_def: looking for symbol ''
$/cancelRequest: 1068
[rc=0x80640065] (code_store::a_store::get_code_item) SQLite Error 1: SQL logic error: not an error
SQL text: SELECT id, file_id, parent_id, kind, attributes, name, type, start_column, start_line, end_column, end_line, name_start_column, name_start_line, name_end_column, name_end_line, param_default_value, param_default_value_start_column, param_default_value_start_line, param_default_value_end_column, param_default_value_end_line, param_number FROM code_items WHERE id = ?1 LIMIT 1

@sean-mcmanus
Copy link
Contributor Author

sean-mcmanus commented Jun 28, 2021

@jeannekamikaze Are you using 1.4.1 or 1.5.0-insiders2? I'm not reproing that issue using the symlink structure described, but I'm only using 1 disk. Does it repro for you if you use only 1 disk? If it requires 2 disks, it could have the same root cause as #7701 . Our directory iteration code has cycle detection in regards to symlinks, but there might be some special case that isn't handled correctly. @Colengms Are you able to repro the issue?

@BillDenton Using one core might be expected if it's responding to workspace updates, but it should eventually go to 0 CPU. Are you able to tell what processing is occurring from the logging or call stacks? It sounds like it might be iterating through the workspace to look for files to reparse. Our includePath and browse.path settings don't support wildcards yet -- it's being tracked by #723 . The log message "query_goto_def: looking for symbol" should only appear with the hidden logging level of 7 or higher (which should only be used temporarily since it could impact performance), but the output of symbol '' should be impossible (@Colengms right?), because all code paths exit out if the symbol string is empty...it should only appear after doing a go to def or hover -- it would be unrelated to the CPU usage if you don't hover or go to def (and therefore don't see the that logging). I'm not sure what "SQL logic error: not an error" means, I assume it's being caused by the empty '' being searched for.

@BillDenton
Copy link

BillDenton commented Jun 28, 2021

@sean-mcmanus I did put the debug level 7 after seeing earlier in the issue. I'll put it back to debug.

I'm not sure what loading has been like today, but I think it has been better. I don't usually notice until the laptop fans go made. I sounds like it will get a lot better once #723 is done.

Sorry, it wasn't a symbol ''. I had removed the symbol and put < removed or something similar >. That didn't come out in the issue report.

@jeannekamikaze
Copy link

@sean-mcmanus I have 1.5.0-insiders2. I don't see any issues with soft links within the save physical drive, so it must be the 2-disk setup. I also don't have LVM or anything that hides the physical disks from applications.

@sean-mcmanus sean-mcmanus removed the more info needed The issue report is not actionable in its current state label Jun 29, 2021
@sean-mcmanus sean-mcmanus added this to the 1.5.0 milestone Jun 29, 2021
@sean-mcmanus
Copy link
Contributor Author

@jeannekamikaze Thanks for the info.

@Colengms This sounds like it might have the same root cause as the 2 disk issue you're investigating.

@sean-mcmanus sean-mcmanus changed the title 100% CPU usage 100% CPU usage when there's a symlink to a different disk drive on Linux Jun 29, 2021
@jeannekamikaze
Copy link

No problem @sean-mcmanus.

Also, not to digress too much here, but my original quest was to get the extension to run on vscodium, which appears to be impossible as described here due to 1) A licensing issue and 2) A technical issue with the telemetry refusing to run outside of vscode.

Is there any chance you guys can address the above as well?

Thank you.

@sean-mcmanus
Copy link
Contributor Author

@jeannekamikaze We don't intend to address running in vscodium...we had an issue tracking that, but I believe it got Won't Fixed.

@sean-mcmanus
Copy link
Contributor Author

@jeannekamikaze Sounds like you may be hitting #7701 with /D or /I paths.

@sean-mcmanus
Copy link
Contributor Author

sean-mcmanus commented Jul 8, 2021

Is anyone still hitting this issue with https://github.com/microsoft/vscode-cpptools/releases/tag/1.5.1 ?

@antonsavin
Copy link

I experience it with 1.5.1. Had a workspace with one of the projects symlinked to another disk, and cpptoolls memory usage went through the roof (like, 25G), up to a point when processes started getting killed. Removed it, and memory usage dropped.

@einarjon
Copy link

2 discoveries here:

  1. A lot of this seems to be caused by ripgrep search indexing. Setting the "search.followSymlinks": false made my CPU load/disk use drop to acceptable levels. Maybe ripgrep needs a feature to detect and not follow circular symlinks.
  2. For those using remote-SSH, a PR was merged yesterday to move the server folder to any location. It should be in the current remote SSH nightly

@sean-mcmanus sean-mcmanus removed this from the 1.5.0 milestone Mar 23, 2022
@bobbrow bobbrow added this to the Backlog milestone Apr 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests