vi segfaults (bb 1.8.2)

Cristian Ionescu-Idbohrn cristian.ionescu-idbohrn at axis.com
Fri Nov 30 16:51:54 UTC 2007


On Tue, 27 Nov 2007, Cristian Ionescu-Idbohrn wrote:

> On Tue, 27 Nov 2007, Cristian Ionescu-Idbohrn wrote:
>
> > On Tue, 27 Nov 2007, Denys Vlasenko wrote:
> >
> > > Failed to reproduce it here.
> >
> > Ok.  I'll dig deeper.

Made some new discoveries.  This is the latest result (see
attachment):

  vi: HERE 100: YDreg=26, Ureg=27, text=0x000e1ca8
  vi: HERE 104: Ureg=27
  vi: HERE 200:
  vi: HERE 201:
  vi: HERE 202:
  vi: HERE 211:
  vi: HERE 105: Ureg=0
  vi: HERE 300: p=0x00000e1c, q=0x00000e1c, dest=0
  vi: HERE 301: p=0x00000e1c, q=0x00000e1c, cnt=1
  vi: HERE 302: dest=0, t=0x00000000
  vi: HERE 303: t=0x00000000
  vi: HERE 304: t=0x000e4610
  vi: HERE 305: t=0x000e4610, cnt=1
  Segmentation fault

Different things go wrong :(

'Ureg' has a different value after returning from 'get_one_char'.
'p' and 'q' addresses inside 'text_yank' are invalid (0xe1c == 3612,
that's the 1st memory page I believe).

My impression is things may get screwed up inside the 'readit'
function.

I need to do some other optimization too.  I'll get back on that later
in another post.  I tested that idea by increasing the BUFSIZ (see
include/libbb.h) from default 4096 to 8192 using:

  CFLAGS += -D"BUFSIZ=8192"

in a wrapper Makefile (keeping the modified vi.c as per attached
diff) and noted the 'vi' segfault does no longer happen.  I see this
on stderr, instead:

  vi: HERE 100: YDreg=26, Ureg=27, text=0x000e5ca8
  vi: HERE 104: Ureg=27
  vi: HERE 200:
  vi: HERE 201:
  vi: HERE 202:
  vi: HERE 211:
  vi: HERE 105: Ureg=27
  vi: HERE 300: p=0x000e5ca8, q=0x000e5ca8, dest=27
  vi: HERE 301: p=0x000e5ca8, q=0x000e5ca8, cnt=1
  vi: HERE 302: dest=27, t=0x00000000
  vi: HERE 303: t=0x00000000
  vi: HERE 304: t=0x000e8650
  vi: HERE 305: t=0x000e8650, cnt=1
  vi: HERE 306
  vi: HERE 307
  vi: HERE 104: Ureg=27
  vi: HERE 200:
  vi: HERE 205:
  vi: HERE 206:
  vi: HERE 208:
  vi: HERE 211:
  vi: HERE 105: Ureg=27
  vi: HERE 104: Ureg=27
  vi: HERE 200:
  vi: HERE 201:
  vi: HERE 202:
  vi: HERE 211:
  vi: HERE 105: Ureg=27
  vi: HERE 200:
  vi: HERE 201:
  vi: HERE 202:
  vi: HERE 211:

The 'vi' commands were: i, <esc>, ZZ.

'Ureg' doesn't change value and the 'p' and 'q' addresses inside
'text_yank' are _valid_.

I suppose that should make me feel lucky ;)
I get a usable 'vi' and at the same time a good optimization result.
But, should I feel lucky?


Cheers,

-- 
Cristian
-------------- next part --------------
--- busybox-1.8.2.orig/editors/vi.c	2007-11-10 02:40:54.000000000 +0100
+++ busybox-1.8.2/editors/vi.c	2007-11-30 17:02:24.000000000 +0100
@@ -464,6 +464,8 @@ static void edit_file(char * fn)
 	Ureg = 27;			// hold orig line for "U" cmd
 	mark[26] = mark[27] = text;	// init "previous context"
 #endif
+	bb_error_msg("HERE 100: YDreg=%d, Ureg=%d, text=0x%08x",
+				 YDreg, Ureg, text);
 
 	last_forward_char = last_input_char = '\0';
 	crow = 0;
@@ -526,9 +528,13 @@ static void edit_file(char * fn)
 			}
 		}
 #endif
