Add NS_TraceMallocStartupArgs() so it's easier to factor between apprunner and other apps. Like viewer. r=brendan
This commit is contained in:
Родитель
f9c64cb8d2
Коммит
5c0a94e714
|
@ -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.
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче