📄 read.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 + -