-		last_input_char = c = get_one_char();	// get a cmd from user
+		bb_error_msg("HERE 104: Ureg=%d", Ureg);
+		//last_input_char = c = get_one_char();	// get a cmd from user
+		c = get_one_char();		// get a cmd from user
+		last_input_char = c;	// get a cmd from user
 #if ENABLE_FEATURE_VI_YANKMARK
 		// save a copy of the current line- for the 'U" command
+		bb_error_msg("HERE 105: Ureg=%d", Ureg);
 		if (begin_line(dot) != cur_line) {
 			cur_line = begin_line(dot);
 			text_yank(begin_line(dot), end_line(dot), Ureg);
@@ -2004,18 +2010,28 @@ static char *text_yank(char * p, char * 
 	char *t;
 	int cnt;
 
+	bb_error_msg("HERE 300: p=0x%08x, q=0x%08x, dest=%d", p, q, dest);
 	if (q < p) {		// they are backwards- reverse them
 		t = q;
 		q = p;
 		p = t;
 	}
 	cnt = q - p + 1;
+	bb_error_msg("HERE 301: p=0x%08x, q=0x%08x, cnt=%d", p, q, cnt);
 	t = reg[dest];
+	bb_error_msg("HERE 302: dest=%d, t=0x%08x", dest, t);
 	free(t);		//  if already a yank register, free it
+	bb_error_msg("HERE 303: t=0x%08x", t);
 	t = xmalloc(cnt + 1);	// get a new register
+	bb_error_msg("HERE 304: t=0x%08x", t);
 	memset(t, '\0', cnt + 1);	// clear new text[]
+	//bb_error_msg("HERE 305");
+	bb_error_msg("HERE 305: t=0x%08x, cnt=%d", t, cnt);
+	//bb_error_msg("HERE 305: t=0x%08x, p=0x%08x, cnt=%d", t, p, cnt);
 	strncpy(t, p, cnt);	// copy text[] into bufer
+	bb_error_msg("HERE 306");
 	reg[dest] = t;
+	bb_error_msg("HERE 307");
 	return p;
 }
 
@@ -2268,16 +2284,21 @@ static char get_one_char(void)
 	// ! adding2q  && ioq == 0  read()
 	// ! adding2q  && ioq != 0  *ioq
 	// adding2q         *last_modifying_cmd= read()
+	bb_error_msg("HERE 200:");
 	if (!adding2q) {
+		bb_error_msg("HERE 201:");
 		// we are not adding to the q.
 		// but, we may be reading from a q
 		if (ioq == 0) {
+			bb_error_msg("HERE 202:");
 			// there is no current q, read from STDIN
 			c = readit();	// get the users input
 		} else {
+			bb_error_msg("HERE 202:");
 			// there is a queue to get chars from first
 			c = *ioq++;
 			if (c == '\0') {
+				bb_error_msg("HERE 203:");
 				// the end of the q, read from STDIN
 				free(ioq_start);
 				ioq_start = ioq = 0;
@@ -2285,21 +2306,27 @@ static char get_one_char(void)
 			}
 		}
 	} else {
+		bb_error_msg("HERE 205:");
 		// adding STDIN chars to q
 		c = readit();	// get the users input
 		if (last_modifying_cmd != 0) {
 			int len = strlen(last_modifying_cmd);
+			bb_error_msg("HERE 206:");
 			if (len >= MAX_LINELEN - 1) {
+				bb_error_msg("HERE 207:");
 				psbs("last_modifying_cmd overrun");
 			} else {
+				bb_error_msg("HERE 208:");
 				// add new char to q
 				last_modifying_cmd[len] = c;
 			}
 		}
 	}
 #else
+	bb_error_msg("HERE 210:");
 	c = readit();		// get the users input
 #endif /* FEATURE_VI_DOT_CMD */
+	bb_error_msg("HERE 211:");
 	return c;			// return the char, where ever it came from
 }
 


More information about the busybox mailing list