Fix the way the segments are included in the gcore outputs (with the

default invokation):
- Right now if segments are not writable are not included. Remove this.
- Right now if a segment is mapped with NOCORE the check is not honoured.
  Change this by checking the newly added flag, from libutil,
  KVME_FLAG_NOCOREDUMP.

Besides that, add a new flag (-f) that forces a 'full' dump of all the
segments excluding just the malformed ones. This might be used very
carefully as, among the reported segments, there could be memory
mapped areas that could be vital to program execution.

Sponsored by:	Sandvine Incorporated
Discussed with:	kib
Reviewed by:	emaste
Tested by:	Sandvine Incorporated
MFC after:	2 weeks
This commit is contained in:
Attilio Rao 2010-07-14 17:16:25 +00:00
parent 629606202c
commit 1d73ef9790
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=210063
4 changed files with 30 additions and 11 deletions

View File

@ -488,12 +488,17 @@ readmap(pid_t pid)
kve = &vmentl[i];
/*
* Ignore segments of the wrong kind and ones which are not
* readable and writable.
* Ignore 'malformed' segments or ones representing memory
* mapping with MAP_NOCORE on.
* If the 'full' support is disabled, just dump the most
* meaningful data segments.
*/
if ((kve->kve_protection & KVME_PROT_WRITE) == 0 ||
(kve->kve_protection & KVME_PROT_READ) == 0 ||
(kve->kve_type != KVME_TYPE_DEFAULT &&
if ((kve->kve_protection & KVME_PROT_READ) == 0 ||
(kve->kve_flags & KVME_FLAG_NOCOREDUMP) != 0 ||
kve->kve_type == KVME_TYPE_DEAD ||
kve->kve_type == KVME_TYPE_UNKNOWN ||
((pflags & PFLAGS_FULL) == 0 &&
kve->kve_type != KVME_TYPE_DEFAULT &&
kve->kve_type != KVME_TYPE_VNODE &&
kve->kve_type != KVME_TYPE_SWAP))
continue;

View File

@ -34,8 +34,11 @@
* $FreeBSD$
*/
#define PFLAGS_FULL 0x01
#define PFLAGS_RESUME 0x02
struct dumpers {
int (*ident)(int efd, pid_t pid, char *binfile);
void (*dump)(int efd, int fd, pid_t pid);
};
extern int sflag;
extern int pflags;

View File

@ -32,7 +32,7 @@
.\" @(#)gcore.1 8.2 (Berkeley) 4/18/94
.\" $FreeBSD$
.\"
.Dd November 18, 2009
.Dd July 14, 2010
.Dt GCORE 1
.Os
.Sh NAME
@ -40,6 +40,7 @@
.Nd get core images of running process
.Sh SYNOPSIS
.Nm
.Op Fl f
.Op Fl s
.Op Fl c Ar core
.Op Ar executable
@ -61,6 +62,13 @@ The following options are available:
.It Fl c
Write the core file to the specified file instead of
.Dq Pa core.<pid> .
.It Fl f
Dumps all the available segments, excluding only the malformed ones and
un-dumpable ones. Differently from the default invocation, it also dumps
device-mapped and sglist-mapped areas that may invalidate the state of
some transactions. This flag, then, may be used very carefully, when the
full behaviour of the application is full-understood and the fallouts can
be easilly controlled.
.It Fl s
Stop the process while gathering the core image, and resume it
when done.

View File

@ -71,7 +71,7 @@ __FBSDID("$FreeBSD$");
#include <unistd.h>
#include "extern.h"
int sflag;
int pflags;
static void killed(int);
static void usage(void) __dead2;
@ -89,15 +89,18 @@ main(int argc, char *argv[])
struct dumpers **d, *dumper;
size_t len;
sflag = 0;
pflags = 0;
corefile = NULL;
while ((ch = getopt(argc, argv, "c:s")) != -1) {
while ((ch = getopt(argc, argv, "c:fs")) != -1) {
switch (ch) {
case 'c':
corefile = optarg;
break;
case 'f':
pflags |= PFLAGS_FULL;
break;
case 's':
sflag = 1;
pflags |= PFLAGS_RESUME;
break;
default:
usage();