Add NS_TraceMallocStartupArgs() so it's easier to factor between apprunner and other apps. Like viewer. r=brendan

This commit is contained in:
waterson%netscape.com 2000-06-01 02:09:25 +00:00
Родитель f9c64cb8d2
Коммит 5c0a94e714
4 изменённых файлов: 202 добавлений и 0 удалений

Просмотреть файл

@ -40,6 +40,8 @@
* - unify calltree with gc/boehm somehow (common utility libs)
* - provide NS_TraceMallocTimestamp() or do it internally
*/
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
@ -986,6 +988,100 @@ PR_IMPLEMENT(void) NS_TraceMallocStartup(int logfd)
tmmon = PR_NewMonitor();
}
PR_IMPLEMENT(int) NS_TraceMallocStartupArgs(int argc, char* argv[])
{
int i, logfd = -1;
/*
* Look for the --trace-malloc <logfile> option early, to avoid missing
* early mallocs (we miss static constructors whose output overflows the
* log file's static 16K output buffer; see xpcom/base/nsTraceMalloc.c).
*/
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "--trace-malloc") == 0 && i < argc-1) {
char *logfilename;
int pipefds[2];
logfilename = argv[i+1];
switch (*logfilename) {
case '|':
if (pipe(pipefds) == 0) {
pid_t pid = fork();
if (pid == 0) {
/* In child: set up stdin, parse args from logfilename, and exec. */
int maxargc, nargc;
char **nargv, *token;
if (pipefds[0] != 0) {
dup2(pipefds[0], 0);
close(pipefds[0]);
}
close(pipefds[1]);
logfilename = strtok(logfilename + 1, " \t");
maxargc = 3;
nargv = (char **) malloc((maxargc + 1) * sizeof(char *));
if (!nargv) exit(1);
nargc = 0;
nargv[nargc++] = logfilename;
while ((token = strtok(NULL, " \t")) != NULL) {
if (nargc == maxargc) {
maxargc *= 2;
nargv = (char**) realloc(nargv, (maxargc+1) * sizeof(char*));
if (!nargv) exit(1);
}
nargv[nargc++] = token;
}
nargv[nargc] = NULL;
(void) setsid();
execvp(logfilename, nargv);
exit(127);
}
if (pid > 0) {
/* In parent: set logfd to the write side of the pipe. */
close(pipefds[0]);
logfd = pipefds[1];
}
}
if (logfd < 0) {
fprintf(stderr,
"%s: can't pipe to trace-malloc child process %s: %s\n",
argv[0], logfilename, strerror(errno));
exit(1);
}
break;
case '-':
/* Don't log from startup, but do prepare to log later. */
if (logfilename[1] == '\0')
break;
/* FALL THROUGH */
default:
logfd = open(logfilename, O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (logfd < 0) {
fprintf(stderr,
"%s: can't create trace-malloc logfilename %s: %s\n",
argv[0], logfilename, strerror(errno));
exit(1);
}
break;
}
/* Now remove --trace-malloc and its argument from argv. */
for (argc -= 2; i < argc; i++)
argv[i] = argv[i+2];
argv[argc] = NULL;
break;
}
}
NS_TraceMallocStartup(logfd);
return argc;
}
PR_IMPLEMENT(void) NS_TraceMallocShutdown()
{
logfile *fp, *next;

Просмотреть файл

@ -105,6 +105,11 @@ typedef struct nsTMStats {
*/
PR_EXTERN(void) NS_TraceMallocStartup(int logfd);
/**
* Initialize malloc tracing, using the ``standard'' startup arguments.
*/
PR_EXTERN(int) NS_TraceMallocStartupArgs(int argc, char* argv[]);
/**
* Stop all malloc tracing, flushing any buffered events to the logfile.
*/

Просмотреть файл

@ -40,6 +40,8 @@
* - unify calltree with gc/boehm somehow (common utility libs)
* - provide NS_TraceMallocTimestamp() or do it internally
*/
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
@ -986,6 +988,100 @@ PR_IMPLEMENT(void) NS_TraceMallocStartup(int logfd)
tmmon = PR_NewMonitor();
}
PR_IMPLEMENT(int) NS_TraceMallocStartupArgs(int argc, char* argv[])
{
int i, logfd = -1;
/*
* Look for the --trace-malloc <logfile> option early, to avoid missing
* early mallocs (we miss static constructors whose output overflows the
* log file's static 16K output buffer; see xpcom/base/nsTraceMalloc.c).
*/
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "--trace-malloc") == 0 && i < argc-1) {
char *logfilename;
int pipefds[2];
logfilename = argv[i+1];
switch (*logfilename) {
case '|':
if (pipe(pipefds) == 0) {
pid_t pid = fork();
if (pid == 0) {
/* In child: set up stdin, parse args from logfilename, and exec. */
int maxargc, nargc;
char **nargv, *token;
if (pipefds[0] != 0) {
dup2(pipefds[0], 0);
close(pipefds[0]);
}
close(pipefds[1]);
logfilename = strtok(logfilename + 1, " \t");
maxargc = 3;
nargv = (char **) malloc((maxargc + 1) * sizeof(char *));
if (!nargv) exit(1);
nargc = 0;
nargv[nargc++] = logfilename;
while ((token = strtok(NULL, " \t")) != NULL) {
if (nargc == maxargc) {
maxargc *= 2;
nargv = (char**) realloc(nargv, (maxargc+1) * sizeof(char*));
if (!nargv) exit(1);
}
nargv[nargc++] = token;
}
nargv[nargc] = NULL;
(void) setsid();
execvp(logfilename, nargv);
exit(127);
}
if (pid > 0) {
/* In parent: set logfd to the write side of the pipe. */
close(pipefds[0]);
logfd = pipefds[1];
}
}
if (logfd < 0) {
fprintf(stderr,
"%s: can't pipe to trace-malloc child process %s: %s\n",
argv[0], logfilename, strerror(errno));
exit(1);
}
break;
case '-':
/* Don't log from startup, but do prepare to log later. */
if (logfilename[1] == '\0')
break;
/* FALL THROUGH */
default:
logfd = open(logfilename, O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (logfd < 0) {
fprintf(stderr,
"%s: can't create trace-malloc logfilename %s: %s\n",
argv[0], logfilename, strerror(errno));
exit(1);
}
break;
}
/* Now remove --trace-malloc and its argument from argv. */
for (argc -= 2; i < argc; i++)
argv[i] = argv[i+2];
argv[argc] = NULL;
break;
}
}
NS_TraceMallocStartup(logfd);
return argc;
}
PR_IMPLEMENT(void) NS_TraceMallocShutdown()
{
logfile *fp, *next;

Просмотреть файл

@ -105,6 +105,11 @@ typedef struct nsTMStats {
*/
PR_EXTERN(void) NS_TraceMallocStartup(int logfd);
/**
* Initialize malloc tracing, using the ``standard'' startup arguments.
*/
PR_EXTERN(int) NS_TraceMallocStartupArgs(int argc, char* argv[]);
/**
* Stop all malloc tracing, flushing any buffered events to the logfile.
*/