[net.bugs.4bsd] Savecore

larry@utecfa.UUCP (Larry Philps) (06/10/85)

Subject: savecore doesn't work with third, ``system'', argument
Index:	/usr/src/etc/savecore.c 4.2BSD

Description:
	When given the third argument specifying an alternate system,
	``system'' to dump, savecore does only one nlist, /vmunix,
	and assumes that the offsets it gets for all the kernel variables
	will be the same in ``system''.  Obviously, this is not always
	true.  Savecore must get the values of DUMPDEV, DUMPLO, and DUMPMAG
	from /vmunix (and /dev/kmem) since they are core variables and until
	you have them you cannot find the dump!  If one of these values is
	different in the two kernels then you are sunk.  However, once these
	are obtained, all the other kernel offsets, (TIME, DUMPSIZE, VERSION,
	DUMPMAG(again), and PANICSTR) should be obtained from ``system'' via
	another nlist call.  Now these variables can be used to properly
	address values down in the depths of the dump device.
Repeat-By:
	Add something big to your kernel (like a distributed file system) and
	make a mistake so that it crashes long before you could finish a
	savecore.  Boot a working kernel and try running

		savecore /usr/crash /vmunix.TEST

	Savecore will print nothing and no core dump will be performed.
Fix:
	The following is a context diff with -c3 that fixes the
	problem.  Two nlists are done the first getting DUMPDEV,
	DUMPLO, and DUMPMAG from /vmunix (/dev/kmem).  The second
	runs on ``system'' or /vmunix depending on whether or not
	the third argument is given.

*** /tmp/,RCSt1005058	Thu Jun  6 22:13:07 1985
--- savecore.c	Wed May 22 12:25:05 1985
***************
*** 1,4
  #ifndef lint
  static	char *sccsid = "@(#)savecore.c	4.13 (Berkeley) 83/07/02";
  #endif
  

--- 1,5 -----
  #ifndef lint
  static	char *sccsid = "@(#)savecore.c	4.13 (Berkeley) 83/07/02";
+ static char rcsid[] = "$Header: savecore.c,v 1.2 85/05/22 12:24:34 larry Exp $";
  #endif
  
***************
*** 26,31
  #define SHUTDOWNLOG "/usr/adm/shutdownlog"
  
