leoliu / ggtags

Emacs frontend to GNU Global source code tagging system.

Home Page:http://elpa.gnu.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

"ggtags-find-tag-dwim" gives error ("Selecting deleted buffer")

asatale opened this issue · comments

I am invoking ggtags-find-tag-dwim (M-.) from C source code and get error Error running timer `compilation-auto-jump': (error "Selecting deleted buffer")

I look at Message buffer and see following.

Global found 1 definition
Error running timer `compilation-auto-jump': (error "Selecting deleted buffer")

This is not a persistent problem. I am able to resolve some of the symbols but not others.

I am using 0.8.9 ggtags and I am invoking emacs with -nw option for terminal mode operation.

@curioussoul,

Thanks for the report. I see this transient error as well but unfortunately I was often in a hurry and forgot to investigate it further. Meanwhile If you found a way to reliably reproduce the bug it could be very helpful.

Thanks,
Leo

@leoliu
I have been able to reproduce this very consistently. I am using linux kernel code base to test this.

Before invoking (ggtags-find-tag-dwin), I did (setq debug-on-error t) to get the back trace and this is what I got.

Debugger entered--Lisp error: (error "Selecting deleted buffer")
compilation-auto-jump(# 250)
apply(compilation-auto-jump (# 250))
byte-code("r\301^H\302H^H\303H"\210)\301\207" [timer apply 5 6] 4)
timer-event-handler([t 21744 38830 141084 nil compilation-auto-jump (# 250) nil 878000])

Does this help?

hi @curioussoul,

Could you show me a recipe that doesn't involve enabling debug-on-error? When debug-on-error is enabled, the timer might work differently, so basically the buffer is deleted before compilation-auto-jump.

Thanks,
Leo

Hi @leoliu,
I get this error even without "debug-on-error". The message buffer simple contains following messages

Global found 1 definition
Error running timer `compilation-auto-jump': (error "Selecting deleted buffer")

Can you tell me what exact data/information would help you?

hi @curioussoul,

It might be tricky to fix this properly. Basically compilation-auto-jump is run by an idle timer. So in order to clean up (deleting the buffer with a single entry) ggtags also run an idle timer. Ideally the first timer should run before the second timer. See the comment before (sit-for 0) in ggtags-global-handle-exit.

Does it help if you change 0 in (ggtags-navigation-mode-cleanup buf 0) of ggtags-global-handle-exit to a greater value, for example, 0.25, 0.5, 1 etc?

What I really like is show me how to reproduce the problem consistently? Mind you, this might depend on OS, emacs, project etc. I run ggtags daily on mac (and centos7 in the past) and I only see this bug occasionally (roughly once per month).

Cheers,
Leo

Hi @leoliu,
I changed as (ggtags-navigation-mode-cleanup but 1) and tested. Now that problem got resolved. I could resolve the symbols for which I was getting error before.

However, now pop-tag-mark (M-*) has stopped working. Since timeout is 1 sec, I can see that the ggtags-global buffer getting deleted (and hence the pop-tag-mark is failing???).

Somehow, this problem is observed only when only one symbol definition is found. I guess before ggtags attempts to jump to that location, the ggtags-global buffer is deleted and hence the operations fails. When the timer is increased (as in this test run), things start (partially working), since buffer persists longer. Somehow if multiple results are found, there is different code path is followed.

@curioussoul,

Sorry I seem to completely drop the ball. Does the error "Selecting deleted buffer" happen every time you jump to a symbol with single definition? Could you show me how to reproduce it?

It would be very annoying if it happens all the time and I'd like to fix it if possible.

Thanks,
Leo

@leoliu
The reason why I see this often may be function of the packages that I have. While I can reproduce this every-time, I am struggling to come up with exact step which will allow you to reproduce this. I am more than willing to try out any instrumented code from you which may provide more insight into this issue.

In the meantime here is my emacs configuration. Not sure if this is helpful to identify anything obvious.

(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(ag-reuse-buffers t)
 '(ansi-color-names-vector
   ["#242424" "#e5786d" "#95e454" "#cae682" "#8ac6f2" "#333366" "#ccaa8f" "#f6f3e8"])
 '(anything-M-x-requires-pattern nil)
 ;;'(anything-c-etags-tag-file-name "GTAGS")
 '(anything-dired-mode
   "Enable anything completion in Dired functions.
Bindings affected are C, R, S, H.
This is deprecated for Emacs24+ users, use `ac-mode' instead.")
 '(auto-compression-mode t nil (jka-compr))
 '(auto-revert-check-vc-info t)
 '(blink-matching-paren-on-screen t)
 '(case-fold-search t)
 '(compilation-scroll-output (quote first-error))
 '(compile-command "cd $WA;make -j 14 rw ")
 '(current-language-environment "ASCII")
 '(custom-enabled-themes (quote (wheatgrass)))
 '(ecb-options-version "2.40")
 '(font-lock-maximum-decoration (quote ((compile) (t . t))))
 '(ggtags-global-window-height 5)
 '(ggtags-highlight-tag-delay 0.5)
 '(ggtags-project-duration 60000)
 '(global-font-lock-mode t nil (font-lock))
 '(globalff-adaptive-selection t)
 '(globalff-basename-match nil)
 '(globalff-camelcase-search nil)
 '(globalff-databases
   "~/locate.db:~repo.db")
 '(globalff-regexp-search t)
 '(globalff-search-delay 0.1)
 '(gtags-auto-update t)
 '(gtags-select-buffer-single t)
 '(gtags-suggested-key-mapping t)
 '(helm-locate-db-file-regexp "~/locate.db")
 '(inhibit-startup-echo-area-message t)
 '(kill-ring-max 100)
 '(kill-whole-line t)
 '(message-default-charset (quote iso-8859-1))
 '(show-paren-mode t nil (paren))
 '(text-mode-hook (quote (turn-on-auto-fill text-mode-hook-identify)))
 '(tool-bar-mode nil)
 '(transient-mark-mode t))
(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(cursor ((t (:background "yellow green"))))
 '(minibuffer-prompt ((t (:foreground "black" :box (:line-width -1 :color "red" :style released-button) :weight bold))))
 '(which-func ((t (:foreground "cyan")))))

;;; '(iswitchb-buffer-ignore (quote ("^ " "^\\*\\*")))
;;;  '(iswitchb-mode t nil (iswitchb))
(iswitchb-mode)

(setq inhibit-startup-message t
      inhibit-startup-echo-area-message t)

;; Set Load path
(add-to-list 'load-path "~/.emacs.d/lisp")

(require 'cc-mode)
;;(require 'iswitchb)
;;(require 'etags)
(require 'pabbrev)
(require 'dired+)
;;(require 'window-number)
;;(window-number-mode)



(require 'google-c-style)              ; Load google-c-style
(add-hook 'c-mode-common-hook 'google-set-c-style)
(add-hook 'c-mode-common-hook 'google-make-newline-indent)

(add-hook 'c-mode-common-hook
          (lambda ()
            (which-function-mode)))

(autoload 'yang-mode "yang-mode" "Major mode for editing YANG modules." t)
(add-to-list 'auto-mode-alist '("\\.yang$" . yang-mode))

(defun google-yang-mode-hook ()
  "Configuration for YANG Mode. Add this to `yang-mode-hook'."
  ;;(c-set-style "google-c-style")
  (setq c-basic-offset 2))
(add-hook 'yang-mode-hook 'google-yang-mode-hook)

;; load cmake mode
;; (setq load-path (cons (expand-file-name "/home/agunturu/.emacs.d/cmake-mode") load-path))
(require 'cmake-mode)
(setq auto-mode-alist
  (append '(("CMakeLists\\.txt\\'" . cmake-mode)
  ("\\.cmake\\'" . cmake-mode)
  ("\\.cmake\\.in\\'" . cmake-mode))
  auto-mode-alist))

(autoload 'vala-mode "vala-mode" "Major mode for editing Vala code." t)
(setq auto-mode-alist
      (append '(("\\.vala$" . vala-mode)) auto-mode-alist))


(defun my-c-mode-common-hook()
  (c-toggle-auto-hungry-state)
  (modify-syntax-entry ?_ "w")
  (font-lock-mode 1)
  (setq c-block-comment-prefix "//")
  (setq c-report-syntactic-error 't)
  ;;;(auto-fill-mode 1)
  (pabbrev-mode))

(defun my-common-mode-hook ()
  (auto-fill-mode 1)
  (pabbrev-mode   1)
  (font-lock-mode 1))

(defun my-python-mode-hook ()
  ;;;(auto-fill-mode 1)
  (modify-syntax-entry ?_ "w")
  ;;;(smart-tab-mode 2)
  (pabbrev-mode 1)
  ;;;(define-key python-mode-map (kbd "C-c C-f") 'anything-project)
  (font-lock-mode 1))




;; Enter key executes newline-and-indent
(defun set-newline-and-indent ()
  "Map the return key with `newline-and-indent'"
  (local-set-key (kbd "RET") 'newline-and-indent))
(add-hook 'python-mode-hook 'set-newline-and-indent)



;;; Lisp Mode hooks
(add-hook 'lisp-mode-hook     'my-common-mode-hook)
;;; Texinfo Mode hooks
(add-hook 'texinfo-mode-hook  'my-common-mode-hook)

;;; Python hooks
(add-hook 'python-mode-hook   'my-python-mode-hook)

(add-hook 'python-mode-hook 'jedi:setup)
(setq jedi:complete-on-dot t)   ; optional

;;; Shell Mode hooks
(add-hook 'shell-script-hook  'my-common-mode-hook)

;;; Perl Mode hooks
(add-hook 'perl-mode-hook     'my-common-mode-hook)

;;; Normal text model
(add-hook 'text-mode-hook     'my-common-mode-hook)

;;; C Mode hooks
(add-hook 'c-mode-hook 'my-c-mode-hooks)

;;; CC-Mode common hooks
(add-hook 'c-mode-common-hook 'my-c-mode-common-hook)

;; Lazy Font locking
(if (fboundp 'turn-on-lazy-lock)
    (add-hook 'font-lock-mode-hook 'turn-on-lazy-lock))

;;; Use iswitchb instead of normal switch-to-buffer
;;(defalias 'read-buffer 'iswitchb-read-buffer)

(defun mark-line-and-copy ()
  "Copy the current line into the kill ring."
  (interactive)
  (beginning-of-line)
  (push-mark)
  (forward-line 1)
  (kill-ring-save (region-beginning) (region-end))
  (message "line copied"))


(defun mark-sexp-and-copy()
  "Copy the current sexp into the kill ring"
  (interactive)
  (let ((start-column (current-column)))
    (forward-sexp)
    (push-mark)
    (backward-sexp)
    (kill-ring-save (region-beginning) (region-end))
    (move-to-column start-column)
    (message "sexp copied")))

(defun mark-sexp-and-kill()
  "Copy the current sexp into the kill ring"
  (interactive)
  (forward-sexp)
  (push-mark)
  (backward-sexp)
  (kill-sexp)
  (message "sexp killed"))


(defun my-c-mode-hooks()
  (setq c-block-comment-prefix "*")
  ;;;(local-set-key [(meta control)] 'tag-complete-symbol)
  (setq c-report-syntactic-errors 't))

(global-set-key (kbd "C-c C-y") 'mark-line-and-copy)
(global-set-key (kbd "C-c C-j") 'mark-sexp-and-copy)
(global-set-key (kbd "C-c C-k") 'mark-sexp-and-kill)
(global-set-key (kbd "C-c C-g") 'ag)

;;;
;;; No TABs
;;;
(setq-default indent-tabs-mode nil)

(defun my-precommand-hook()
  (cond ((eq this-command 'beginning-of-defun)
         (push-mark))
        ((eq this-command 'end-of-defun)
         (push-mark))
        ((eq this-command 'c-beginning-of-defun)
         (push-mark))
        ((eq this-command 'c-end-of-defun)
         (push-mark))
        ((eq this-command 'goto-line)
         (push-mark))
        ((eq this-command 'backward-up-list)
         (push-mark))
        )
  )

(add-hook 'pre-command-hook 'my-precommand-hook)

(defun my-find-local-def()
  "Find the defintion variable on function stack"
  (interactive)
  (let ((word-here (word-at-point)))
    (if word-here
        (let ((point-here (point)))
          (c-beginning-of-defun)
          (cond ((not (search-forward word-here point-here t 1))
                 (goto-char point-here)
                 (message "No definition found"))
                (t (push-mark point-here))))
      (message "Nothing to search"))))



;(define-key input-decode-map "^[[1;9C" [M-right])
;(define-key input-decode-map "^[[1;9D" [M-left])
;(define-key input-decode-map "^[[1;9A" [M-up])
;(define-key input-decode-map "^[[1;9B" [M-down])

;; Some general Shortcut, should always be towards the end of this file





;;; Remove all menu bars
(menu-bar-mode -1)

;;;; Undo Tree
;(global-undo-tree-mode)


;;; To make "shift Up" select text
;(if (equal "xterm" (tty-type))
;    (define-key input-decode-map "\e[1;2A" [S-up]))

;;; No warnings for large files
(setq large-file-warning-threshold nil)

;; To avoid dired from opening multiple buffers
;;(put 'dired-find-alternate-file 'disabled nil)
;; (add-hook 'dired-mode-hook
;;           (lambda ()
;;             (define-key dired-mode-map (kbd "^")
;;               (lambda () (interactive) (find-alternate-file "..")))
;;                                         ; was dired-up-directory
;;             ))
;;;(global-set-key "\M-l"      'goto-line)
(global-set-key "\M-o"      'other-window)
(global-set-key "\M-0"      'delete-window)
(global-set-key "\M-2"      'split-window-vertically)
(global-set-key "\M-3"      'split-window-horizontally)
(global-set-key "\M-n"      'iswitchb-buffer)
(global-set-key "\M-p"      'globalff)
;;(global-set-key "\M-l"      'jump-to-register)
(global-set-key "\M-]"      'kill-buffer)
;;(global-set-key "\M-s"      'copy-to-register)
;;(global-set-key "\M-j"      'insert-register)
(global-set-key "\M-\\"     'align-current)
;;;(global-set-key (kbd "C-c C-g") 'my-find-local-def)


(global-set-key [M-right] 'forward-sexp)
(global-set-key [M-left]  'backward-sexp)
(global-set-key [M-up] 'compile)

(require 'package)
(add-to-list 'package-archives
             '("melpa" . "http://melpa.milkbox.net/packages/") t)
(package-initialize)

(autoload 'doc-mode "doc-mode" nil t)
(add-to-list 'auto-mode-alist '("\\.adoc$" . doc-mode))
(add-to-list 'auto-mode-alist '("\\.ad$" . doc-mode))
(add-hook 'doc-mode-hook
          '(lambda ()
             (turn-on-auto-fill)
             (require 'asciidoc)))

(autoload 'lua-mode "lua-mode" "Major mode for editing Lua code." t)
(setq auto-mode-alist
      (append '(("\\.lua$" . lua-mode)) auto-mode-alist))


;;(require 'dired+)
;;; Reuse buffer for dired
;;;(toggle-diredp-find-file-reuse-dir 1)
;;(global-set-key (kbd "C-?") 'help-command)
;;(global-set-key (kbd "M-?") 'mark-paragraph)
;;(global-set-key (kbd "C-h") 'delete-backward-char)
;;(global-set-key (kbd "M-h") 'backward-kill-word)

(require 'protobuf-mode)
(add-to-list 'auto-mode-alist '("\\.proto\\'" . protobuf-mode))


(global-set-key (kbd "C-c C-f") 'find-name-dired)

;;(require 'setup-helm)
;;(helm-mode 1)
;;(require 'helm)
;;(require 'helm-config)
;;(require 'helm-eshell)
;;(require 'helm-files)
;;(require 'helm-grep)
;;(global-set-key (kbd "C-c h") 'helm-command-prefix)
;;(global-unset-key (kbd "C-x c"))
;;(define-key helm-map (kbd "C-i") 'helm-execute-persistent-action)


(global-set-key (kbd "C-x <up>") 'windmove-up)
(global-set-key (kbd "C-x <down>") 'windmove-down)
(global-set-key (kbd "C-x <right>") 'windmove-right)
(global-set-key (kbd "C-x <left>") 'windmove-left)

(toggle-diredp-find-file-reuse-dir 1)

(load "server")
(unless (server-running-p) (server-start))

(set-face-attribute  'mode-line
                     nil
                     :foreground "cyan"
                     :background "black"
                     :box '(:line-width 1 :style released-button))
(set-face-attribute  'mode-line-inactive
                     nil
                     :foreground "white"
                     :background "black"
                     :box '(:line-width 1 :style released-button))

(require 'anything)
(require 'anything-config)

(setq anything-sources
      (list anything-c-source-buffers
            anything-c-source-file-name-history
            ;;anything-c-source-info-pages
            ;;anything-c-source-man-pages
            ;;anything-c-source-file-cache
            anything-c-source-emacs-commands))

(global-set-key (kbd "M-x") 'anything)

(require 'anything-project)
(global-set-key (kbd "C-x C-f") 'anything-find-files)
(global-set-key (kbd "C-x p f") 'anything-project)
(global-set-key (kbd "C-M-m") 'compile)

(require 'icicles)
(icy-mode 1)


(require 'globalff)
;;(require 'anything-exuberant-ctags)

(add-to-list 'load-path "~/.emacs.d/lisp")
;;(autoload 'gtags-mode "gtags" "" t)
;; (add-hook 'gtags-mode-hook
;;           '(lambda ()
;;  Local customization (overwrite key mapping)
;;              (define-key gtags-mode-map "\C-f" 'scroll-up)
;;              (define-key gtags-mode-map "\C-b" 'scroll-down)
;;              ))
(add-hook 'gtags-select-mode-hook
          '(lambda ()
             (setq hl-line-face 'underline)
             (hl-line-mode 1)
             ))
(add-hook 'c-mode-hook
          '(lambda ()
             (ggtags-mode 1)))

(add-hook 'c++-mode-hook
          '(lambda ()
             (gtags-mode 1)))

(add-hook 'python-mode-hook
          '(lambda ()
             (gtags-mode 1)))

(add-hook 'lua-mode-hook
          '(lambda ()
             (gtags-mode 1)))


;; Customization
;;(setq gtags-suggested-key-mapping t)
;;(setq gtags-auto-update t)

I find the same problem. invocation of ggtags-find-tag-dwim, fails with the message (error "Selecting deleted buffer")

+1, I see this problem intermittently. Very frustrating.

Let me see if I can track it down and fix it. Thanks for the feedback.

This is also being referenced at http://debbugs.gnu.org/cgi/bugreport.cgi?bug=23987
HTH

Hi all,

I still couldn't reproduce the problem so this is a best-effort fix. Could someone that can reproduce the issue confirm the fix? Thanks.

Leo

@leoliu
I patched compile.el(don't patch timer.el) acording to GNU bug report logs - #24585, but the problem exists. I recorded my screen http://p1.bpimg.com/567571/cd0b5423a7cf74d5.gif. Like gif showing, when find only one object, the problem occured. And when finding more the one object "error running timer" occur, but ggtags-global buffer was not killed.

hi @newdye,

ggtags.el needs patching to make use of the feature from the change to compile.el? Could you apply the following patch and try again?

diff --git a/ggtags.el b/ggtags.el
index d8bd4586..bf19a0e8 100644
--- a/ggtags.el
+++ b/ggtags.el
@@ -1698,9 +1698,11 @@ (defun ggtags-global-handle-exit (buf how)
       ;; - http://debbugs.gnu.org/23987
       ;; - https://github.com/leoliu/ggtags/issues/89
       ;;
-      (pcase (cl-find 'compilation-auto-jump timer-list :key #'timer--function)
-        (`nil )
-        (timer (timer-event-handler timer)))
+      ;; (pcase (cl-find 'compilation-auto-jump timer-list :key #'timer--function)
+      ;;   (`nil )
+      ;;   (timer (timer-event-handler timer)))
+      (compilation--ensure-parse (point-max))
+      (compilation-auto-jump buf)
       (ggtags-navigation-mode -1)
       (ggtags-navigation-mode-cleanup buf t)))))

hi @leoliu
Thank you for your replying. I apply this patch to ggtags.el. I'm afraid the problem remaining. I wonder whether I could patch timer.el too. And I found not finding every tag coursing problem. It's frustrating.

hi @newdye,

Try the timer.el patch too, please. It is unlikely to help but still try it anyway.

Could you also post the operating system, version of emacs, how do you reproduce the issue? Can you reproduce it starting from emacs -Q? Thanks.

The bug seems nasty.

hi @leoliu:

My enviroment:

  • OS: win10 64version
  • Emacs: emacs-w64-25.1-O2-with-modules

Just now, I try emacs -Q, it seems no error message, but stiil killed ggtags-global buffer when finding only one object. Is it normal?

hi @newdye,

When there is one match, ggtags by default jump to the match and kill the global buffer. So what you see is normal.