Hi, I have this test case:
---8<--- #!/bin/ksh toto="s" alarm -r alarm_handler +1 function alarm_handler.alarm { if [[ $toto == "s" ]] then toto="e" else toto="f" fi } IFS="," (echo "2";sleep 1;echo "3") | while IFS="," read arg1 #(echo "2";sleep 1;echo "3") | while read arg1 do print "$arg1" done ---8<--- provided by a user. The test case causes it to start reading random memory in src/cmd/ksh93/bltins/read.c in this chunk of sh_readline: ---%<--- /* skip over word characters */ wrd = -1; while(1) { while((c=shp->ifstable[*cp++])==0) <<<=== HERE if(!wrd) wrd = 1; ---%<--- A example gdb session after finding the root of the problem is: ---%<--- $ gdb --args /home/pcpa/rhel/ksh/ksh-20120801/arch/linux.i386-64/bin/ksh t2.ksh GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-51.el7 Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home/pcpa/rhel/ksh/ksh-20120801/arch/linux.i386-64/bin/ksh...done. (gdb) b sh_readline Breakpoint 1 at 0x4825f9: file /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/bltins/read.c, line 215. (gdb) r Starting program: /home/pcpa/rhel/ksh/ksh-20120801/arch/linux.i386-64/bin/ksh t2.ksh Detaching after fork from child process 11872. Breakpoint 1, sh_readline (shp=0x795300 <sh>, names=0x7ffff7fae9a8, fd=0, flags=0, size=0, timeout=0) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/bltins/read.c:215 215 char was_escape = 0; Missing separate debuginfos, use: debuginfo-install glibc-2.17-55.el7_0.1.x86_64 (gdb) p &shp->ifstable [0] $1 = 0x795930 <sh+1584> "" (gdb) watch *(char*)$1 Hardware watchpoint 2: *(char*)$1 (gdb) p $1 $2 = 0x795930 <sh+1584> "" (gdb) c Continuing. Hardware watchpoint 2: *(char*)$1 Old value = 0 '\000' New value = 2 '\002' sh_readline (shp=0x7fffffffc0dc, names=0x7ffff7fae9b0, fd=0, flags=0, size=0, timeout=0) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/bltins/read.c:310 310 if((flags&SS_FLAG)) (gdb) bt #0 sh_readline (shp=0x7fffffffc0dc, names=0x7ffff7fae9b0, fd=0, flags=0, size=0, timeout=0) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/bltins/read.c:310 #1 0x00000000004824ef in b_read (argc=2, argv=0x7ffff7fae9a8, context=0x795810 <sh+1296>) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/bltins/read.c:177 #2 0x0000000000466b98 in sh_exec (t=0x7fffffffc0dc, flags=512) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:1410 #3 0x000000000046a326 in sh_exec (t=0x7fffffffc0dc, flags=4) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:2485 #4 0x0000000000468847 in sh_exec (t=0x7fffffffc0dc, flags=4) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:1978 #5 0x00000000004693d2 in sh_exec (t=0x7fffffffc0dc, flags=4) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:2195 #6 0x000000000040738f in exfile (shp=0x7fffffffc0dc, iop=0x7ffff7f930e1, fno=0) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/main.c:581 #7 0x0000000000406847 in sh_main (ac=2, av=0x7fffffffe0a8, userinit=0x0) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/main.c:353 #8 0x0000000000405c55 in main (argc=2, argv=0x7fffffffe0a8) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/pmain.c:45 (gdb) c Continuing. Hardware watchpoint 2: *(char*)$1 Old value = 2 '\002' New value = 0 '\000' 0x00007ffff739bc1f in __memset_sse2 () from /lib64/libc.so.6 (gdb) bt #0 0x00007ffff739bc1f in __memset_sse2 () from /lib64/libc.so.6 #1 0x0000000000421cd3 in get_ifs (np=0x7ffff7fb0b38, fp=0x7ffff7fb0610) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/init.c:546 #2 0x0000000000407a49 in nv_getv (np=0x7ffff7fb0b38, nfp=0x795930 <sh+1584>) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/nvdisc.c:58 #3 0x0000000000448b6e in nv_getval (np=0x7ffff7fb0b38) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/name.c:2801 #4 0x0000000000447da2 in table_unset (shp=0x795300 <sh>, root=0x7ffff7f93290, flags=524289, oroot=0x7ffff7fcaf80) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/name.c:2446 #5 0x000000000044ab37 in sh_unscope (shp=0x795300 <sh>) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/name.c:3548 #6 0x000000000046d760 in sh_funscope (argn=1, argv=0x7fffffffb9c8, fun=0x0, arg=0x7fffffffb8e0, execflg=0) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:3482 #7 0x000000000046dc27 in sh_funct (shp=0x795300 <sh>, np=0x7ffff7f92910, argn=1, argv=0x7fffffffb9c8, envlist=0x0, execflg=0) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:3556 #8 0x000000000046e1dd in sh_fun (np=0x7ffff7f92910, nq=0x7ffff7f92240, argv=0x7fffffffb9c8) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:3630 #9 0x000000000047952c in sh_timetraps (shp=0x795300 <sh>) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/bltins/alarm.c:144 #10 0x00000000004794ab in trap_timeout (handle=0x7ffff7f922d0) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/bltins/alarm.c:126 #11 0x0000000000461456 in sigalrm (sig=14) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/timers.c:162 #12 <signal handler called> #13 _sffilbuf (f=0x792dc0 <_Sfstdin>, n=-1) at /home/pcpa/rhel/ksh/ksh-20120801/src/lib/libast/sfio/sffilbuf.c:94 #14 0x00000000004e0556 in sfgetr (f=0x792dc0 <_Sfstdin>, rc=10, type=0) at /home/pcpa/rhel/ksh/ksh-20120801/src/lib/libast/sfio/sfgetr.c:81 #15 0x0000000000483830 in sh_readline (shp=0x792dc0 <_Sfstdin>, names=0x7ffff7fae9b0, fd=0, flags=0, size=0, timeout=0) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/bltins/read.c:496 #16 0x00000000004824ef in b_read (argc=2, argv=0x7ffff7fae9a8, context=0x795810 <sh+1296>) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/bltins/read.c:177 #17 0x0000000000466b98 in sh_exec (t=0x792dc0 <_Sfstdin>, flags=512) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:1410 #18 0x000000000046a326 in sh_exec (t=0x792dc0 <_Sfstdin>, flags=4) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:2485 #19 0x0000000000468847 in sh_exec (t=0x792dc0 <_Sfstdin>, flags=4) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:1978 #20 0x00000000004693d2 in sh_exec (t=0x792dc0 <_Sfstdin>, flags=4) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:2195 #21 0x000000000040738f in exfile (shp=0x792dc0 <_Sfstdin>, iop=0x1, fno=65536) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/main.c:581 #22 0x0000000000406847 in sh_main (ac=2, av=0x7fffffffe0a8, userinit=0x0) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/main.c:353 #23 0x0000000000405c55 in main (argc=2, argv=0x7fffffffe0a8) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/pmain.c:45 (gdb) q A debugging session is active. Inferior 1 [process 11868] will be killed. Quit anyway? (y or n) y ---%<--- The code "memset(shp->ifstable,0,(1<<CHAR_BIT));" in src/cmd/ksh93/sh/init.c:get_ifs() is causing it to not stop when reading a null byte. The attached patch corrects the problem, but I think an alternative that could be better would be to save/restore shp->ifstable in the signal handler, or a function called by it. On a normal run, shp->ifstable would be: {2,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,39,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,} but if the alarm signal handler is called, it would become, without the patch: {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,} The patch force 0 as 2 (S_EOF), and remaining differences are 3 at offset 10, 39 at offset 92. Do you think it would be better to save/restore shp->ifstable in the alarm handler? src/cmd/ksh93/sh/timers.c:sigalrm() or some other alternative? for example, adding hardcoded shp->ifstable['\n'] = S_NL; shp->ifstable['\\'] = S_ESC; (what looks like extra sensible hardcoded defaults), or not calling memset. Thanks, Paulo
diff -up ksh-20120801/src/cmd/ksh93/sh/init.c.orig ksh-20120801/src/cmd/ksh93/sh/init.c --- ksh-20120801/src/cmd/ksh93/sh/init.c.orig 2014-12-10 20:11:17.693446084 -0200 +++ ksh-20120801/src/cmd/ksh93/sh/init.c 2014-12-10 20:11:24.753442619 -0200 @@ -576,6 +576,7 @@ static char* get_ifs(register Namval_t* shp->ifstable[' '] = shp->ifstable['\t'] = S_SPACE; shp->ifstable['\n'] = S_NL; } + shp->ifstable[0] = S_EOF; } return(value); }
_______________________________________________ ast-users mailing list ast-users@lists.research.att.com http://lists.research.att.com/mailman/listinfo/ast-users