* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
static char sccsid
[] = "@(#)pmon.c 5.1 (Berkeley) 6/5/85";
* pxp - Pascal execution profiler
* Version 1.2 January 1979
* Profile counter processing cluster
* This file contains all routines which do the hard work in profiling.
* The first group of routines (getit, getpmon, getcore, and pmread)
* deal with extracting data from the pmon.out and (with more difficulty)
* The routines cnttab and prttab collect counters for
* and print the summary table respectively.
* The routines "*cnt*" deal with manipulation of counters,
* especially the "current" counter px.
* for procedure/function summary
STATIC
long *zbuf
; /* Count buffer */
STATIC
short zcnt
; /* Number of counts */
STATIC
short zpfcnt
; /* Number of proc/funcs's */
STATIC
short gcountr
; /* Unique name generator */
STATIC
short zfil
; /* I/o unit for count data reads */
STATIC
short lastpf
; /* Total # of procs and funcs for consistency chk */
* Setup monitor data buffer from pmon.out
* style file whose name is fp.
if (pmread() < 0 || read(zfil
, &garbage
, 1) == 1) {
Perror(fp
, "Bad format for pmon.out style file");
STATIC
char nospcm
[] = "Not enough memory for count buffers\n";
write(2, nospcm
, sizeof nospcm
);
* Structure of the first few
* items of a px core dump.
char *off
; /* Self-reference for pure text */
short type
; /* 0 = non-pure text, 1 = pure text */
char *bp
; /* Core address of pxps struct */
* First few words of the px
write(2, "-c: option not supported\n", sizeof("-c: option not supported\n"));
if (lseek(zfil, 02000, 0) < 0)
if (read(zfil, &inf, sizeof inf) < 0)
if (inf.type != 0 && inf.type != 1)
if (lseek(zfil, inf.bp + 02000, 0) < 0)
if (read(zfil, &pxp, sizeof pxp) != sizeof pxp)
Perror(fp, "No profile data in file");
if (lseek(zfil, pxp.buf + 02000, 0) < 0)
Perror(fp, "Not a Pascal system core file");
if (read(zfil
, &zmagic
, sizeof zmagic
) != sizeof zmagic
)
cp
= zbuf
= pcalloc(i
= (zcnt
+ 1) * sizeof *zbuf
, 1);
cp
= zpf
= pcalloc(zpfcnt
* sizeof *zpf
, 1);
if (read(zfil
, zbuf
+ (sizeof(zmagic
) / sizeof(*zbuf
)), i
) != i
)
register struct pftab
*pp
;
register struct pftab
*zpfp
;
if (profile
== 0 && table
== 0)
if (cnts
!= zcnt
|| lastpf
!= zpfcnt
)
printf("\n\tLine\t Count\n\n");
for (i
= 0; i
< zpfcnt
; i
++) {
printf("\t%4d\t%8ld\t", zpfp
->pfline
, zpfp
->pfcnt
);
for (j
= zpfp
->pflev
* unit
; j
> 1; j
--)
printf("%s\n", zpfp
->pfname
);
if (profile
== 0 && table
== 0)
if (profile
== 0 && table
== 0)
register struct pxcnt
*pxc
;
if (profile
== 0 && table
== 0)
pxc
->counter
= px
.counter
;
register struct pxcnt
*pxc
;
if (profile
== 0 && table
== 0)
px
.counter
= pxc
->counter
;
px
.printed
= pxc
->printed
;
return (gocnt
!= pxc
->gos
);
if (profile
== 0 && table
== 0)
* Control printing of '|'
* Do we want cnt and/or '|' on this line ?
STATIC
char mism
[] = "Program and counter data do not correspond\n";
printf("cnts %d zcnt %d, lastpf %d zpfcnt %d\n",
cnts
, zcnt
, lastpf
, zpfcnt
);
write(2, mism
, sizeof mism
);