What happens: $ ./busybox ash BusyBox v1.15.2 (2009-11-25 04:37:07 CET) built-in shell (ash) Enter 'help' for a list of built-in commands. $ arg='boot=cdrom' $ echo $arg boot=cdrom $ BOOT="${arg#boot=}" (locks forever...) ^C $ 1.15.1 didn't have this problem. Applying this patch to 1.15.2 http://hg.geexbox.org/geexbox?cmd=changeset;node=78663e485688 fixes the problem, so the code responsible for the regression is someplace in there. Regards, Davide
Cannot reproduce. Please attach your .config. Also, what gcc -v says on the build machine?
You can see the config at http://hg.geexbox.org/geexbox/file/3a28edd74597/packages/busybox/config/busybox.conf I build busybox as part of GeeXboX, which builds and uses a cross toolchain. The output of gcc -v (i586-geexbox-linux-gnu-gcc) on an x86_64 host, targeting i586 is Using built-in specs. Target: i586-geexbox-linux-gnu Configured with: ../configure --host=x86_64-unknown-linux-gnu --build=x86_64-unknown-linux-gnu --target=i586-geexbox-linux-gnu --prefix=/home/davide/geexbox/build.i386.eglibc/toolchain --with-sysroot=/home/davide/geexbox/build.i386.eglibc/toolchain/i586-geexbox-linux-gnu/sysroot --with-local-prefix=/usr/local --with-gmp=/home/davide/geexbox/build.i386.eglibc/toolchain --with-mpfr=/home/davide/geexbox/build.i386.eglibc/toolchain --enable-languages=c,c++ --disable-__cxa_atexit --disable-libmudflap --disable-libssp --disable-multilib --enable-shared --enable-c99 --enable-long-long --enable-threads=posix --enable-tls --disable-nls Thread model: posix gcc version 4.4.1 (GCC) Please note that this particular toolchain uses eglibc, but the same problem happens using glibc. Davide
Can't reproduce it with your config. Since the config is from 1.15.0, I tried both 1.15.0 and 1.15.2. Both work with your testcase on my system. My gcc: # gcc -v Using built-in specs. Target: i386-pc-linux-gnu Configured with: ../gcc-4.2.1/configure --prefix=/usr/app/gcc-4.2.1 --exec-prefix=/usr/app/gcc-4.2.1 --bindir=/usr/bin --sbindir=/usr/sbin --libexecdir=/usr/app/gcc-4.2.1/libexec --datadir=/usr/app/gcc-4.2.1/share --sysconfdir=/etc --sharedstatedir=/usr/app/gcc-4.2.1/var/com --localstatedir=/usr/app/gcc-4.2.1/var --libdir=/usr/lib --includedir=/usr/include --infodir=/usr/info --mandir=/usr/man --with-slibdir=/usr/app/gcc-4.2.1/lib --with-local-prefix=/usr/local --with-gxx-include-dir=/usr/app/gcc-4.2.1/include/g++-v3 --enable-languages=c,c++ --without-system-zlib --disable-nls --enable-threads=posix i386-pc-linux-gnu Thread model: posix gcc version 4.2.1 Can you identify the part of ash.c where it loops?
Does this help you? Is there any specific test I can do? davide@sfera:~/geexbox/dev/geexbox-davide$ gdb ./build.i386.eglibc/busybox-1.15.2/busybox_unstripped GNU gdb (GDB) 7.0-debian Copyright (C) 2009 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-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home/davide/geexbox/dev/geexbox-davide/build.i386.eglibc/busybox-1.15.2/busybox_unstripped...done. (gdb) run sh Starting program: /home/davide/geexbox/dev/geexbox-davide/build.i386.eglibc/busybox-1.15.2/busybox_unstripped sh BusyBox v1.15.2 (2009-11-28 18:04:26 CET) built-in shell (ash) Enter 'help' for a list of built-in commands. $ arg='boot=cdrom' $ BOOT="${arg#boot=}" ^C Program received signal SIGINT, Interrupt. 0x08061625 in evalvar (p=0x80991f8 "boot\201=\203\210", flags=<value optimized out>, var_str_list=0x80991d0) at shell/ash.c:6634 6634 if (subtype != VSNORMAL) { /* skip to end of alternative */ (gdb) bt #0 0x08061625 in evalvar (p=0x80991f8 "boot\201=\203\210", flags=<value optimized out>, var_str_list=0x80991d0) at shell/ash.c:6634 #1 argstr (p=0x80991f8 "boot\201=\203\210", flags=<value optimized out>, var_str_list=0x80991d0) at shell/ash.c:5964 #2 0x0806187b in expandarg (arg=<value optimized out>, arglist=<value optimized out>, flag=4) at shell/ash.c:7023 #3 0x08063f8e in evalcommand (cmd=0x8099214, flags=0) at shell/ash.c:9027 #4 0x08060ba5 in evaltree (n=0x8099214, flags=0) at shell/ash.c:8218 #5 0x080629fd in cmdloop (top=<value optimized out>) at shell/ash.c:11938 #6 0x08063931 in ash_main (argc=1, argv=0xffffd488) at shell/ash.c:13322 #7 0x0804cbca in run_applet_no_and_exit (applet_no=65, argv=0xffffd488) at libbb/appletlib.c:741 #8 0x0804cbef in run_applet_and_exit (name=0xffffd64f "sh", argv=0xffffd488) at libbb/appletlib.c:748 #9 0x0804cdd4 in busybox_main (name=<value optimized out>, argv=0xffffd488) at libbb/appletlib.c:713 #10 run_applet_and_exit (name=<value optimized out>, argv=0xffffd488) at libbb/appletlib.c:750 #11 0x0804ce58 in main (argc=2, argv=0xffffd484) at libbb/appletlib.c:785 (gdb)
I added two prints near that place (in 1.15.2): end: bb_error_msg("p:'%s'", p); if (subtype != VSNORMAL) { /* skip to end of alternative */ int nesting = 1; for (;;) { char c = *p++; bb_error_msg("c:%u '%c'", c, c); if (c == CTLESC) p++; else if (c == CTLBACKQ || c == (CTLBACKQ|CTLQUOTE)) { if (varlen >= 0) argbackq = argbackq->next; } else if (c == CTLVAR) { if ((*p++ & VSTYPE) != VSNORMAL) nesting++; } else if (c == CTLENDVAR) { if (--nesting == 0) break; } } } return p; } and I see this: # arg='boot=cdrom' # BOOT="${arg#boot=}" ash: p:'boot=' ash: c:98 'b' ash: c:111 'o' ash: c:111 'o' ash: c:116 't' ash: c:129 '' ash: c:131 '' # What do you see?
Created attachment 767 [details] program output I've attached the output I get as out.bz2. When it ends busybox segfaults with (cut) sh: c:0 '' sh: c:0 '' sh: c:0 '' Program received signal SIGSEGV, Segmentation fault. evalvar (p=0x80ba000 <Address 0x80ba000 out of bounds>, flags=<value optimized out>, var_str_list=0x80991d0) at shell/ash.c:6638 6638 char c = *p++; (gdb) bt #0 evalvar (p=0x80ba000 <Address 0x80ba000 out of bounds>, flags=<value optimized out>, var_str_list=0x80991d0) at shell/ash.c:6638 #1 argstr (p=0x80ba000 <Address 0x80ba000 out of bounds>, flags=<value optimized out>, var_str_list=0x80991d0) at shell/ash.c:5964 #2 0x08061896 in expandarg (arg=<value optimized out>, arglist=<value optimized out>, flag=4) at shell/ash.c:7025 #3 0x08063f9c in evalcommand (cmd=0x8099214, flags=0) at shell/ash.c:9029 #4 0x08060ba5 in evaltree (n=0x8099214, flags=0) at shell/ash.c:8220 #5 0x08062a0b in cmdloop (top=<value optimized out>) at shell/ash.c:11940 #6 0x0806393f in ash_main (argc=1, argv=0xffffd488) at shell/ash.c:13324 #7 0x0804cbca in run_applet_no_and_exit (applet_no=65, argv=0xffffd488) at libbb/appletlib.c:741 #8 0x0804cbef in run_applet_and_exit (name=0xffffd64f "sh", argv=0xffffd488) at libbb/appletlib.c:748 #9 0x0804cdd4 in busybox_main (name=<value optimized out>, argv=0xffffd488) at libbb/appletlib.c:713 #10 run_applet_and_exit (name=<value optimized out>, argv=0xffffd488) at libbb/appletlib.c:750 #11 0x0804ce58 in main (argc=2, argv=0xffffd484) at libbb/appletlib.c:785 (gdb)
I have an idea what it can be. Please try this patch: http://busybox.net/downloads/fixes-1.15.2/busybox-1.15.2-ash.patch
With your last patch applied 1.15.2 works fine $ arg='boot=cdrom' $ BOOT="${arg#boot=}" $ echo $BOOT cdrom $
What does i586-geexbox-linux-gnu-gcc -funsigned-char -static-libgcc -S -o /dev/null -xc /dev/null; echo $? print? When you do: touch shell/ash.c; make V=1 do you see -funsigned-char in gcc's command line used to rebuild ash.c?
(In reply to comment #9) > What does > i586-geexbox-linux-gnu-gcc -funsigned-char -static-libgcc -S -o /dev/null -xc > /dev/null; echo $? > print? 0 > When you do: > touch shell/ash.c; make V=1 > do you see -funsigned-char in gcc's command line used to rebuild ash.c? No. The full output is /home/davide/geexbox/build.i386.eglibc/toolchain/bin/i586-geexbox-linux-gnu-gcc -Wp,-MD,shell/.ash.o.d -Iinclude -Ilibbb -include include/autoconf.h -D_GNU_SOURCE -DNDEBUG -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D"BB_VER=KBUILD_STR(1.15.2)" -DBB_BT=AUTOCONF_TIMESTAMP -Os -Wall -pipe -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -mtune=generic -march=i586 -s -fomit-frame-pointer -Wold-style-definition -std=gnu99 -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(ash)" -D"KBUILD_MODNAME=KBUILD_STR(ash)" -c -o shell/ash.o shell/ash.c make -f scripts/Makefile.build obj=util-linux make -f scripts/Makefile.build obj=util-linux/volume_id shell/ash.c: In function 'exptilde': shell/ash.c:5614: warning: case label value exceeds maximum value for type shell/ash.c:5616: warning: case label value exceeds maximum value for type shell/ash.c:5623: warning: case label value exceeds maximum value for type rm -f shell/lib.a; /home/davide/geexbox/build.i386.eglibc/toolchain/bin/i586-geexbox-linux-gnu-ar rcs shell/lib.a shell/ash.o shell/ash_ptr_hack.o shell/math.o
This means that this in Makefile.flags: CFLAGS += $(call cc-option,-funsigned-char -static-libgcc,) does not think your gcc supports these flags. cc-option is (in scripts/Kbuild.include): cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \ > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;) Since bare "i586-geexbox-linux-gnu-gcc -funsigned-char -static-libgcc" works for you, I conclude either $(CC) or $(CFLAGS) expand to something strange. Can you replace cc-option definition with cc-option = $(shell echo "$(CC) $(CFLAGS) $(1)" >>/tmp/cc_cflags; if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \ > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;) , run "touch shell/ash.c; make" again and attach resulting /tmp/cc_cflags to this bug?
Created attachment 775 [details] /tmp/cc_cflags Here's the resulting /tmp/cc_cflags.
Looks like cc-options works, and you have this long string: -Wall -Wshadow -Wwrite-strings -Wundef -Wstrict-prototypes -Wunused -Wunused-parameter -Wunused-function -Wunused-value -Wmissing-prototypes -Wmissing-declarations -Wdeclaration-after-statement -Wold-style-definition -fno-builtin-strlen -finline-limit=0 -fomit-frame-pointer -ffunction-sections -fdata-sections -fno-guess-branch-probability -funsigned-char -static-libgcc -falign-functions=1 -falign-jumps=1 -falign-labels=1 -falign-loops=1 -Os -march=i386 -mpreferred-stack-boundary=2 added piece-by-piece to CFLAGS. Bu then it gets lost, and ash.c is compiled without any of these flags. This is wrong. Do you pass CFLAGS to make in environment or on make commandline? For one, where "-pipe -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -mtune=generic -march=i586" section come from? busybox doesn't have "-pipe" anywhere in the tree.
After unpacking the tarball, our unpack script does cat <<EOF >$BUSYBOX/Makefile.custom HOSTCC = $HOST_CC CROSS_COMPILE = $TARGET_PREFIX CFLAGS += -std=gnu99 EOF where TARGET_PREFIX is our toolchain prefix and HOST_CC points to the system (not crosscompiler) gcc. The actual script to build busybox simply does ARCH=$TARGET_ARCH make $1 from busybox sources directory. On my system TARGET_ARCH=i386 (I compile for an x86 target on an x86_64 build machine). The build script runs in a special environment where, among others, the following variables are set: CC=/home/davide/geexbox/build.i386.eglibc/toolchain/bin/i586-geexbox-linux-gnu-gcc CFLAGS='-Os -Wall -pipe -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -mtune=generic -march=i586 -s -fomit-frame-pointer' CXX=/home/davide/geexbox/build.i386.eglibc/toolchain/bin/i586-geexbox-linux-gnu-g++ CXXFLAGS='-Os -Wall -pipe -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -mtune=generic -march=i586 -s -fomit-frame-pointer' LDFLAGS=' -s' HOST_CC=/home/davide/geexbox/build.i386.eglibc/toolchain/bin/host-gcc HOST_CFLAGS='-O2 -Wall -pipe' HOST_CPPFLAGS= HOST_CXX=/home/davide/geexbox/build.i386.eglibc/toolchain/bin/host-g++ HOST_LD=ld HOST_LDFLAGS=
(In reply to comment #14) > where TARGET_PREFIX is our toolchain prefix and HOST_CC points to the system > (not crosscompiler) gcc. The actual script to build busybox simply does > ARCH=$TARGET_ARCH make $1 To clarify, $1 == package name, so the expanded command is ARCH=i386 make busybox
I tried this: # touch shell/ash.c; CFLAGS='-Os -Wall -pipe -mtune=generic -march=i586 -s -fomit-frame-pointer' make V=1 shell/ash.o and I get this (with my .config): ... i486-linux-uclibc-gcc -Wp,-MD,shell/.ash.o.d -std=gnu99 -Iinclude -Ilibbb -include include/autoconf.h -D_GNU_SOURCE -DNDEBUG -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D"BB_VER=KBUILD_STR(1.16.0.git)" -DBB_BT=AUTOCONF_TIMESTAMP -Os -Wall -pipe -mtune=generic -march=i586 -s -fomit-frame-pointer -Wall -Wshadow -Wwrite-strings -Wundef -Wstrict-prototypes -Wunused -Wunused-parameter -Wunused-function -Wunused-value -Wmissing-prototypes -Wmissing-declarations -Wdeclaration-after-statement -Werror -Wold-style-definition -fno-builtin-strlen -finline-limit=0 -fomit-frame-pointer -ffunction-sections -fdata-sections -fno-guess-branch-probability -funsigned-char -static-libgcc -falign-functions=1 -falign-jumps=1 -falign-labels=1 -falign-loops=1 -Os -march=i386 -mpreferred-stack-boundary=2 -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(ash)" -D"KBUILD_MODNAME=KBUILD_STR(ash)" -c -o shell/ash.o shell/ash.c Note that -funsigned-char *is present*. With CFLAGS set as make parameter, I get this: # touch shell/ash.c; make V=1 shell/ash.o CFLAGS='-Os -Wall -pipe -mtune=generic -march=i586 -s -fomit-frame-pointer' ... i486-linux-uclibc-gcc -Wp,-MD,shell/.ash.o.d -std=gnu99 -Iinclude -Ilibbb -include include/autoconf.h -D_GNU_SOURCE -DNDEBUG -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D"BB_VER=KBUILD_STR(1.16.0.git)" -DBB_BT=AUTOCONF_TIMESTAMP -Os -Wall -pipe -mtune=generic -march=i586 -s -fomit-frame-pointer -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(ash)" -D"KBUILD_MODNAME=KBUILD_STR(ash)" -c -o shell/ash.o shell/ash.c Now -funsigned-char is missing. Looks more like what you are seeing. Can you determine what exactly causes -funsigned-char to disappear from your command line in your environment?
Using ARCH=$TARGET_ARCH make $1 V=1 in the build script (CFLAGS set in the environment) I get /home/davide/geexbox/dev/geexbox-davide/build.i386.eglibc/toolchain/bin/i586-geexbox-linux-gnu-gcc -Wp,-MD,shell/.ash.o.d -Iinclude -Ilibbb -include include/autoconf.h -D_GNU_SOURCE -DNDEBUG -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D"BB_VER=KBUILD_STR(1.15.2)" -DBB_BT=AUTOCONF_TIMESTAMP -Os -Wall -pipe -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -mtune=generic -march=i586 -g3 -Wold-style-definition -std=gnu99 -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(ash)" -D"KBUILD_MODNAME=KBUILD_STR(ash)" -c -o shell/ash.o shell/ash.c Forcing CFLAGS with -funsigned-char in the environment ARCH=$TARGET_ARCH CFLAGS="$CFLAGS -funsigned-char" make $1 V=1 /home/davide/geexbox/dev/geexbox-davide/build.i386.eglibc/toolchain/bin/i586-geexbox-linux-gnu-gcc -Wp,-MD,shell/.ash.o.d -Iinclude -Ilibbb -include include/autoconf.h -D_GNU_SOURCE -DNDEBUG -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D"BB_VER=KBUILD_STR(1.15.2)" -DBB_BT=AUTOCONF_TIMESTAMP -Os -Wall -pipe -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -mtune=generic -march=i586 -g3 -funsigned-char -Wold-style-definition -std=gnu99 -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(ash)" -D"KBUILD_MODNAME=KBUILD_STR(ash)" -c -o shell/ash.o shell/ash.c Passing CFLAGS as make parameter ARCH=$TARGET_ARCH make $1 CFLAGS="$CFLAGS" V=1 /home/davide/geexbox/dev/geexbox-davide/build.i386.eglibc/toolchain/bin/i586-geexbox-linux-gnu-gcc -Wp,-MD,shell/.ash.o.d -Iinclude -Ilibbb -include include/autoconf.h -D_GNU_SOURCE -DNDEBUG -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D"BB_VER=KBUILD_STR(1.15.2)" -DBB_BT=AUTOCONF_TIMESTAMP -Os -Wall -pipe -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -mtune=generic -march=i586 -g3 -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(ash)" -D"KBUILD_MODNAME=KBUILD_STR(ash)" -c -o shell/ash.o shell/ash.c Forcing CFLAGS with -funsigned-char as make parameter ARCH=$TARGET_ARCH make $1 CFLAGS="$CFLAGS -funsigned-char" V=1 /home/davide/geexbox/dev/geexbox-davide/build.i386.eglibc/toolchain/bin/i586-geexbox-linux-gnu-gcc -Wp,-MD,shell/.ash.o.d -Iinclude -Ilibbb -include include/autoconf.h -D_GNU_SOURCE -DNDEBUG -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D"BB_VER=KBUILD_STR(1.15.2)" -DBB_BT=AUTOCONF_TIMESTAMP -Os -Wall -pipe -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -mtune=generic -march=i586 -g3 -funsigned-char -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(ash)" -D"KBUILD_MODNAME=KBUILD_STR(ash)" -c -o shell/ash.o shell/ash.c
(In reply to comment #14) > After unpacking the tarball, our unpack script does > cat <<EOF >$BUSYBOX/Makefile.custom > HOSTCC = $HOST_CC > CROSS_COMPILE = $TARGET_PREFIX > CFLAGS += -std=gnu99 > EOF Wait a second. This basically nukes Makefile.custom! Why do you do it? You aren't satisfied with Makefile.custom as shipped? I propose stopping doing that, and also passing any additional CFLAGS you need in EXTRA_CFLAGS, leaving CFLAGS not set. Anyway, the problem seems to be solved. And it is partially caused by you messing up build system. (On the bright side, ash.c code now is less buggy wrt architectures with signed chars).
(In reply to comment #18) > (In reply to comment #14) > > After unpacking the tarball, our unpack script does > > cat <<EOF >$BUSYBOX/Makefile.custom > > HOSTCC = $HOST_CC > > CROSS_COMPILE = $TARGET_PREFIX > > CFLAGS += -std=gnu99 > > EOF > > Wait a second. This basically nukes Makefile.custom! Why do you do it? You > aren't satisfied with Makefile.custom as shipped? Looks like this was an old workaround that somehow managed to stay in place. Thanks for spotting it, I've removed it. > I propose stopping doing that, and also passing any additional CFLAGS you need > in EXTRA_CFLAGS, leaving CFLAGS not set. > Anyway, the problem seems to be solved. And it is partially caused by you > messing up build system. (On the bright side, ash.c code now is less buggy wrt > architectures with signed chars). I rewrote our busybox build script according to your suggestions and it works fine now, feel free to close this bug. Thanks for your help Davide
Fixed in 1.15.3