Làm thế nào để tìm ra một hàm được gọi từ đâu (backtrace / stacktrace)?


10

Tôi đã gặp phải một vấn đề là khu vực bị vô hiệu hóa (ở chế độ đánh dấu thoáng qua). Hàm deactivate-markđược gọi và tôi muốn tìm hiểu nó được gọi từ đâu (và tại sao).

Tôi đã thử M-x debug-on-entry RET deactivate-markvà nó dừng lại nhưng tôi không tìm ra cách nào để tìm ra người gọi. Toàn bộ stacktrace được hiển thị là:

Debugger entered--entering a function:
* deactivate-mark()

Tôi đã thử M-x edebug-eval-defunnhưng Edebug cũng không hiển thị người gọi.

Làm thế nào để tôi tìm hiểu tại sao (từ đâu) deactivate-markđược gọi là? Tôi đang tìm kiếm tiêu đề backtrace hoặc stacktrace.

BIÊN TẬP:

Một advice-addmẹo:

(defun message-show-backtrace ()
  (message "%s" (backtrace-frame 10)))

(advice-add deactivate-mark :before #'message-show-backtrace)

sản xuất niltrong *Messages*.

Chỉnh sửa: thêm thông tin về deactivate-mark: http://emacshorrors.com/posts/deac activate-mark.html


1
Tôi có thể tái tạo hành vi được mô tả và đầu ra. Chạy emacs -Q, bật gỡ lỗi M-x debug-on-entry deactivate-mark, kích hoạt đánh dấu C-<SPC>, nhập một ký tự.
Andrew Swann

Bạn có thể tư vấn deactiveate-markvà sử dụng chức năng tư vấn của mình backtrace-framesđể có được chế độ xem toàn bộ ngăn xếp cuộc gọi nếu edebug không hiển thị những gì bạn mong đợi.
Jordon Biondo

Đã thêm chỉnh sửa về advice-addbacktrace-frame. Nó không giúp được gì.
Gracjan Polak

Liên quan đến việc sao chép từ @AndrewSwann, điều đáng chú ý là việc gõ một ký tự thường chạy self-insert-commandvà "lệnh tự chèn là một hàm tích hợp tương tác trong 'mã nguồn C'." Điều này, cùng với các hành vi khác được ghi nhận cho đến nay, cho thấy rằng người ta sẽ phải gỡ lỗi gdb.
Joe Corneli

1
Từ việc đọc câu hỏi, có vẻ như dấu hiệu bị tắt bất ngờ. Trong khi đó, hành vi được mô tả bởi @AndrewSwann là hoàn toàn mong đợi (khu vực bị vô hiệu hóa khi bạn nhập một cái gì đó). Nếu hành vi bạn nhận được khớp với Andrew, vui lòng làm rõ những gì bạn muốn làm.
Malabarba

Câu trả lời:


4

Từ command_loop_1trong keyboard.c.

  ...
  if (!NILP (BVAR (current_buffer, mark_active))
  && !NILP (Vrun_hooks))
{
  /* In Emacs 22, setting transient-mark-mode to `only' was a
     way of turning it on for just one command.  This usage is
     obsolete, but support it anyway.  */
  if (EQ (Vtransient_mark_mode, Qidentity))
    Vtransient_mark_mode = Qnil;
  else if (EQ (Vtransient_mark_mode, Qonly))
    Vtransient_mark_mode = Qidentity;

  if (!NILP (Vdeactivate_mark))
    /* If `select-active-regions' is non-nil, this call to
       `deactivate-mark' also sets the PRIMARY selection.  */
    call0 (Qdeactivate_mark);
  else
  ...

Đó dường như là nơi duy nhất Qdeactivate_markđược gọi trong tất cả src/*.c. Vì vậy, dự đoán của tôi là đây là những gì bạn đang chạy vào.


Lưu ý, tôi không phải là một chuyên gia về Emacs C. Tôi chọc xung quanh với gdb --args src/emacs -Qsau khi đọc Làm thế nào để biên dịch emacs với các biểu tượng debug? .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.