⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nptl_trace.c

📁 linux下的多线程调试工具
💻 C
字号:
/* Copyright (C) 2004,2005,2006  Bull S.A. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#if HAVE_CONFIG_H#include <config.h>#endif#define _XOPEN_SOURCE 500#include <string.h>#include <stdio.h>#include <fcntl.h>#include <stdlib.h>#include <unistd.h>#include <endian.h>#include <signal.h>#include <sys/mman.h>#include "types.h"#include "level.h"#include "timestamp.h"#include "daemon.h"#include "debug.h"#include "version.h"#define PTT_FILE_LEN 255#define PTT_BIN_FILE_LEN 255#define PTT_BUF_SIZE_DEFAULT (1<<21)#define PTT_MAX_BUF_SIZE ((1<<30)-1)#define PTT_SZ_WORD (sizeof(PTT_WORD))#define PTT_ARCH_LEN 30struct ptt_buffer * ptt_buf;extern unsigned int max_file, max_size;static void usage(void) {    printf ("ptt_trace [options] cmd [cmd_arg ...]\n"           "Help :\n"           "\t-s size:\tchange the buffer size\n"           "\t-l level:\tchange the trace level\n"           "\t-m max:\t\tmax file size in Mb\n"           "\t-f max:\t\tmax number of file\n"           "\t-n name:\tname of the trace file\n"           "\t-h:\t\tthis help\n"           "\t--:\t\tforce an end of option-scanning\n");    exit (1);}static pid_t cmd; /* pid of the process which inits the trace mechanism */char region [PTT_FILE_LEN]; /* shared memory name */static void sighandler (int signum) {    printf ("Killed by signal %d\n", signum);    kill (cmd, signum);}static void aborthandler (int signum) {    printf ("Killed by signal %d\n", signum);    if (shm_unlink (region) == -1) perror("shm_unlink failed");    kill (cmd, SIGKILL);}int main (int argc, char**argv) {    pid_t pgid;    /* name of the binary file created by the trace mechanism */    static char binary [PTT_BIN_FILE_LEN];    int fd;    long long size_buff;    int size_log2 = 0;    int trace_level = PTT_LEVEL_ALL;    signed char c;    int status;    ptt_header_t header = {        .byte_order = __BYTE_ORDER,        .version = { .major = PTT_VERS_MAJOR, .minor = PTT_VERS_MINOR },        .freq_khz = get_clockfreq_khz (),        .timestamp = get_timestamp (),        .start_time = time (NULL),    };    const char * optstring = "+s:hl:m:f:n:";    /* don't use _SC_AVPHYS_PAGES since memory could be cached and still      * usable */    size_buff = (long long) sysconf (_SC_PHYS_PAGES) / (1<<7)                 * sysconf (_SC_PAGESIZE) * sysconf (_SC_NPROCESSORS_ONLN);    if (size_buff <= 0) size_buff = PTT_BUF_SIZE_DEFAULT;    /* default file name */    snprintf (binary, sizeof (binary), "trace_%d_%d", (int) time (NULL),              getpid());    while ((c = getopt (argc-1, argv+1, optstring)) != EOF) {        switch (c) {            case 'h': usage(); break;            case 's': size_buff = strtol (optarg, NULL, 10); break;	    case 'l': trace_level = PTT_LEVEL_NONE;                      while (optarg) {                          char *level = optarg;                          strsep (&optarg, ",");                          trace_level |= levelstr2int (level);                      }                      break;            case 'm': max_size = strtol (optarg, NULL, 10) * (1<<20);                      break;            case 'f': max_file = strtol (optarg, NULL, 10); break;            case 'n': strncpy (binary, optarg, sizeof (binary));                      binary [sizeof (binary)] = 0;                      break;            case '?': printf ("error : %c\n", optopt); usage();	}    }    if ((argc - 1 - optind) < 1) {        printf("missing program to excecute\n"); usage();        exit (1);    }	    if (size_buff > (PTT_MAX_BUF_SIZE)) size_buff =                    (long long) (PTT_MAX_BUF_SIZE);    if (size_buff < 4) size_buff = 4;    while (size_buff != 0) { ++size_log2; size_buff>>=1; }    size_buff = (long long) (1<<size_log2);    pgid = getpid ();    if (pgid != getpgid (0))        if (setpgid (pgid, pgid)) { perror("setpgid failed"); abort(); }    snprintf (region, sizeof (region), "/ptt_%d", pgid);	    printf("*** Currently using the NPTL Trace Tool.\n");    if (max_size) printf("*** Output file is %s-[0-9]*.bin\n", binary);    else printf("*** Output file is %s.bin\n", binary);    printf("*** pgid=%d\n", pgid);    /* Create and open a new POSIX shared memory object*/    if ((fd = shm_open(region, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR))        == -1) {        perror("shm_open failed"); abort();    }    /* we should clean our file if we are aborted */    signal (SIGABRT, aborthandler);	    /* set the size of the shared memory object to size of buffer */    if (lseek (fd, sizeof (struct ptt_buffer) + size_buff, SEEK_SET) == -1) {        perror("lseek failed"); abort();    }    if (write (fd, &fd, 1) != 1) { perror("write for extended"); abort(); }		    /* map the shared memory */    ptt_buf = mmap (0, sizeof (struct ptt_buffer) + size_buff,                PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);    if (ptt_buf == MAP_FAILED) { perror("mmap failed"); abort(); }	    /* initialize fields of the buffer */    ptt_buf->reserved = 0;    ptt_buf->written = 0;    ptt_buf->beg_read = 0;    ptt_buf->PAUSE = 0;    ptt_buf->size_buff = size_buff / PTT_SZ_WORD;    ptt_buf->current_level = trace_level;#ifdef PTT_TRACE_INFO    ptt_buf->stat_enable = 1;#else    ptt_buf->stat_enable = 0;#endif    /* initialize the fields of the header */    strncpy (header.architecture, PTT_ARCH, PTT_ARCH_LEN);    /* create the second process */    if ((cmd = fork()) == -1) { perror("fork failed"); abort(); }    if (cmd == 0) {        /* add argv[optind] to LD_PRELOAD in process environnement */        char *old_preld = getenv ("LD_PRELOAD");        if (old_preld == NULL) setenv ("LD_PRELOAD", argv[1], 1);        else {            char *new_preld = (char *) malloc (sizeof (char) *                              (strlen (old_preld) + 2 + strlen (argv[1])));            strncpy (new_preld, argv[optind], strlen(argv[1]));            strncat (new_preld, ":", 1);            strncat (new_preld, old_preld, strlen(old_preld));            setenv ("LD_PRELOAD", new_preld, 1);        }        execvp (argv[optind+1], argv+optind+1);        perror("execve failed"); abort();    }    /* term signal */    signal (SIGHUP,    sighandler);    signal (SIGINT,    sighandler);    signal (SIGQUIT,   sighandler);    signal (SIGKILL,   sighandler);    signal (SIGPIPE,   sighandler);    signal (SIGALRM,   sighandler);    signal (SIGTERM,   sighandler);    signal (SIGPROF,   sighandler);    signal (SIGVTALRM, sighandler);    /* user signal */    signal(SIGUSR1,    sighandler);    signal(SIGUSR2,    sighandler);    /* stop signal */    signal(SIGSTOP,    sighandler);    signal(SIGTSTP,    sighandler);    signal(SIGTTIN,    sighandler);    signal(SIGTTOU,    sighandler);    signal(SIGCONT,    sighandler);    status = daemon (&header, binary);    /* reader process has finished */    if (shm_unlink (region) == -1) perror("shm_unlink failed");    PTT_TRACE_INTERNALS (PTT_DBG_MAIN,                         "At the end of this program, written=%u\n",                         ptt_buf->written);    printf("*** The NPTL Trace Tool's work is finished.\n");    if (WIFSIGNALED (status)) {        printf("*** %s was killed by a signal(%d)\n", argv[optind+1],               WTERMSIG (status));        kill (getpid(), WTERMSIG (status));    }    if (WIFEXITED (status)) {        printf("*** %s terminated normally(%d)\n", argv[optind+1],               WEXITSTATUS (status));        exit (WEXITSTATUS (status));    }    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -