9

我是 Emacs 的忠实粉丝,并且经常使用它,尤其是在编程和调试(使用 gud)(C/C++)时。

最近我不得不调试一个程序(相当简单,但需要计算大量数据(图论)),但我遇到了一个相当烦人的问题。在程序的逐步执行过程中,我收到以下错误:

error in process filter: Stack overflow in regexp matcher

我做了一些研究以找出它是什么,我发现了这篇文章:Debugging in emacs (with gud) 通常会导致堆栈溢出错误

所以据我了解,正则表达式匹配器存在问题,而且我的程序中的某些内容太长了?(我确实有非常长的函数名和很多参数,而且我还使用了非常大的容器。)

我真的很想解决这个问题,但我对调试 Emacs Lisp 一无所知,有没有人可以帮助我?

这是我从 Emacs 内部调试器得到的输出:http: //pastebin.com/5CKe74e6

我还应该指出,我使用的是 Emacs Prelude 的个性化版本。

4

2 回答 2

4

根本问题是正则表达式 (regexp) 包含太多替代项,当应用于(通常很长的)文本时,它无法匹配它试图匹配的任何内容。

在您的情况下,它是正则表达式:

"\\([[:alnum:]-_]+\\)=\\({\\|\\[\\|\"\"\\|\"\\(?:[^\\\"]\\|\\\\.\\)*\"\\)"

函数使用哪个gdb-jsonify-buffer

看起来这个正则表达式试图匹配分配。基本上,它匹配左侧的变量=和右侧的表达式(的一部分)。正则表达式似乎匹配的一件事是包含转义引号的字符串——这始终是一个警告信号,因为 Emacs 提供了更好的字符串解析方法。

问题可能源于这个正则表达式是错误的(因此它比你的字符串匹配更多),你有一个格式错误的字符串,或者你的程序只包含一个非常大的字符串。

我建议您向该软件包的维护者提交错误报告。确保包含导致触发错误的文本。

或者,您可以尝试自己解决此问题。我建议您将复杂的正则表达式替换为更简单的正则表达式,该正则表达式可以找到字符串的开头。然后,您可以使用,例如,(forward-sexp)查找字符串的结尾。

于 2015-07-05T08:00:51.390 回答
4

我也遇到了这个问题,所以我使用了 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 "}")))
于 2017-12-29T00:10:31.547 回答