! struct nlist nl[] = {
! #define X_DUMPDEV	0
  	{ "_dumpdev" },
  #define X_DUMPLO	1

--- 27,32 -----
  #define SHUTDOWNLOG "/usr/adm/shutdownlog"
  
! struct nlist nlRunning[] = {
! #define R_DUMPDEV	0
  	{ "_dumpdev" },
  #define R_DUMPLO	1
***************
*** 29,33
  #define X_DUMPDEV	0
  	{ "_dumpdev" },
! #define X_DUMPLO	1
  	{ "_dumplo" },
  #define X_TIME		2

--- 30,34 -----
  #define R_DUMPDEV	0
  	{ "_dumpdev" },
! #define R_DUMPLO	1
  	{ "_dumplo" },
  #define	R_DUMPMAG	2
***************
*** 31,35
  #define X_DUMPLO	1
  	{ "_dumplo" },
! #define X_TIME		2
  	{ "_time" },
  #define	X_DUMPSIZE	3

--- 32,42 -----
  #define R_DUMPLO	1
  	{ "_dumplo" },
! #define	R_DUMPMAG	2
! 	{ "_dumpmag" },
! 	{ "" },
! };
! 
! struct nlist nl[] = {
! #define X_TIME		0
  	{ "_time" },
  #define	X_DUMPSIZE	1
***************
*** 33,37
  #define X_TIME		2
  	{ "_time" },
! #define	X_DUMPSIZE	3
  	{ "_dumpsize" },
  #define X_VERSION	4

--- 40,44 -----
  #define X_TIME		0
  	{ "_time" },
! #define	X_DUMPSIZE	1
  	{ "_dumpsize" },
  #define X_VERSION	2
***************
*** 35,39
  #define	X_DUMPSIZE	3
  	{ "_dumpsize" },
! #define X_VERSION	4
  	{ "_version" },
  #define X_PANICSTR	5

--- 42,46 -----
  #define	X_DUMPSIZE	1
  	{ "_dumpsize" },
! #define X_VERSION	2
  	{ "_version" },
  #define X_PANICSTR	3
***************
*** 37,41
  #define X_VERSION	4
  	{ "_version" },
! #define X_PANICSTR	5
  	{ "_panicstr" },
  #define	X_DUMPMAG	6

--- 44,48 -----
  #define X_VERSION	2
  	{ "_version" },
! #define X_PANICSTR	3
  	{ "_panicstr" },
  #define	X_DUMPMAG	4
***************
*** 39,43
  #define X_PANICSTR	5
  	{ "_panicstr" },
! #define	X_DUMPMAG	6
  	{ "_dumpmag" },
  	{ "" },

--- 46,50 -----
  #define X_PANICSTR	3
  	{ "_panicstr" },
! #define	X_DUMPMAG	4
  	{ "_dumpmag" },
  	{ "" },
***************
*** 158,163
  	register char *cp;
  
! 	nlist("/vmunix", nl);
! 	if (nl[X_DUMPDEV].n_value == 0) {
  		fprintf(stderr, "savecore: /vmunix: dumpdev not in namelist\n");
  		exit(1);

--- 165,170 -----
  	register char *cp;
  
! 	nlist("/vmunix", nlRunning);
! 	if (nlRunning[R_DUMPDEV].n_value == 0) {
  		fprintf(stderr, "savecore: /vmunix: dumpdev not in namelist\n");
  		exit(1);
***************
*** 163,167
  		exit(1);
  	}
! 	if (nl[X_DUMPLO].n_value == 0) {
  		fprintf(stderr, "savecore: /vmunix: dumplo not in namelist\n");
  		exit(1);

--- 170,174 -----
  		exit(1);
  	}
! 	if (nlRunning[R_DUMPLO].n_value == 0) {
  		fprintf(stderr, "savecore: /vmunix: dumplo not in namelist\n");
  		exit(1);
***************
*** 167,170
  		exit(1);
  	}
  	if (nl[X_TIME].n_value == 0) {
  		fprintf(stderr, "savecore: /vmunix: time not in namelist\n");

--- 174,191 -----
  		exit(1);
  	}
+ 	if (nlRunning[R_DUMPMAG].n_value == 0) {
+ 		fprintf(stderr, "savecore: /vmunix: dumpmag not in namelist\n");
+ 		exit(1);
+ 	}
+ 	kmem = Open("/dev/kmem", 0);
+ 	Lseek(kmem, (long)nlRunning[R_DUMPDEV].n_value, 0);
+ 	Read(kmem, (char *)&dumpdev, sizeof (dumpdev));
+ 	Lseek(kmem, (long)nlRunning[R_DUMPLO].n_value, 0);
+ 	Read(kmem, (char *)&dumplo, sizeof (dumplo));
+ 	Lseek(kmem, (long)nlRunning[R_DUMPMAG].n_value, 0);
+ 	Read(kmem, (char *)&dumpmag, sizeof (dumpmag));
+ 	dumplo *= 512L;
+ 
+ 	nlist(system?system:"/vmunix", nl);
  	if (nl[X_TIME].n_value == 0) {
  		fprintf(stderr, "savecore: %s: time not in namelist\n",
***************
*** 168,172
  	}
  	if (nl[X_TIME].n_value == 0) {
! 		fprintf(stderr, "savecore: /vmunix: time not in namelist\n");
  		exit(1);
  	}

--- 189,194 -----
  	nlist(system?system:"/vmunix", nl);
  	if (nl[X_TIME].n_value == 0) {
! 		fprintf(stderr, "savecore: %s: time not in namelist\n",
! 			system?system:"/vmunix");
  		exit(1);
  	}
***************
*** 172,176
  	}
  	if (nl[X_DUMPSIZE].n_value == 0) {
! 		fprintf(stderr, "savecore: /vmunix: dumpsize not in namelist\n");
  		exit(1);
  	}

--- 194,199 -----
  	}
  	if (nl[X_DUMPSIZE].n_value == 0) {
! 		fprintf(stderr, "savecore: %s: dumpsize not in namelist\n",
! 			system?system:"/vmunix");
  		exit(1);
  	}
***************
*** 176,180
  	}
  	if (nl[X_VERSION].n_value == 0) {
! 		fprintf(stderr, "savecore: /vmunix: version not in namelist\n");
  		exit(1);
  	}

--- 199,204 -----
  	}
  	if (nl[X_VERSION].n_value == 0) {
! 		fprintf(stderr, "savecore: %s: version not in namelist\n",
! 			system?system:"/vmunix");
  		exit(1);
  	}
***************
*** 180,184
  	}
  	if (nl[X_PANICSTR].n_value == 0) {
! 		fprintf(stderr, "savecore: /vmunix: panicstr not in namelist\n");
  		exit(1);
  	}

--- 204,209 -----
  	}
  	if (nl[X_PANICSTR].n_value == 0) {
! 		fprintf(stderr, "savecore: %s: panicstr not in namelist\n",
! 			system?system:"/vmunix");
  		exit(1);
  	}
