Sarcasm / irony-mode

A C/C++ minor mode for Emacs powered by libclang
GNU General Public License v3.0
907 stars 99 forks source link

irony stops working #218

Open nickenchev opened 9 years ago

nickenchev commented 9 years ago

Hey, I'm finding that irony seems to work properly right after I start up a fresh emacs instance. After using it for a while (not sure what may be triggering this), I stop seeing relevant autocompletion, and start seeing a whole bunch of irrelevant identifiers popping up in my auto completion box. I then have to "irony-server-kill" and "irony-server" to restart, at which point completions starts working properly again.

I'm using cmake to generate compile_commands.json.

Thanks

marcelino-m commented 9 years ago

I have the same issue!!

3246251196 commented 9 years ago

I can confirm that I have seen this issue too. Perhaps if one of us pass in the -d flag to irony it would help - and report the log file next time? I think I will start using -d at work so if I run into a problem I can report the log here.

Sarcasm commented 9 years ago

Yeah @3246251196 is right, I need more material to reproduce/understand the issue. I'm busy with reworking the irony-mode internals right now, so I'm switching to some other issues when they are simple to fix or at least well identified.

marcelino-m commented 9 years ago

Adding the flag directly in the definition of irony--start-server-process is the correct way to do it ??

Sarcasm commented 9 years ago

To add -d yes. But be aware, debugging/understanding this bug will probably need more than that.

nickenchev commented 9 years ago

Hey, off the top of your head, can you think of any reasons why irony would become unresponsive? Seems like the completion becomes sluggish and/or stops working after some use. I've also noticed that completion starts to work better after I switch to another (new) buffer. You're doing an awesome job with irony-mode and I'll definitely continue to use it regardless of hiccups, though really hope we can get to the bottom of this.

Is there a way to provide a in-a-nutshell explanation of how irony requests completions from irony-server?

3246251196 commented 9 years ago

I can add that sometimes I have found a completion window that has all of the non-relevant completions DUE to the fact that there is an error in code.

For example, I was half way through a class's hpp file. I then created a cpp file (forgetting that I had not put the closing braces for the class and namespace). Then I do something like this for the constructor:

SomeNS::SomeNestedNS:: // completions full of garbage.

Perhaps this could be better handled, I do not know. SOmething like - Clang failed to compile - but maybe knowing what the error from clang is is too difficult. I do not know.,

I still can confirm that it does stop working though for unclear reasons.

3246251196 commented 9 years ago

In the context of my setup this list of obscure and non-relevant completions occurs when Clang goes off to do its thing and throws the following in the log file:

debug: complete: 20 diagnostic(s)
d:/development/External/boost_1_57_0\boost/core/addressof.hpp:29:5: error: unknown type name '__forceinline'
d:/development/External/boost_1_57_0\boost/core/addressof.hpp:29:23: error: member 'addr_impl_ref' has the same name as its class
d:/development/External/boost_1_57_0\boost/core/addressof.hpp:29:23: error: constructor cannot have a return type
d:/development/External/boost_1_57_0\boost/core/addressof.hpp:30:5: error: unknown type name '__forceinline'
d:/development/External/boost_1_57_0\boost/core/addressof.hpp:38:12: error: unknown type name '__forceinline'
d:/development/External/boost_1_57_0\boost/core/addressof.hpp:38:31: error: expected ';' at end of declaration list
d:/development/External/boost_1_57_0\boost/core/addressof.hpp:66:12: error: unknown type name '__forceinline'
d:/development/External/boost_1_57_0\boost/core/addressof.hpp:66:31: error: expected ';' at end of declaration list
d:/development/External/boost_1_57_0\boost/core/addressof.hpp:76:12: error: unknown type name '__forceinline'
d:/development/External/boost_1_57_0\boost/core/addressof.hpp:76:31: error: expected ';' at end of declaration list
d:/development/External/boost_1_57_0\boost/core/addressof.hpp:86:12: error: unknown type name '__forceinline'
d:/development/External/boost_1_57_0\boost/core/addressof.hpp:86:31: error: expected ';' at end of declaration list
d:/development/External/boost_1_57_0\boost/core/addressof.hpp:96:12: error: unknown type name '__forceinline'
d:/development/External/boost_1_57_0\boost/core/addressof.hpp:96:31: error: expected ';' at end of declaration list
d:/development/External/boost_1_57_0\boost/core/addressof.hpp:107:1: error: unknown type name '__forceinline'
d:/development/External/boost_1_57_0\boost/core/addressof.hpp:108:2: error: expected ';' at end of declaration
d:/development/External/boost_1_57_0\boost/core/addressof.hpp:108:16: error: unknown type name 'T'
d:/development/External/boost_1_57_0\boost/core/addressof.hpp:108:5: error: C++ requires a type specifier for all declarations
d:/development/External/boost_1_57_0\boost/core/ref.hpp:73:5: error: unknown type name '__forceinline'
fatal error: too many errors emitted, stopping now [-ferror-limit=]

The interesting thing is, if irony-server is stopped and then restarted and I request completion I get all the necessary completions. For example, I do

boost:: // things are fine (AND, the log file does not dump these diagnostic errors),

yet, later on, I can delete that boost:: line and re-do it and all of a sudden the diagnostic errors appear and I do not get completions.

Just some extra information as we try and get to the bottom of this.

(I could, perhaps, try giving a large value to -ferror-limit ... ?)

Sarcasm commented 9 years ago

Can clang compile your code for sure? Does it define __forceinline? The diagnostic looks legit to me. I know Clang is quite capable on Windows but I think (I may be wrong here) that the compile options to specify may be a little tricky to get right. Does your file compile okay with clang (not clang-cl) with the compile options you use?

