emacs-libvterm icon indicating copy to clipboard operation
emacs-libvterm copied to clipboard

segmentation fault with compilation-shell-minor-mode

Open tpapp opened this issue 5 years ago • 21 comments

I am experimenting with vterm in julia-repl (https://github.com/tpapp/julia-repl/pull/84). It works fine, the only issue is that when I click on some file locations in the output to navigate using compilation-shell-minor-mode, I occasionally get a segfault. But it has proven to be near impossible to reproduce on purpose --- usually it works fine.

The backtrace is

emacs[0x512b1e]                                                                                     
emacs[0x4f84da]                                                                                     
emacs[0x510fee]                                                                                     
emacs[0x511218]                                                                                     
emacs[0x511299]                                                                                     
/lib/x86_64-linux-gnu/libpthread.so.0(+0x153c0)[0x7f2d667603c0]                                     
/home/tamas/.emacs.d/elpa/vterm-20200501.2231/vterm-module.so(Fvterm_get_pwd+0x97)[0x7f2d5b48d107]
emacs[0x59c48d]                                                                                     
emacs[0x56f57b]                                                                                     
emacs[0x5ab340]                                                                                     
emacs[0x56f57b]                                                                                     
emacs[0x5ab340]                                                                                     
emacs[0x56f57b]                                                                                     
emacs[0x5ab340]                                                                                     
emacs[0x56f57b]                                                                                     
emacs[0x5ab340]                                                                                     
emacs[0x56f57b]                                                                                     
emacs[0x56bfcd]                                                                                     
emacs[0x56f5fc]                                                                                     
emacs[0x57132a]                                                                                     
emacs[0x56c538]                                                                                     
emacs[0x56f5fc]                                                                                     
emacs[0x5ab340]                                                                                     
emacs[0x56f57b]                                                                                     
emacs[0x56f6ba]                                                                                     
emacs[0x507800]                                                                                     
emacs[0x56e74e]                                                                                     
emacs[0x4f88b4]                                                                                     
emacs[0x56e6bd]                                                                                     
emacs[0x4f884b]                                                                                     
emacs[0x4fd9a3]                                                                                     
emacs[0x4fdce8]                                                                                     
emacs[0x41b991]                                                                                     
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x7f2d6644e0b3]
emacs[0x41c69a]                                                                                     

I am using 26.3~1.git96dd019-kk1+19.04 from the KelleyK PPA. I am happy to compile any other version if that helps with the debugging.

tpapp avatar May 05 '20 16:05 tpapp

I still have this problem --- any suggestions on isolating this would be appreciated.

tpapp avatar May 19 '20 11:05 tpapp

You could track it down by commenting and uncommenting parts of vterm-get-pwd step by step.

brotzeit avatar May 19 '20 16:05 brotzeit

I am not sure what is the problem. Most of the time, I've seen crashes it is because vterm--term is not set correctly. Can you try

(defun vterm--get-pwd (&optional linenum)
  "Get working directory at LINENUM."
(when vterm--term
  (let ((raw-pwd (vterm--get-pwd-raw
                  vterm--term
                  (or linenum (line-number-at-pos)))))
    (when raw-pwd
      (vterm--get-directory raw-pwd)))))

I don't really expect it to work, but it is worth trying if the current buffer is temporarily switched for some operation.

Sbozzolo avatar Jun 02 '20 00:06 Sbozzolo

@SBozzolo: thanks for the suggestion. This works, and also seems to fix #340.

I will make I make a PR. The only thing that seems to be using vterm--get-pwd is vterm-next-error-function, which looks like it will be fine with a nil.

tpapp avatar Jun 21 '20 14:06 tpapp

I still get the issue with #350, so unfortunately that's not a fix (it made the crash less frequent though).

tpapp avatar Jun 28 '20 14:06 tpapp

Thanks for your report. It's good to hear that the crashes are less frequent. I suspect that there are other functions that can lead to crashes because they were designed to be called in a specific context, but somehow they are called in a different way. I am planning to go over all the functions and make sure that they don't accidentally trigger segmentation faults when improperly called.

Sbozzolo avatar Jun 28 '20 15:06 Sbozzolo

Can you please try #356?

Sbozzolo avatar Jun 28 '20 15:06 Sbozzolo

I am still experiencing this issue occasionally, with vterm-20200713.1344 that I think should include #356. Can you please reopen? Backtrace is the same --- could it be a threading issue?

