我是Emacs的忠实粉丝,并且经常使用它,特别是在编程和调试时(使用gud)(C / C ++)。
最近我不得不调试一个程序(相当简单,但计算大量数据(图论)),但我有一个相当讨厌的问题。 在程序执行过程中,我收到以下错误:
error in process filter: Stack overflow in regexp matcher
我做了一些研究以找出它是什么,我发现了这篇文章:Debugging in emacs (with gud) often results in stack overflow error。
据我了解,正则表达式匹配器存在问题,而且程序中的某些内容太长了? (我确实有很多参数的异常长的函数名称,我也使用异常大的容器。)
我真的想解决这个问题,但我对调试Emacs Lisp一无所知,有没有人可以帮助我?
以下是我从Emacs内部debbuger获得的输出:http://pastebin.com/5CKe74e6
我还应该指出,我使用的是Emacs Prelude的个性化版本。
答案 0 :(得分:4)
潜在的问题是正则表达式(regexp)包含太多替代方案,并且当应用于(通常很长的)文本时,它无法匹配它试图匹配的任何内容。
在你的情况下,它是正则表达式:
"\\([[:alnum:]-_]+\\)=\\({\\|\\[\\|\"\"\\|\"\\(?:[^\\\"]\\|\\\\.\\)*\"\\)"
函数gdb-jsonify-buffer
使用了它。
看起来这个正则表达式尝试匹配分配。基本上,它匹配=
左侧的变量和右侧表达式(部分)。 regexp似乎匹配的一个东西是一个包含转义引号的字符串 - 这总是一个警告标志,因为Emacs提供了更好的解析字符串的方法。
问题可能源于这个正则表达式错误(因此它比你的字符串更多匹配),你有一个格式错误的字符串,或者你的程序只包含一个非常大的字符串。
我建议您向该软件包的维护者提交错误报告。确保包含导致错误被触发的文本。
或者,您可以尝试自行修复此问题。我建议您使用更简单的正则表达式替换复杂的正则表达式,以找到字符串的开头。然后,您可以使用(forward-sexp)
来查找字符串的结尾。
答案 1 :(得分:3)
我也遇到了这个问题,所以我使用了Lindydancer建议将字符串文字上的正则表达式转换为使用(forward-sexp),并且它对我来说一直很好。
我发布了补丁:
http://lists.gnu.org/archive/html/bug-gnu-emacs/2017-12/msg00968.html
所以希望它会在某个时候合并。在此期间,您可以将此用于gdb-jsonify-buffer:
(defun gdb-jsonify-buffer (&optional fix-key fix-list)
"Prepare GDB/MI output in current buffer for parsing with `json-read'.
Field names are wrapped in double quotes and equal signs are
replaced with semicolons.
If FIX-KEY is non-nil, strip all \"FIX-KEY=\" occurrences from
partial output. This is used to get rid of useless keys in lists
in MI messages, e.g.: [key=.., key=..]. -stack-list-frames and
-break-info are examples of MI commands which issue such
responses.
If FIX-LIST is non-nil, \"FIX-LIST={..}\" is replaced with
\"FIX-LIST=[..]\" prior to parsing. This is used to fix broken
-break-info output when it contains breakpoint script field
incompatible with GDB/MI output syntax.
If `default-directory' is remote, full file names are adapted accordingly."
(save-excursion
(let ((remote (file-remote-p default-directory)))
(when remote
(goto-char (point-min))
(while (re-search-forward "[\\[,]fullname=\"\\(.+\\)\"" nil t)
(replace-match (concat remote "\\1") nil nil nil 1))))
(goto-char (point-min))
(when fix-key
(save-excursion
(while (re-search-forward (concat "[\\[,]\\(" fix-key "=\\)") nil t)
(replace-match "" nil nil nil 1))))
(when fix-list
(save-excursion
;; Find positions of braces which enclose broken list
(while (re-search-forward (concat fix-list "={\"") nil t)
(let ((p1 (goto-char (- (point) 2)))
(p2 (progn (forward-sexp)
(1- (point)))))
;; Replace braces with brackets
(save-excursion
(goto-char p1)
(delete-char 1)
(insert "[")
(goto-char p2)
(delete-char 1)
(insert "]"))))))
(goto-char (point-min))
(insert "{")
(let ((re (concat "\\([[:alnum:]-_]+\\)=")))
(while (re-search-forward re nil t)
(replace-match "\"\\1\":" nil nil)
(if (eq (char-after) ?\") (forward-sexp) (forward-char))))
(goto-char (point-max))
(insert "}")))