Como descobrir de onde uma função é chamada (backtrace / stacktrace)?

10

Eu atingi um problema em que a região está desativada (no modo de marca transitória). A função deactivate-marké chamada e eu gostaria de descobrir de onde (e por que) é chamada.

Eu tentei M-x debug-on-entry RET deactivate-marke para, mas não encontrei maneira de descobrir a pessoa que ligou. Todo o rastreamento de pilha exibido é:

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

Eu tentei, M-x edebug-eval-defunmas o Edebug também não mostra o chamador.

Como descubro por que (de onde) deactivate-marké chamado? Estou procurando backtrace ou functinality stacktrace.

EDITAR:

Um advice-addtruque:

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

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

produz nilem *Messages*.

Edit: mais informações sobre deactivate-mark: http://emacshorrors.com/posts/deactivate-mark.html

Gracjan Polak
fonte
11
Eu posso reproduzir o comportamento e a saída descritos. Executar emacs -Q, ativar a depuração M-x debug-on-entry deactivate-mark, ativar a marca C-<SPC>, digite um caractere.
Andrew Swann
Você pode aconselhar deactiveate-marke, em sua função de aconselhamento, usar backtrace-framespara obter uma visão de toda a pilha de chamadas se o edebug não estiver mostrando o que você espera.
Jordon Biondo
Adicionada edição sobre advice-adde backtrace-frame. Não ajudou.
Gracjan Polak
Em relação à reprodução de @AndrewSwann, é importante notar que a digitação de um caractere geralmente é executada self-insert-commande "o comando self-insert-command é uma função interna interativa em 'código-fonte C'". Isso, junto com o outro comportamento observado até agora, sugere que um terá que ser depurado gdb.
Joe Corneli
11
Ao ler a pergunta, parecia que a marca estava sendo desativada inesperadamente. Enquanto isso, o comportamento descrito por @AndrewSwann é perfeitamente esperado (a região é desativada quando você digita alguma coisa). Se o comportamento que você obtiver corresponder ao de Andrew, esclareça o que deseja fazer.
Malabarba 29/05

Respostas:

4

De command_loop_1dentro 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
  ...

Esse parece ser o único lugar onde Qdeactivate_marké chamado em todos src/*.c. Então, meu palpite é que é nisso que você está se deparando.


Note, eu não sou um especialista em Emacs C. Eu remexia com gdb --args src/emacs -Qdepois de ler Como compilar emacs com símbolos de depuração? .

Joe Corneli
fonte