Fatal error 11: Segmentation fault
Backtrace:
emacs[0x512b1e]
emacs[0x4f84da]
emacs[0x510fee]
emacs[0x511218]
emacs[0x511299]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x153c0)[0x7fee26f0e3c0]
/home/tamas/.emacs.d/elpa/vterm-20200713.1344/vterm-module.so(Fvterm_get_pwd+0x97)[0x7fee2043d107]
emacs[0x59c48d]
emacs[0x56f57b]
emacs[0x5ab340]
emacs[0x56f57b]
emacs[0x5ab340]
emacs[0x56f57b]
emacs[0x5ab340]
emacs[0x56f57b]
emacs[0x5ab340]
emacs[0x56f57b]
emacs[0x56bfcd]
emacs[0x56f5fc]
emacs[0x57132a]
emacs[0x56c538]
emacs[0x56f5fc]
emacs[0x5ab340]
emacs[0x56f57b]
emacs[0x56f6ba]
emacs[0x507800]
emacs[0x56e74e]
emacs[0x4f88b4]
emacs[0x56e6bd]
emacs[0x4f884b]
emacs[0x4fd9a3]
emacs[0x4fdce8]
emacs[0x41b991]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x7fee26bfc0b3]
emacs[0x41c69a]
[1]    262961 segmentation fault (core dumped)  emacs

tpapp avatar Jul 21 '20 11:07 tpapp

I changed the relevant function to

