segmentation fault with compilation-shell-minor-mode
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.
I still have this problem --- any suggestions on isolating this would be appreciated.
You could track it down by commenting and uncommenting parts of vterm-get-pwd step by step.
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: 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.
I still get the issue with #350, so unfortunately that's not a fix (it made the crash less frequent though).
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.
Can you please try #356?
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
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>
Also using print, I checked that the second argument (or linenum (line-number-at-pos)) is an integer.
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]
That's tremendously useful. Can you continue debugging in get_row_directory?
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?)
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.
Would a recording with rr help in investigating this? If yes, I am happy to make one.
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?
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.
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]
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)
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}
This code prevents the segfault, but it causes the jump to source line to not work correctly and show this in the minibuffer:
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;
}
}