Sarcasm / irony-mode

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

Random crashes with "Selecting deleted buffer" #332

Closed cbourjau closed 7 years ago

cbourjau commented 7 years ago

Hello, since a few days I am experiencing random crashes of Irony/Flyspell, i.e., FlyC becomes FlyC* in the mode line. I already miss Irony dearly but am not sure on how to debug this further.

The issue

The error appears seemingly at random. Sometimes, I can work for a few minutes, sometimes it crashes immediately including the use of company-completion. I think that the crashes occur when irony tries to auto-complete something. E.g., after typing std and waiting for a moment, a crash might occur.

After enabling toggle-debug-on-error I get the following backtrace (strings with special characters are replaced by "..." for formatting):

Debugger entered--Lisp error: (error "Selecting deleted buffer")
  irony-diagnostics--request-handler(t #[385 "..." [irony #[128 "..." [[cl-struct-flycheck-syntax-check #<killed buffer> irony nil] apply flycheck-report-buffer-checker-status] 5 "\n\n(fn &rest ARGS)"] #<killed buffer> error errored cancelled finished nil success mapcar make-byte-code 257 "..." vconcat vector [flycheck-irony--build-error] 5 "\n\n(fn DIAGNOSTIC)" delq] 11 "\n\n(fn STATUS &rest ARGS)"] #<killed buffer>)
  apply(irony-diagnostics--request-handler t (#[385 "..." [irony #[128 "..." [[cl-struct-flycheck-syntax-check #<killed buffer> irony nil] apply flycheck-report-buffer-checker-status] 5 "\n\n(fn &rest ARGS)"] #<killed buffer> error errored cancelled finished nil success mapcar make-byte-code 257 "..." vconcat vector [flycheck-irony--build-error] 5 "\n\n(fn DIAGNOSTIC)" delq] 11 "\n\n(fn STATUS &rest ARGS)"] #<killed buffer>))
  byte-code("..." [callback sexp apply] 4)
  irony--process-server-response(#<process Irony> "t\n\n;;EOT\n")
  #[(r) "..." [process r irony--process-server-response] 3]("t\n\n;;EOT\n")
  mapc(#[(r) "..." [process r irony--process-server-response] 3] ("t\n\n;;EOT\n"))
  irony--server-process-filter(#<process Irony> "t\n\n;;EOT\n")

System information

As I said, it seems like this issue started a few days ago, which makes me wonder if it is related to some updates. I am currently on:

Again, I am happy to provide more diagnostics but am unsure where and how to start about debugging this.

Thank you very much for this awesome tool and thanks for any help in advance! Cheers, Christian

Sarcasm commented 7 years ago

Ok,

So I have no clue for now about what is going on. You are using melpa stable for irony, right? So recent change in irony did not produce this, right?

I would start by doing the following:

After ensuring none of this change anything to your issue, I think one should look into the buffer argument in flycheck-irony--start, if I understand correctly, this is the buffer that ends up being killed.

You could evaluate the following function with C-x e in your *scratch* buffer, then check the messages when the error appear (C-h e to check *Messages*):


(progn
  (setq-local lexical-binding t)
  (defun flycheck-irony--start (checker callback)
    (let ((buffer (current-buffer)))
      (message "flycheck-irony--start: buffer:%S" buffer)
      (irony-diagnostics-async
       #'(lambda (status &rest args) ;; closure, lexically bound
           (message "flycheck-irony--start (lambda): buffer:%S" buffer)
           (pcase status
             (`error (funcall callback 'errored (car args)))
             (`cancelled (funcall callback 'finished nil))
             (`success
              (let* ((diagnostics (car args))
                     (errors (mapcar #'(lambda (diagnostic)
                                         (flycheck-irony--build-error checker buffer diagnostic))
                                     diagnostics)))
                (funcall callback 'finished (delq nil errors)))))))))
)

If you have an error, try this slightly changed version, which seems to be more slightly more correct:

(progn
  (setq-local lexical-binding t)
  (defun flycheck-irony--start (checker callback)
    (let ((buffer (current-buffer)))
      (message "flycheck-irony--start: buffer:%S" buffer)
      (irony-diagnostics-async
       (lambda (status &rest args) ;; closure, lexically bound
           (message "flycheck-irony--start (lambda): buffer:%S" buffer)
           (pcase status
             (`error (funcall callback 'errored (car args)))
             (`cancelled (funcall callback 'finished nil))
             (`success
              (let* ((diagnostics (car args))
                     (errors (mapcar (lambda (diagnostic)
                                         (flycheck-irony--build-error checker buffer diagnostic))
                                     diagnostics)))
                (funcall callback 'finished (delq nil errors)))))))))
)

Thanks

cbourjau commented 7 years ago

Thanks for your fast response. I went through your list and am now on the current melpa version. (Note for other people following this to debug in the future: I had to delete irony's temporary files in /tmp in order to install the new version.) As I said previously, the error does not always occur and now it seems like I do not get a backtrace, but this could just be a coincident? However, Flycheck still seems to crash (FlyC* in the modeline) and I get the following in the Message buffer:

Debug on Error enabled globally
irony--process-server-response: End of file during parsing

This error seems to have have been an issue in the past but I could not fix it looking at the old issues here on github.

Using your first snippet I get the following in Messages:

flycheck-irony--start: buffer:#<buffer AliAnalysisTaskMCSmearing.cxx>
flycheck-irony--start (lambda): buffer:#<buffer AliAnalysisTaskMCSmearing.cxx> [2 times]

Using your second snippet I get:

flycheck-irony--start: buffer:#<buffer AliAnalysisTaskMCSmearing.cxx>
flycheck-irony--start (lambda): buffer:#<buffer AliAnalysisTaskMCSmearing.cxx>
flycheck-irony--start: buffer:#<buffer AliAnalysisTaskMCSmearing.cxx>
flycheck-irony--start (lambda): buffer:#<buffer AliAnalysisTaskMCSmearing.cxx>
flycheck-irony--start: buffer:#<buffer AliAnalysisTaskMCSmearing.cxx>
irony--process-server-response: End of file during parsing

Does this hint at anything? Thanks again!

Sarcasm commented 7 years ago

What a let down, I was hoping to understand the issue but now you have another problem instead...

irony--process-server-response: End of file during parsing

This error usually happens when irony server crashes.

Does irony-server work?

~/.emacs.d/irony/bin/irony-server --version

Do you have some log, something like "libclang crash detected" in /tmp/irony.<date>.log?

cbourjau commented 7 years ago

Thanks again for your help. I am now on a slightly different machine than earlier today but they are both very similar and show the same issue (One is Debian Sid, the other Ubuntu 14.04). Even after the crash (FlyC* in modeline + no more autocompletion) the server seems to be responding:

$ ~/.emacs.d/irony/bin/irony-server --version
irony-server version 0.2.0
Debian clang version 3.6.2-3 (tags/RELEASE_362/final) (based on LLVM 3.6.2)

There are indeed logs produced and here is one right after a crash:

execute: Command{action=Command::Parse, file='/home/christian/repos/alicesw/aliphysics/master/src/PWGCF/Correlations/C2/test.cxx', dir='', line=0, column=0, flags=['-x', 'c++', '-working-directory', '/home/christian/repos/alicesw/aliphysics/master/src/', '-std=c++11', '-pthread', '-m64', '-I/home/christian/repos/alicesw/root/v5-34-30/inst/include/', '-I/home/christian/repos/alicesw/aliroot/master/inst/include/', '-I/home/christian/repos/alicesw/aliphysics/master/inst/include/', '-I/home/christian/repos/alicesw/aliphysics/master/inst/PWGLF/FORWARD/trains/', '-L/home/christian/repos/alicesw/root/v5-34-30/inst/lib', '-lEve', '-lEG', '-lTreePlayer', '-lGeom', '-lGed', '-lRGL', '-lGui', '-lCore', '-lCint', '-lRIO', '-lNet', '-lHist', '-lGraf', '-lGraf3d', '-lGpad', '-lTree', '-lRint', '-lPostscript', '-lMatrix', '-lPhysics', '-lMathCore', '-lThread', '-pthread', '-lm', '-ldl', '-rdynamic'], unsavedFiles.count=1, opt=off}
execute: Command{action=Command::Diagnostics, file='', dir='', line=0, column=0, flags=[], unsavedFiles.count=0, opt=off}
execute: Command{action=Command::Parse, file='/home/christian/repos/alicesw/aliphysics/master/src/PWGCF/Correlations/C2/test.cxx', dir='', line=0, column=0, flags=['-x', 'c++', '-working-directory', '/home/christian/repos/alicesw/aliphysics/master/src/', '-std=c++11', '-pthread', '-m64', '-I/home/christian/repos/alicesw/root/v5-34-30/inst/include/', '-I/home/christian/repos/alicesw/aliroot/master/inst/include/', '-I/home/christian/repos/alicesw/aliphysics/master/inst/include/', '-I/home/christian/repos/alicesw/aliphysics/master/inst/PWGLF/FORWARD/trains/', '-L/home/christian/repos/alicesw/root/v5-34-30/inst/lib', '-lEve', '-lEG', '-lTreePlayer', '-lGeom', '-lGed', '-lRGL', '-lGui', '-lCore', '-lCint', '-lRIO', '-lNet', '-lHist', '-lGraf', '-lGraf3d', '-lGpad', '-lTree', '-lRint', '-lPostscript', '-lMatrix', '-lPhysics', '-lMathCore', '-lThread', '-pthread', '-lm', '-ldl', '-rdynamic'], unsavedFiles.count=1, opt=off}
execute: Command{action=Command::Complete, file='/home/christian/repos/alicesw/aliphysics/master/src/PWGCF/Correlations/C2/test.cxx', dir='', line=21, column=3, flags=['-x', 'c++', '-working-directory', '/home/christian/repos/alicesw/aliphysics/master/src/', '-std=c++11', '-pthread', '-m64', '-I/home/christian/repos/alicesw/root/v5-34-30/inst/include/', '-I/home/christian/repos/alicesw/aliroot/master/inst/include/', '-I/home/christian/repos/alicesw/aliphysics/master/inst/include/', '-I/home/christian/repos/alicesw/aliphysics/master/inst/PWGLF/FORWARD/trains/', '-L/home/christian/repos/alicesw/root/v5-34-30/inst/lib', '-lEve', '-lEG', '-lTreePlayer', '-lGeom', '-lGed', '-lRGL', '-lGui', '-lCore', '-lCint', '-lRIO', '-lNet', '-lHist', '-lGraf', '-lGraf3d', '-lGpad', '-lTree', '-lRint', '-lPostscript', '-lMatrix', '-lPhysics', '-lMathCore', '-lThread', '-pthread', '-lm', '-ldl', '-rdynamic'], unsavedFiles.count=1, opt=off}
libclang: crash detected in code completion
execute: Command{action=Command::Diagnostics, file='', dir='', line=0, column=0, flags=[], unsavedFiles.count=0, opt=off}

As you can see ther is indeed a crash in libclang!

I have been trying to build a minimum example that can reproduce this crash, but it seems to not work with a very simple file. It seems like it only crashes after adding some #include statements pointing to a very large framework. Do you see any way to pinpoint which files might be the offenders if it were for example an encoding issue? I should mention though, that my code compiles regardless of this irony issue.

Sarcasm commented 7 years ago

I don't understand the issue, but can you try the following fix from another issue:

cbourjau commented 7 years ago

Commenting out the

parseTUOptions_ &= ~CXTranslationUnit_CacheCompletionResults;

in TUManager.cpp as pointed out in #326 did indeed do the trick and everything is working now. I guess I got on the wrong track after seeing the "Selecting deleted buffer" error in the beginning.

Thanks a lot for your help and I guess I can close this issue since it is now a duplicate of said issue.

Sarcasm commented 7 years ago

Change added to master branch, we will see if there is any downside.

Thanks for reporting the issue.