(defun vterm--get-pwd (&optional linenum)
  "Get working directory at LINENUM."
  (print "vterm--get-pwd called" #'external-debugging-output)
  (when vterm--term
    (print vterm--term #'external-debugging-output)
    (let ((raw-pwd (vterm--get-pwd-raw
                    vterm--term
                    (or linenum (line-number-at-pos)))))
      (print raw-pwd)
      (when raw-pwd
        (vterm--get-directory raw-pwd)))))

to get some debugging output, then I get a

"vterm--get-pwd called"
#<user-ptr ptr=0x67cdde0 finalizer=0x7efd8131bb50>

tpapp avatar Jul 21 '20 11:07 tpapp

Also using print, I checked that the second argument (or linenum (line-number-at-pos)) is an integer.

tpapp avatar Jul 21 '20 13:07 tpapp

I think the error is in the C code. I added some printf statements in

emacs_value Fvterm_get_pwd(emacs_env *env, ptrdiff_t nargs, emacs_value args[],
                           void *data) {
  Term *term = env->get_user_ptr(env, args[0]);
  fprintf(stderr, "got term\n"); 
  int linenum = env->extract_integer(env, args[1]);
  fprintf(stderr, "linenum %d\n", linenum); 
  int row = linenr_to_row(term, linenum);
  fprintf(stderr, "row %d\n", row); 
  char *dir = get_row_directory(term, row);
  fprintf(stderr, "dir %s\n", dir); 
  return dir ? env->make_string(env, dir, strlen(dir)) : Qnil;
}

and got the backtrace

got term                                                                                                                                                                                                                                                                                    
linenum 87                                                                                                                                                                                                                                                                                  
row -28                                                                                                                                                                                                                                                                                     
Fatal error 11: Segmentation fault                                                                                                                                                                                                                                                          
Backtrace:                                                                                                                                                                                                                                                                                  
emacs[0x512b1e]                                                                                                                                                                                                                                                                             
emacs[0x4f84da]                                                                                                                                                                                                                                                                             
emacs[0x510fee]                                                                                                                                                                                                                                                                             
emacs[0x511218]                                                                                                                                                                                                                                                                             
emacs[0x511299]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x153c0)[0x7f8ffdc7f3c0]
/home/tamas/src/emacs-libvterm/vterm-module.so(Fvterm_get_pwd+0x102)[0x7f8ff29a2912]

tpapp avatar Jul 21 '20 14:07 tpapp

That's tremendously useful. Can you continue debugging in get_row_directory?

Sbozzolo avatar Jul 21 '20 15:07 Sbozzolo

I think the error is in linenr_to_row. If I clamp the output from that as

  int row = linenr_to_row(term, linenum);
  char *dir = get_row_directory(term, row < 1 ? 1 : row);

everything works fine.

I am happy to debug more, just need some guidance. Could vterm->sb_current be off?

(also, can you please reopen the issue? or should I start a new one?)

tpapp avatar Jul 21 '20 15:07 tpapp

I reopened the issue. I think you gave very valuable insight. I need to look into this more carefully, which I'll probably do during the weekend. I'll get back to you if I need more info.

Sbozzolo avatar Jul 21 '20 15:07 Sbozzolo

Would a recording with rr help in investigating this? If yes, I am happy to make one.

tpapp avatar Aug 03 '20 11:08 tpapp

I understand that debugging this is complex and may not happen for a while. Since my use case actually doesn't really need the pwd (all paths are absolute), I am wondering if introducing a workaround would make sense, and what's the best way to do it (I don't insist on #378).

Eg add an advice to vterm--get-pwd that just returns "" if in a Julia inferior buffer, without calling the function?

tpapp avatar Aug 03 '20 12:08 tpapp

Bugs that can lead to a crash are critical and need to be addressed. As of recently, I've worked to improvements to the continuous integration, so that we can edit the C code with less worry that we end up breaking the package. It's still unclear to me what's the root of the problem you are finding, but I would like to find it out.

For your specific use case, you can try to replace vterm--get-pwd with something that cannot fail. Your default-directory will not be updated, but I guess that it's not a problem if you are just running an interpreter.

Sbozzolo avatar Aug 03 '20 14:08 Sbozzolo

same here, each time

/home/tux/.emacs.d.dev/elpa/vterm-20241218.331/vterm-module.so(+0x2a97) [0x7f1c4059ba97] emacs(+0x25c362) [0x55b59f648362] emacs(+0x221c9e) [0x55b59f60dc9e] /home/tux/.emacs.d.dev/eln-cache/30.1-c7a97098/vterm-9b905962-0247d9a7.eln(F767465726d2d2d6765742d707764_vterm__get_pwd_0+0x6f) [0x7f1c405d475f]

KrullBorg avatar May 09 '25 20:05 KrullBorg

I have this same problem, except it happens every time I click on an error.

I'm using emacs-libvterm com 056ad74653704bc353d8ec8ab52ac75267b7d373 GNU Emacs 30.1 (build 2, x86_64-pc-linux-gnu, X toolkit, cairo version 1.16.0, Xaw3d scroll bars) of 2025-06-04

$ emacs
Fatal error 11: Segmentation fault
Backtrace:
emacs(+0x1984f0)[0x56219a2bf4f0]
emacs(+0x4fd72)[0x56219a176d72]
emacs(+0x50289)[0x56219a177289]
emacs(+0x196a78)[0x56219a2bda78]
emacs(+0x196af9)[0x56219a2bdaf9]
/lib/x86_64-linux-gnu/libc.so.6(+0x3c050)[0x7fa82345b050]
/home/bdc34/.emacs.d/emacs-libvterm/vterm-module.so(+0x2917)[0x7fa816097917]
emacs(+0x23e612)[0x56219a365612]
emacs(+0x208f7c)[0x56219a32ff7c]
emacs(+0x2074e5)[0x56219a32e4e5]
emacs(+0x209191)[0x56219a330191]
emacs(+0x207b4b)[0x56219a32eb4b]
emacs(+0x207df1)[0x56219a32edf1]
emacs(+0x207b4b)[0x56219a32eb4b]
emacs(+0x207b4b)[0x56219a32eb4b]
emacs(+0x208901)[0x56219a32f901]
emacs(+0x208f7c)[0x56219a32ff7c]
emacs(+0x2074e5)[0x56219a32e4e5]
emacs(+0x2095bf)[0x56219a3305bf]
emacs(+0x207b4b)[0x56219a32eb4b]
emacs(+0x208901)[0x56219a32f901]
emacs(+0x204936)[0x56219a32b936]
/usr/local/bin/../lib/emacs/30.1/native-lisp/30.1-6fe72d09/preloaded/simple-fab5b0cf-4a9a0458.eln(F6e6578742d6572726f722d696e7465726e616c_next_error_internal_0+0x58)[0x7fa81e901278]
emacs(+0x204936)[0x56219a32b936]
/home/bdc34/.emacs.d/eln-cache/30.1-6fe72d09/compile-91e1c2a0-df231367.eln(F636f6d70696c652d676f746f2d6572726f72_compile_goto_error_0+0x195)[0x7fa81c172635]
emacs(+0x204936)[0x56219a32b936]
emacs(+0x20068e)[0x56219a32768e]
emacs(+0x204936)[0x56219a32b936]
emacs(+0x204ed2)[0x56219a32bed2]
emacs(+0x201f99)[0x56219a328f99]
/usr/local/bin/../lib/emacs/30.1/native-lisp/30.1-6fe72d09/preloaded/simple-fab5b0cf-4a9a0458.eln(F636f6d6d616e642d65786563757465_command_execute_0+0x28d)[0x7fa81e90ebad]
emacs(+0x204936)[0x56219a32b936]
emacs(+0x18aeb7)[0x56219a2b1eb7]
emacs(+0x203127)[0x56219a32a127]
emacs(+0x176d56)[0x56219a29dd56]
emacs(+0x203081)[0x56219a32a081]
emacs(+0x176cf1)[0x56219a29dcf1]
emacs(+0x17e443)[0x56219a2a5443]
emacs(+0x17e7b0)[0x56219a2a57b0]
emacs(+0x5902c)[0x56219a18002c]
/lib/x86_64-linux-gnu/libc.so.6(+0x2724a)[0x7fa82344624a]
...
Segmentation fault (core dumped)

bdc34 avatar Jun 28 '25 00:06 bdc34

The bt shows a problem with get_row_directory so similar problem to @tpapp

#8  <signal handler called>
#9  0x00007fa50fa0e917 in get_row_directory (row=<optimized out>, term=0x562d36c63330) at /home/bdc34/.emacs.d/emacs-libvterm/vterm-module.c:212
#10 Fvterm_get_pwd (env=0x7ffcee68ecf0, nargs=<optimized out>, args=0x7ffcee68dc70, data=<optimized out>) at /home/bdc34/.emacs.d/emacs-libvterm/vterm-module.c:1402
#11 0x0000562cfc5d0747 in funcall_module (function=0x562d34bb6f95, nargs=2, arglist=0x7ffcee68ef20) at emacs-module.c:1282
...
(gdb) p *term
$2 = {vt = 0x5576b6014120, vts = 0x5576b22cc890, sb_buffer = 0x5576b5623560, sb_current = 260, sb_size = 1000, sb_pending = 0, sb_pending_by_height_decr = 0, sb_clear_pending = false, linenum = 306, linenum_added = 0, 
  invalid_start = 2147483647, invalid_end = -1, is_invalidated = false, cursor = {row = 45, col = 32, cursor_type = -1, cursor_visible = true, cursor_blink = false, cursor_type_changed = false, 
    cursor_blink_changed = false}, title = 0x5576b6b04900 "bdc34@soup: ~/workspace/submit-ce", title_changed = false, directory = 0x0, directory_changed = false, elisp_code_first = 0x0, 
  elisp_code_p_insert = 0x5576b56201f8, selection_mask = 0, selection_data = 0x0, 
  selection_buf = "\b\000\002\000\036", '\000' <repeats 11 times>, "r\000\000\000\377\377\377\377\032\000\000\000\000\000\000\000\305\001B\265vU\000\000\021\000\037\000\t\000\000\000\b\000\362\377\036\000\200\377\000\000\000\000\000\000\000\000m\000\000\000\000\000\000\000\033\000\000\000\000\000\000\000\305\001B\265vU\000\000\021\000\037\000\t\000\000\000\b\000\002", '\000' <repeats 13 times>, "-\000\000\000\377\377\377\377\034\000\000\000\000\000\000\000\305\001B\265vU\000\000\021\000\037\000\t\000\000\000\b\000\362\377\000\000\200\377\000\000\000\000\000\000\000\000y\000\000\000\000\000\000\000\035\000\000\000\000\000\000\000\305\001B\265vU\000\000\021\000\037\000\t\000\000\000\b\000\002", '\000' <repeats 13 times>..., 
  lines = 0x5576b4516ce0, lines_len = 46, width = 224, height = 46, height_resize = 0, resizing = false, disable_bold_font = false, disable_underline = false, 
  disable_inverse_video = false, ignore_blink_cursor = true, cmd_buffer = 0x0, pty_fd = 21}

bdc34 avatar Jun 28 '25 01:06 bdc34

This code prevents the segfault, but it causes the jump to source line to not work correctly and show this in the minibuffer:

Image

If I enter manually the correct base directory it then works.

static char *get_row_directory(Term *term, int row) {
  if (row < 0) {
    ScrollbackLine *sbrow = term->sb_buffer[-row - 1];
    if ( sbrow && sbrow->info && sbrow->info->directory ) {
      return sbrow->info->directory;
    } else {
      return NULL;
    }
  } else {
    LineInfo *line = term->lines[row];
    return line ? line->directory : NULL;
  }
}

bdc34 avatar Jun 28 '25 02:06 bdc34