On Tue, 19 Feb 2008, Denys Vlasenko wrote:

> I got around to trying to reproduce, and you know what?
> It works for me:

I was afraid wou'd say that :)

> sh-3.2# export RUNLEVEL=3
> sh-3.2# ./busybox ash
> /.1/usr/srcdevel/bbox/fix/busybox.t1 # for B in $RUNLEVEL; do echo $B; done
> ash: name_len:2    <====== debug
> ash: str:'echo'    <====== debug
> 3
> /.1/usr/srcdevel/bbox/fix/busybox.t1 # exit
>
> Same with unset variable:
>
> sh-3.2# ./busybox ash
> /.1/usr/srcdevel/bbox/fix/busybox.t1 # for B in $RUNLEVE; do echo $B; done
> (no output, as expected)
> /.1/usr/srcdevel/bbox/fix/busybox.t1 #

Yes.  That works for me too, x86, sort of, doesn't segfault:
  gcc (GCC) 4.2.3 (Debian 4.2.3-1)
  libc-2.7.so

Pointer values and strings (in some cases) look wrong to me.
Please see attached ash.PAGER.err.gz and ash.PAGE.err.gz.

But segfaults on cris v10:
  gcc version 3.2.1 Axis release R64/1.64
  libuClibc-0.9.27.so

> .config is attached. I build busybox against static uclibc as follows:
>
> vda_mk.sh:
>
> export ARCH=i386
> export CROSS_COMPILE=i486-linux-uclibc-
> test x"$CROSS_COMPILE" = x || cross="CROSS_COMPILE=$CROSS_COMPILE"
> nice -n 10 make $cross "$@"
>
> Can you try with my .config?

I'll check that tomorrow, when I get back to work (I need phisical access
to my embedded system).

> > ,----
> > | + [ N ]
> > | sh: LINE 5907
> > | sh: LINE 5914: name='runlevel=', name_len=9
> > | sh: LINE 5916
> > | sh: LINE 5920: var_str_list=0x00118404, str=0x001183fc
>
> Value of pointer doesn't seem to be terribly wrong.

No, not that one, but see below.

> Can you just printf str?
> bb_error_msg("LINE %d str %p '%s", __LINE__, str, str);

Ok, but (in case you missed it) the pointer value here is way off:

> > | + [ N != N ]
> > | sh: LINE 5907
> > | sh: LINE 5914: name='runlevel=.d/S??*', name_len=9
> > | sh: LINE 5916
> > | sh: LINE 5920: var_str_list=0x000b5bee, str=0x8feee1fc
> > | sh: LINE 5923
> > | rc (pid 75) segfaults for page address 8feee000 at pc 355a06a6
> > `----

And here too:

> > ,----
> > | # for B in $VAR;do echo $B;done
> > | sh: LINE 5907
> > | sh: LINE 5914: name='VAR=', name_len=4
> > | sh: LINE 5916
> > | sh: LINE 5920: var_str_list=0x000b81c2, str=0x201892c1
> > | sh: LINE 5923
> > | sh (pid 72) segfaults for page address 20188000 at pc 355a06a6
> > `----

That's why it segfaults.


Cheers,

-- 
Cristian

Attachment: ash.PAGER.err.gz
Description: Binary data

Attachment: ash.PAGE.err.gz
Description: Binary data

Index: shell/ash.c
===================================================================
--- shell/ash.c	(revision 21043)
+++ shell/ash.c	(working copy)
@@ -5904,32 +5904,52 @@
 		p = num ? shellparam.p[num - 1] : arg0;
 		goto value;
 	default:
+		bb_error_msg("LINE %d", __LINE__);
 		/* NB: name has form "VAR=..." */
 
 		/* "A=a B=$A" case: var_str_list is a list of "A=a" strings
 		 * which should be considered before we check variables. */
 		if (var_str_list) {
 			unsigned name_len = (strchrnul(name, '=') - name) + 1;
+			bb_error_msg("LINE %d: name='%s', name_len=%u",  __LINE__, name, name_len);
 			p = NULL;
+			bb_error_msg("LINE %d", __LINE__);
 			do {
+				char *eq;
 				char *str = var_str_list->text;
-				char *eq = strchr(str, '=');
+				bb_error_msg("LINE %d: var_str_list: %p, str: %p '%s'", __LINE__, var_str_list, str, str);
+				if (!str)
+					break;
+				bb_error_msg("LINE %d", __LINE__);
+				eq = strchr(str, '=');
+				bb_error_msg("LINE %d", __LINE__);
 				if (!eq) /* stop at first non-assignment */
 					break;
+				bb_error_msg("LINE %d", __LINE__);
 				eq++;
+				bb_error_msg("LINE %d", __LINE__);
 				if (name_len == (eq - str)
 				 && strncmp(str, name, name_len) == 0) {
+					bb_error_msg("LINE %d", __LINE__);
 					p = eq;
 					/* goto value; - WRONG! */
 					/* think "A=1 A=2 B=$A" */
+					bb_error_msg("LINE %d", __LINE__);
 				}
+				bb_error_msg("LINE %d", __LINE__);
 				var_str_list = var_str_list->next;
+				bb_error_msg("LINE %d", __LINE__);
 			} while (var_str_list);
+			bb_error_msg("LINE %d", __LINE__);
 			if (p)
 				goto value;
+			bb_error_msg("LINE %d", __LINE__);
 		}
+		bb_error_msg("LINE %d", __LINE__);
 		p = lookupvar(name);
+		bb_error_msg("LINE %d", __LINE__);
  value:
+		bb_error_msg("LINE %d", __LINE__);
 		if (!p)
 			return -1;
 
@@ -9115,7 +9135,7 @@
  * For a non-interactive shell, an error condition encountered
  * by a special built-in ... shall cause the shell to write a diagnostic message
  * to standard error and exit as shown in the following table:
- * Error                                           Special Built-In 
+ * Error                                           Special Built-In
  * ...
  * Utility syntax error (option or operand error)  Shall exit
  * ...
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox

Reply via email to