Apart from that, it's not impossible that irony is doing some shady things, there is this issue https://github.com/Sarcasm/irony-mode/issues/134#issuecomment-68412195 for example.

3246251196 commented 8 years ago

I will look into your questions in the near future.

One thing that would help in this situation: I have noticed that I get all of these non-relevant completion candidates when Clang complains that there is an error in the code. For example, (the classic M-w, C-y error) I copied over a class and renamed the class, but forgot to rename the constructor names in the class. So, when I was changing the return type of a function I noticed all of these non-relevant completion candidates. I opened up the log file and Clang is complaining that it expected the same name as the class for the cons/destructor. But, it is not until I open the log file that I find this information out.... so, is it not possible for irony server to display a message in the mini-buffer or something that says: Clang failed to parse. Or, even, grab the last error and display it from the log file.

I know I am issuing a lot of requests, but this is an awesome tool so I think by commenting often I am helping. I could help even more though by messing with the server and suggesting some patches if I ever get time.

Cheers.

Sarcasm commented 8 years ago

Ok thank you. Regarding the errors that aren't always printed. Do you use flycheck-irony? I think there is one issue, if the issue is in the header file flycheck just filter-them out, which is annoying.

I guess, irony could also print so error information somewhere, until now I relied 100% on flycheck but if you have a suggestion of how to alert the user about issues in the buffer I will be inclined to do it.

3246251196 commented 8 years ago

The best option - for me - would be to print the error text in the mini buffer (semantic/cedet does this I believe). This links in with #249 because not everyone can use flycheck. Flycheck and irony should not be considered coupled products (though they do synergise very well!)

nickenchev commented 8 years ago

How do you pass -d to irony? Let me know what you need me to do in order to get some logs over to you. I've been staying on top of the updates and irony is still doing this. Thanks

3246251196 commented 8 years ago

How do you pass -d to irony? Let me know what you need me to do in order to get some logs over to you. I've been staying on top of the updates and irony is still doing this. Thanks

~/.emacs.d/irony-mode/irony.el

in irony--start-server-process: (setq process (start-process-shell-command "Irony" ;process name irony--server-buffer ;buffer (format "%s -d -i 2> %s"

3246251196 commented 8 years ago

I still have this issue in the back of my mind. I have set up what is needed to be able to attach a gdb session to the running irony process so I can have a closer inspection the next time I get non-relevant completions.

I should maybe compile the clang libraries with debugging information too, but for now I will see what I can do next the issue happens.

nickenchev commented 7 years ago

Hey, I'm not sure why this issue is closed, irony still does this with my projects. It runs fine for a while and over time gets slower, until it just stops responding with completion results. This happens across all of my C++ projects so its not specific to one codebase or another. I'll add the diagnostic flags from a couple of replies up and see if I get anything, better late than never.

The ticket referenced when this issue was close doesn't seem to apply to what I'm talking about here. For me irony-mode works fast on a fresh start, near instant completion results, and just gets slower and slower as I work for an hour or 2. I'm constantly using irony-server-kill and restarting.

Sarcasm commented 7 years ago

Is it an old problem that you have, or is it recent? Are you up to date? Recently there was a big change in the internals.

Do you think it can relates to the memory consumption? irony-server does not get rid of old translation unit, which is not nice w.r.t memory usage.

nickenchev commented 7 years ago

I've been having this issue since at least Jul 2015, which was when I originally logged this issue. No idea whats going on. I actually update quite often and run "irony-install-server" as well to recompile in case of server changes. Not sure if its memory consumption, I can diagnose if you tell me what you'd like for me to check. I'd love to help you fix this as everything else about irony is just perfect. I've added the "-d" directive as the poster above noted, I'm not sure what extra info that spits out and where to actually get it. My assumption was that it would generate another Emacs buffer kinda like Rtags or YCMD, with diagnostic/error information.

Let me know what you'd like for me to do to help you get to the bottom of this.

Sarcasm commented 7 years ago

Hey, I'm not sure why this issue is closed, irony still does this with my projects. It runs fine for a while and over time gets slower, until it just stops responding with completion results.

Hey, to answer this question specifically, this issue has never been closed I think. The auto-reference of Github: https://github.com/Sarcasm/irony-mode/issues/218#ref-issue-205457359 just indicate that the issue that references this one is closed, I get confused by this from time to time as well.

sonictk commented 7 years ago

I'm having the same issue; is there a way to restart the irony server within an Emacs session itself? I can only find the kill command...

4lph4-Ph4un commented 6 years ago

Experiencing the same issue here!

3246251196 commented 6 years ago

What I do is periodically restart the server because at work this is the best thing to do for my set up.

You can run a standard emacs timer and trigger a parse / reparse command to irony. I think I needed to hack together a function to do it. I can provide more information soon.

3246251196 commented 6 years ago

; create some timer - in this case, run after 3 seconds and only do this once for the session - hence the hacky global variable: (setq rjd-irony-reparse-timer 'nil) (defun rjd-should-re-parse () (if (null rjd-irony-reparse-timer) (setq rjd-irony-reparse-timer (run-with-timer 3 120 (lambda() (irony-server-kill) (irony-parse-buffer))))))

; add a hook so that the re-parse function gets called on irony-mode relevant files. (add-hook 'irony-mode-hook 'rjd-should-re-parse)

; i think the only function that is not available is the one I created called irony-parse-buffer which I just threw in irony.el. Sarcasm would have plenty to say about these hacks I imagine, but - for now - they work just fine for me.

(defun irony-parse-buffer () "Parse the current buffer." (interactive) (irony--run-task-asynchronously (irony--parse-task) (lambda (result) ())))