***************
*** 184,188
  	}
  	if (nl[X_DUMPMAG].n_value == 0) {
! 		fprintf(stderr, "savecore: /vmunix: dumpmag not in namelist\n");
  		exit(1);
  	}

--- 209,214 -----
  	}
  	if (nl[X_DUMPMAG].n_value == 0) {
! 		fprintf(stderr, "savecore: %s: dumpmag not in namelist\n",
! 			system?system:"/vmunix");
  		exit(1);
  	}
***************
*** 187,198
  		exit(1);
  	}
- 	kmem = Open("/dev/kmem", 0);
- 	Lseek(kmem, (long)nl[X_DUMPDEV].n_value, 0);
- 	Read(kmem, (char *)&dumpdev, sizeof (dumpdev));
- 	Lseek(kmem, (long)nl[X_DUMPLO].n_value, 0);
- 	Read(kmem, (char *)&dumplo, sizeof (dumplo));
- 	Lseek(kmem, (long)nl[X_DUMPMAG].n_value, 0);
- 	Read(kmem, (char *)&dumpmag, sizeof (dumpmag));
- 	dumplo *= 512L;
  	ddname = find_dev(dumpdev, S_IFBLK);
  	if ((fp = fdopen(kmem, "r")) == NULL) {

--- 213,216 -----
  		exit(1);
  	}
  	ddname = find_dev(dumpdev, S_IFBLK);
  	if (system)
***************
*** 196,199
  	dumplo *= 512L;
  	ddname = find_dev(dumpdev, S_IFBLK);
  	if ((fp = fdopen(kmem, "r")) == NULL) {
  		fprintf(stderr, "savecore: Couldn't fdopen kmem\n");

--- 214,219 -----
  	}
  	ddname = find_dev(dumpdev, S_IFBLK);
+ 	if (system)
+ 		return;
  	if ((fp = fdopen(kmem, "r")) == NULL) {
  		fprintf(stderr, "savecore: Couldn't fdopen kmem\n");
***************
*** 200,205
  		exit(1);
  	}
- 	if (system)
- 		return;
  	fseek(fp, (long)nl[X_VERSION].n_value, 0);
  	fgets(vers, sizeof vers, fp);

--- 220,223 -----
  		exit(1);
  	}
  	fseek(fp, (long)nl[X_VERSION].n_value, 0);
  	fgets(vers, sizeof vers, fp);
***************
*** 216,227
  		exit(1);
  	}
! 	fseek(fp, (off_t)(dumplo+ok(nl[X_VERSION].n_value)), 0);
! 	fgets(core_vers, sizeof core_vers, fp);
! 	fclose(fp);
! 	if (!eq(vers, core_vers))
! 		fprintf(stderr,
! 		   "savecore: Warning: vmunix version mismatch:\n\t%sand\n\t%s",
! 		   vers, core_vers);
! 	fp = fopen(ddname, "r");
  	fseek(fp, (off_t)(dumplo + ok(nl[X_PANICSTR].n_value)), 0);
  	fread((char *)&panicstr, sizeof panicstr, 1, fp);

--- 234,247 -----
  		exit(1);
  	}
! 	if (!system) {
! 		fseek(fp, (off_t)(dumplo+ok(nl[X_VERSION].n_value)), 0);
! 		fgets(core_vers, sizeof core_vers, fp);
! 		fclose(fp);
! 		if (!eq(vers, core_vers))
! 			fprintf(stderr,
! 			   "savecore: Warning: vmunix version mismatch:\n\t%sand\n\t%s",
! 			   vers, core_vers);
! 		fp = fopen(ddname, "r");
! 	}
  	fseek(fp, (off_t)(dumplo + ok(nl[X_PANICSTR].n_value)), 0);
  	fread((char *)&panicstr, sizeof panicstr, 1, fp);
***************
*** 241,246
  	time_t clobber = (time_t)0;
  
- 	if (system)
- 		return (1);
  	dumpfd = Open(ddname, 0);
  	Lseek(dumpfd, (off_t)(dumplo + ok(nl[X_TIME].n_value)), 0);

--- 261,264 -----
  	time_t clobber = (time_t)0;
  
  	dumpfd = Open(ddname, 0);
  	Lseek(dumpfd, (off_t)(dumplo + ok(nl[X_TIME].n_value)), 0);

--------------------- End of Diff -------------------------------------
-- 
						Larry Philps
						Engineering Computing Facility
						University of Toronto
		{linus,ihnp4,uw-beaver,floyd,decvax,utzoo}!utcsri!utecfa!larry