[Bug 276935] tcsh crash in rehist()
Date: Fri, 09 Feb 2024 23:15:44 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=276935 Bug ID: 276935 Summary: tcsh crash in rehist() Product: Base System Version: 15.0-CURRENT Hardware: Any OS: Any Status: New Severity: Affects Only Me Priority: --- Component: standards Assignee: standards@FreeBSD.org Reporter: joyul@juniper.net Hi teams, I encountered a crash in rehist() and below is its backtrace. In frame 3, cleanup_sp is 0, which means it's already at the bottom of the cleanup_stack, but last_var cannot be found. It seems like in rehist(), it invokes setexit() without updating cleanup_mark. If the program goes to error handling to reset the clean_stack[], it will clean more than required, which should be handled by cleanup_until() when the program jumps back to rehist(). I'm providing a patch below that might fix it. Feel free to apply it to the tcsh git, FreeBSD baseline, or fix it using other solutions. We can downstream it to our local and try it. Thank you. diff --git a/contrib/tcsh/sh.hist.c b/contrib/tcsh/sh.hist.c index 14d862a3e7b..09f4814dbe3 100644 --- a/contrib/tcsh/sh.hist.c +++ b/contrib/tcsh/sh.hist.c @@ -1235,6 +1235,7 @@ rechist(Char *xfname, int ref) struct stat st; static Char *fname; static Char *dumphist[] = {STRhistory, STRmhT, 0, 0}; + size_t omark; if (fname == NULL && !ref) return; @@ -1308,8 +1309,10 @@ rechist(Char *xfname, int ref) #endif } getexit(osetexit); + omark = cleanup_push_mark(); if (setexit() == 0) loadhist(fname, 1); + cleanup_pop_mark(omark); resexit(osetexit); } } (gdb) bt #0 thr_kill () at thr_kill.S:4 #1 0x0000000001b7ee61 in __raise (s=s@entry=6) at /.amd/svl-engdata5vs2/occamdev/build/freebsd/main/sandbox-main-202401181141/freebsd/main/20240118.171413__ci_fbsd_builder_main.c38f35a/src/lib/libc/gen/raise.c:50 #2 0x0000000001c1cca9 in abort () at /.amd/svl-engdata5vs2/occamdev/build/freebsd/main/sandbox-main-202401181141/freebsd/main/20240118.171413__ci_fbsd_builder_main.c38f35a/src/lib/libc/stdlib/abort.c:64 #3 0x000000000022148c in cleanup_until (last_var=0x1cc33c26ee80) at /src/contrib/tcsh/sh.err.c:470 #4 0x000000000022e68f in rechist (xfname=xfname@entry=0x0, ref=<optimized out>) at /src/contrib/tcsh/sh.hist.c:1327 #5 0x000000000021b2d0 in record () at /src/contrib/tcsh/sh.c:2539 #6 0x000000000021b3e1 in phup () at /src/contrib/tcsh/sh.c:1856 #7 0x0000000000261440 in handle_pending_signals () at /src/contrib/tcsh/tc.sig.c:67 #8 0x0000000000233c55 in xwrite (fildes=18, buf=0x28d170 <linbuf>, nbyte=11) at /src/contrib/tcsh/sh.misc.c:719 #9 0x00000000002352ff in flush () at /src/contrib/tcsh/sh.print.c:256 #10 0x00000000002351d3 in xputchar (c=<optimized out>, c@entry=10) at /src/contrib/tcsh/sh.print.c:183 #11 0x0000000000235dcf in pprint (pp=0x1cc33c210a00, flag=160) at /src/contrib/tcsh/sh.proc.c:1178 #12 0x0000000000236385 in pjwait (pp=0x1cc33c210a00) at /src/contrib/tcsh/sh.proc.c:543 #13 0x00000000002361ab in pwait () at /src/contrib/tcsh/sh.proc.c:473 #14 0x0000000000238c9d in execute (t=0x1cc33c25e090, wanttty=28987, pipein=<optimized out>, pipeout=0x0, do_glob=do_glob@entry=1) at /src/contrib/tcsh/sh.sem.c:623 #15 0x0000000000238983 in execute (t=t@entry=0x1cc33c25e060, wanttty=28987, pipein=<optimized out>, pipein@entry=0x0, pipeout=pipeout@entry=0x0, do_glob=do_glob@entry=1) at /src/contrib/tcsh/sh.sem.c:724 #16 0x000000000021af01 in process (catch=<optimized out>) at /src/contrib/tcsh/sh.c:2166 #17 0x0000000000219d1e in main (argc=<optimized out>, argv=0x820710290) at /src/contrib/tcsh/sh.c:1431 (gdb) f 4 #4 0x000000000022e68f in rechist (xfname=xfname@entry=0x0, ref=<optimized out>) at /src/contrib/tcsh/sh.hist.c:1327 (gdb) f 3 #3 0x000000000022148c in cleanup_until (last_var=0x1cc33c26ee80) at /src/contrib/tcsh/sh.err.c:470 470 abort(); (gdb) list 456 while (cleanup_sp != 0) { 457 struct cleanup_entry ce; 458 459 cleanup_sp--; 460 461 ce = cleanup_stack[cleanup_sp]; 462 ce.fn(ce.var); 463 #ifdef CLEANUP_DEBUG 464 syslog(LOG_INFO,"[tcsh][cleanup_until] cleanup_sp %zu, file %s, line %zu, var %p\n", cleanup_sp, ce.file, ce.line, ce.var); 465 #endif 466 if (ce.var == last_var) 467 return; 468 } 469 syslog(LOG_INFO, "abort in cleanup_until\n"); 470 abort(); 471 } 472 (gdb) p cleanup_sp $3 = 0 -- You are receiving this mail because: You are the assignee for the bug.