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

📄 read.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#include <string.h>#include <stdio.h>#include <errno.h>#include <bits/wordsize.h>#include "types.h"#include "modules.h"#include "version.h"#define SZ_WORD sizeof(PTT_WORD)#define SZ_INT sizeof(int)#define SZ_PTR sizeof(void*)#define SZ_UINT sizeof(unsigned int)#define SZ_ULL sizeof(unsigned long long)#define SZ_TIME sizeof(ptt_timestamp_t)#define SZ_CHECK sizeof(ptt_checksum_t)extern ptt_event_data_t ptt_event_array[];extern ptt_point_data_t ptt_point_array[];extern ptt_point_compiled_data_t ptt_point_compiled_array[];extern struct get_obj_name get_obj_name;extern struct give_name give_name;extern struct interval interval;static FILE *stream;static int freq_khz;static ptt_timestamp_t start_time;static ptt_timestamp_t curr_time;/* buffer must be big enough */static PTT_WORD buf [(SZ_TIME + SZ_WORD + SZ_INT + SZ_PTR) / SZ_WORD                     + PTT_MAXARG * SZ_ULL / SZ_WORD];static int pos = 0;static ptt_point_data_t *v_trace;static int evt_ind = 0;static int waiting = 0;static char *file_prefix = NULL;static int file_number = 0;static ptt_timestamp_t timestamp2ms (ptt_timestamp_t *time_stamp) {    return (*time_stamp - start_time) / freq_khz;}static int nextfile (ptt_header_t *head) {    char arch_size;    if (file_prefix == NULL) return 0;    char filename [strlen (file_prefix) + sizeof ("-xxxx.bin")];    fclose (stream);    sprintf (filename, "%s-%04i.bin", file_prefix, ++file_number);    stream = fopen (filename, "r");    if (stream == NULL) return (errno == ENOENT) ? 0 : -errno;    if (fread (&arch_size, 1, 1, stream) != 1) return -errno;    if (arch_size != sizeof (void*)) {        fprintf (stderr, "the number of bit of the arch changed\n");        return -1;    }    if (fread (head ,sizeof (ptt_header_t), 1, stream) != 1) {        if (feof (stream)) {            fprintf (stderr, "the file is too short\n");            return -1;        }        perror ("read header failed");        return -errno;    }    if (head->byte_order != __BYTE_ORDER) {        fprintf (stderr, "endian is not the same\n");        return -1;    }    if (head->version.major != PTT_VERS_MAJOR) {        fprintf (stderr, "incorrect major version (%d != %d)\n",                 head->version.major, PTT_VERS_MAJOR);        return -1;    }    if (head->version.minor != PTT_VERS_MINOR)        fprintf (stderr, "warning : minor version is not the same "                 "(%d != %d)\n", head->version.minor, PTT_VERS_MINOR);    if (head->file_number != file_number) {        fprintf (stderr, "warning : wrong file number");        return -1;    }    waiting = 0;    return 1;}static int get_trace_point () {    ptt_point_t tr_point;    /* read a trace point */    if (fread (buf, SZ_WORD, 1, stream) != 1) {        if (feof (stream)) return 0;        perror ("can't read point trace name");        return -1;    }    tr_point = *buf;    if ((tr_point <= TR_NULL) || (tr_point >= TR_LAST)) {        fprintf (stderr, "wrong trace point %u\n", tr_point);        return -1;    }    else {        ptt_point_compiled_data_t *v_tracec = ptt_point_compiled_array                                              + tr_point;        int size = v_tracec->size - 1;        int i;        ptt_checksum_t check_sum = 0;        /* buf:         * 0 tr_point         * 1 timestamp         * 2 timestamp         * 3 pid         * 4 tid         * 5 args         * ...         * size check_sum */        if (fread (buf+1, SZ_WORD, size, stream) != size) {            if (feof (stream)) {                fprintf (stderr, "missing point trace data\n");                return -1;            }            perror ("can't read point trace data");            return -1;        }        /* check the check sum */        for (i = 0; i < size; i++) check_sum ^= buf[i];        if (buf[size] != check_sum) {            check_sum = 0;            for (i = 0; i < size; i++) {                check_sum ^= buf[i];                printf ("buf[%d] = %#lx, check_sum = %#lx\n", i, buf[i],                        check_sum);            }            fprintf (stderr, "wrong checksum %u != %u\n", buf[size],                     check_sum);            return -1;        }        /* check version number of START_USER */        if (buf[0] == TR_INIT) {#if (__WORDSIZE == 64)            int vers = buf[6];#else            int vers = buf[5];#endif            if (vers/10000 != PTT_VERS_MAJOR) {                fprintf (stderr, "incorrect major version (%d != %d)\n",                         vers/10000, PTT_VERS_MAJOR);                return -1;            }            if (vers%10000 != PTT_VERS_MINOR)            fprintf (stderr, "warning : minor version is not the same "                     "(%d != %d)\n", vers%10000, PTT_VERS_MAJOR);        }        /* convert the timestamp */        curr_time = buf[1] | ((long long)(buf[2]) << 32);        curr_time = timestamp2ms (&curr_time);		        v_trace = ptt_point_array + tr_point;        return v_trace->nevts;    }}static int get_trace_filtered () {    /* gcc 3.x seem buggy as they miss the first event if not volatile */    volatile int ret;    int waiting;    ptt_header_t head;        do {        waiting = get_trace_point ();        if ((waiting < 0) || ((waiting == 0) && (!file_number)))            return waiting;        if (waiting == 0) {            waiting = nextfile (&head);            if (waiting <= 0) return waiting;            continue;	}        /* check the interval */        ret = interval.accept (&curr_time, waiting);        if (ret < 0) return ret;        else if (ret == 2) return 0;    } while (ret == 0);    return waiting;}static inline ptt_event_t get_event (int evt_ind) {    ptt_event_t event = v_trace->event[evt_ind];    if ((event <= EVT_NULL) || (event >= EVT_LAST)) return EVT_NULL;    return event;}	static int _get_info (char **list_name, int *list_int,                      unsigned int *list_uint, long long *list_ll, int fast) {    ptt_event_t event = get_event (evt_ind);    /* get the the event info */    ptt_event_data_t *evt_data;    if (event == EVT_NULL) return -1;    evt_data = ptt_event_array + event;    void *list_ptr[PTT_MAXARG+1];    int nb_int = 0, nb_uint = 0, nb_ptr = 0, nb_ll = 0;    int arg_ind = 0;#if __WORDSIZE == 64    list_ptr[nb_ptr++] = (void *)(buf[(SZ_TIME + SZ_WORD + SZ_INT)/SZ_WORD] | 			 ((long long)(buf[(SZ_TIME + SZ_WORD + SZ_INT)/SZ_WORD                                          + 1]) << 32));#else    list_ptr[nb_ptr++] = (void *)buf[(SZ_TIME + SZ_WORD + SZ_INT)/SZ_WORD];#endif    if (evt_data->flags == 1) { pos+=SZ_PTR/SZ_WORD; arg_ind=1; }        /* read each data in the event */    for(; arg_ind < evt_data->nargs; arg_ind++) {        ptt_arg_t v_type = evt_data->arg_type[arg_ind];        switch (v_type) {            case PTT_INT: list_int[nb_int++] = buf[pos++]; break;            case PTT_PTR:#if __WORDSIZE == 64                list_ptr[nb_ptr++] = (void *)(buf[pos] |                                     ((long long)(buf[pos+1]) << 32));                pos += SZ_PTR/SZ_WORD;#else                list_ptr[nb_ptr++] = (void *)buf[pos++];#endif	        break;            case PTT_UINT: list_uint[nb_uint++] = buf[pos++]; break;		            case PTT_ULL:                list_ll[nb_ll++] =  buf[pos] |                                    ((long long)(buf[pos+1]) << 32);                pos += SZ_ULL/SZ_WORD;                break;            default:                 printf("INVALID TYPE OF ARGUMENT\n"); return -1;        }    }    if (!fast)        list_ptr[nb_ptr++] = get_obj_name.get (event, 			     buf[(SZ_TIME + SZ_WORD)/SZ_WORD], list_ptr);    give_name.get (event, list_ptr, list_name);    return 1;}static int get_info (char **list_name, int *list_int, unsigned int *list_uint,                     long long *list_ll) {    return _get_info (list_name, list_int, list_uint, list_ll, 1);}static int read_bin(int *pid, ptt_timestamp_t* time, ptt_event_t* event,                    char **list_name, int *list_int, unsigned int *list_uint,                    long long *list_ll) {    if (waiting == 0) {        waiting = get_trace_filtered ();        if (waiting <= 0) return waiting;        pos = (SZ_TIME + SZ_WORD + SZ_INT + SZ_PTR)/SZ_WORD;    }    evt_ind = v_trace->nevts - waiting--;    *time = curr_time;    *event = get_event (evt_ind);    if (*event == EVT_NULL) return -1;    *pid = buf[(SZ_TIME + SZ_WORD)/SZ_WORD];    /* get the the event info */    return _get_info (list_name, list_int, list_uint, list_ll, 0);}static int read_fast(int *pid, ptt_timestamp_t* time, ptt_event_t* event) {    if (waiting == 0) {        waiting = get_trace_point ();        if (waiting <= 0) return waiting;        pos = (SZ_TIME + SZ_WORD + SZ_INT + SZ_PTR)/SZ_WORD;    }    evt_ind = v_trace->nevts - waiting--;;    *time = curr_time;    *event = get_event (evt_ind);    if (*event == EVT_NULL) return -1;    *pid = buf[(SZ_TIME + SZ_WORD)/SZ_WORD];    return 1;}static int init(char *filename, ptt_header_t *head) {    char arch_size;    stream = fopen (filename, "r");    if (stream == NULL) return -errno;    if (fread (&arch_size, 1, 1, stream) != 1) return -errno;    if (arch_size != sizeof (void*)) {        fprintf (stderr, "the number of bit of the arch changed\n");        return -1;    }    if (fread (head, sizeof (ptt_header_t), 1, stream) != 1) {        if (feof (stream)) {            fprintf (stderr, "the file is too short\n"); return -1;        }        perror ("read header failed"); return -errno;    }    if (head->byte_order != __BYTE_ORDER) {        fprintf(stderr, "endian is not the same\n"); return -1;    }    if (head->version.major != PTT_VERS_MAJOR) {        fprintf(stderr, "incorrect major version (%d != %d)\n",		head->version.major, PTT_VERS_MAJOR);        return -1;    }    if (head->version.minor != PTT_VERS_MINOR) {	fprintf(stderr, "warning : minor version is not the same "                "(%d != %d)\n", head->version.minor, PTT_VERS_MINOR);    }    freq_khz = head->freq_khz/1000;    if (!freq_khz) {        fprintf(stderr, "Invalid frequence : %d\n", head->freq_khz);        return -1;    }    if (head->file_number) {        file_prefix = strdup (filename);        file_prefix[strlen (filename) - sizeof ("-xxxx.bin") + 1] = 0;        file_number = head->file_number;    }    start_time = head->timestamp;    waiting = 0;    return get_obj_name.init();}static void close () {    if (stream) fclose(stream);    get_obj_name.close ();}struct read_trace read_trace = {    .init = init,    .read = read_bin,    .read_fast = read_fast,    .close = close,    .info = get_info,    .next = nextfile};

⌨️ 快捷键说明

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