mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-18 03:40:47 -08:00
Add __attribute__((__format__(printf))) to functions that take a printf-compatible format string (when building using GCC or Clang), so that format string mistakes can be detected statically. Copied from Perforce Change: 185021 ServerID: perforce.ravenbrook.com
226 lines
5.6 KiB
C
226 lines
5.6 KiB
C
/* replay.c: Allocation replayer
|
|
* Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
|
|
*
|
|
* $Id$
|
|
*/
|
|
|
|
#include "config.h"
|
|
/* override variety setting for EVENT */
|
|
#define EVENT
|
|
|
|
#include "eventcom.h"
|
|
#include "eventpro.h"
|
|
#include "eventrep.h"
|
|
#include "mpmtypes.h"
|
|
|
|
#include <stddef.h> /* for size_t */
|
|
#include <stdio.h> /* for printf */
|
|
#include <stdarg.h> /* for va_list */
|
|
#include <stdlib.h> /* for EXIT_FAILURE */
|
|
#include <string.h> /* for strcmp */
|
|
#include "mpstd.h"
|
|
|
|
|
|
#if defined(MPS_OS_W3) && defined(MPS_ARCH_I6)
|
|
#define PRIuLONGEST "llu"
|
|
#define PRIXPTR "016llX"
|
|
typedef unsigned long long ulongest_t;
|
|
#else
|
|
#define PRIuLONGEST "lu"
|
|
#define PRIXPTR "08lX"
|
|
typedef unsigned long ulongest_t;
|
|
#endif
|
|
|
|
|
|
typedef unsigned long ulong;
|
|
|
|
|
|
/* command-line arguments */
|
|
|
|
static char *prog; /* program name */
|
|
|
|
|
|
/* Globals */
|
|
|
|
static Word eventTime = 0; /* current event time */
|
|
|
|
|
|
/* error -- error signalling */
|
|
|
|
ATTRIBUTE_FORMAT((printf, 1, 2))
|
|
static void error(const char *format, ...)
|
|
{
|
|
va_list args;
|
|
|
|
fflush(stdout); /* sync */
|
|
fprintf(stderr, "%s: @%"PRIuLONGEST" ", prog, (ulongest_t)eventTime);
|
|
va_start(args, format);
|
|
vfprintf(stderr, format, args);
|
|
fprintf(stderr, "\n");
|
|
va_end(args);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
|
|
/* usage -- usage message */
|
|
|
|
static void usage(void)
|
|
{
|
|
fprintf(stderr,
|
|
"Usage: %s [-f logfile] [-p] [-?]\n"
|
|
"See guide.mps.telemetry for instructions.\n",
|
|
prog);
|
|
}
|
|
|
|
|
|
/* usageError -- explain usage and error */
|
|
|
|
static void usageError(void)
|
|
{
|
|
usage();
|
|
error("Bad usage");
|
|
}
|
|
|
|
|
|
/* parseArgs -- parse command line arguments, return log file name */
|
|
|
|
static char *parseArgs(int argc, char *argv[])
|
|
{
|
|
char *name = "mpsio.log";
|
|
int i = 1;
|
|
|
|
if (argc >= 1)
|
|
prog = argv[0];
|
|
else
|
|
prog = "unknown";
|
|
|
|
while (i < argc) { /* consider argument i */
|
|
if (argv[i][0] == '-') { /* it's an option argument */
|
|
switch (argv[i][1]) {
|
|
case 'f': /* file name */
|
|
++ i;
|
|
if (i == argc)
|
|
usageError();
|
|
else
|
|
name = argv[i];
|
|
break;
|
|
case '?': case 'h': /* help */
|
|
usage();
|
|
break;
|
|
default:
|
|
usageError();
|
|
}
|
|
} /* if option */
|
|
++ i;
|
|
}
|
|
return name;
|
|
}
|
|
|
|
|
|
/* readLog -- read and parse log */
|
|
|
|
|
|
static void readLog(EventProc proc)
|
|
{
|
|
while (TRUE) {
|
|
Event event;
|
|
Res res;
|
|
|
|
res = EventRead(&event, proc);
|
|
if (res == ResFAIL) break; /* eof */
|
|
if (res != ResOK) error("Truncated log");
|
|
eventTime = event->any.clock;
|
|
EventRecord(proc, event, eventTime);
|
|
EventReplay(event, eventTime);
|
|
EventDestroy(proc, event);
|
|
}
|
|
}
|
|
|
|
|
|
/* logReader -- reader function for a file log */
|
|
|
|
static FILE *input;
|
|
|
|
static Res logReader(void *file, void *p, size_t len)
|
|
{
|
|
size_t n;
|
|
|
|
n = fread(p, 1, len, (FILE *)file);
|
|
return (n < len) ? (feof((FILE *)file) ? ResFAIL : ResIO) : ResOK;
|
|
}
|
|
|
|
|
|
/* main */
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
char *filename;
|
|
EventProc proc;
|
|
Res res;
|
|
|
|
filename = parseArgs(argc,argv);
|
|
|
|
if (strcmp(filename, "-") == 0)
|
|
input = stdin;
|
|
else {
|
|
input = fopen(filename, "rb");
|
|
if (input == NULL)
|
|
error("unable to open \"%s\"\n", filename);
|
|
}
|
|
|
|
res = EventProcCreate(&proc, logReader, (void *)input);
|
|
if (res != ResOK)
|
|
error("Can't init EventProc module: error %d.", res);
|
|
|
|
res = EventRepInit();
|
|
if (res != ResOK)
|
|
error("Can't init EventRep module: error %d.", res);
|
|
|
|
readLog(proc);
|
|
|
|
EventRepFinish();
|
|
EventProcDestroy(proc);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
|
|
/* C. COPYRIGHT AND LICENSE
|
|
*
|
|
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
|
|
* All rights reserved. This is an open source license. Contact
|
|
* Ravenbrook for commercial licensing options.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* 3. Redistributions in any form must be accompanied by information on how
|
|
* to obtain complete source code for this software and any accompanying
|
|
* software that uses this software. The source code must either be
|
|
* included in the distribution or be available for no more than the cost
|
|
* of distribution plus a nominal fee, and must be freely redistributable
|
|
* under reasonable conditions. For an executable file, complete source
|
|
* code means the source code for all modules it contains. It does not
|
|
* include source code for modules or files that typically accompany the
|
|
* major components of the operating system on which the executable file
|
|
* runs.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
|
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
|
* PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
* COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|