diff -Nur src-20060401/runtime/bin_write.c src-modified/runtime/bin_write.c --- src-20060401/runtime/bin_write.c 1970-01-01 08:00:00.000000000 +0800 +++ src-modified/runtime/bin_write.c 2006-04-04 02:19:34.000000000 +0800 @@ -0,0 +1,354 @@ +// Binary Tracing runtime interface and example scripts. +// Originated from Hitachi's gBTI and Martin's ideas. +// +// main features: +// 1) store integers in binary format; +// 2) support to use string and integer as arguments +// +// http://sourceware.org/bugzilla/show_bug.cgi?id=2307 +// +// Copyright (C) 2006 IBM Corp +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// Created by: Gui,Jian +// 03/14/2006 Tom Zanussi : +// added event len (%n) specifier +// 03/21/2006 Tom Zanussi : +// added a common bin_swrite that avoids using relayfs directly +// moved this code here from bin_write.stp +// +#ifndef _BIN_WRITE_C +#define _BIN_WRITE_C + +static int skip_atoi(const char **s) +{ + int i=0; + + while (isdigit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + +int bin_vsnwrite(char *buf, size_t size, const char *fmt, va_list args) +{ + int i, len; + char *str, *end, c, *write_len = NULL; + const char *s; + int field_width, written, write_len_width = 0; + int qualifier; + int64_t temp; + + if(size < 0) + return 0; + + str = buf; + end = buf + size - 1; + + if(end < buf - 1) { + end = (void *) -1; + size = end - buf + 1; + } + + written = 0; + for (; *fmt ; ++fmt) { + if (*fmt != '%') { + if (str <= end) + *str = *fmt; + ++str; ++written; + continue; + } + + ++fmt; + + qualifier = -1; + if (*fmt == 'l' || *fmt == 'L') { + qualifier = *fmt; + ++fmt; + if (qualifier == 'l' && *fmt == 'l') { + qualifier = 'L'; + ++fmt; + } + } + + field_width = -1; + if (isdigit(*fmt)) + field_width = skip_atoi(&fmt); + + switch (*fmt) { + case 's': + s = (char *)va_arg(args, void *); + if ((unsigned long)s < PAGE_SIZE) + s = ""; + + len = strnlen(s, STP_STRING_SIZE); + + if(len <= 0) + len = 0; + for (i = 0; i < len; ++i) { + if (str <= end) { + *str = *s; + } + ++str; ++s; + } + if (str <= end) + *str = '\0'; + ++str; + written += len + 1; + continue; + + case '%': + if (str <= end) + *str = '%'; + ++str; ++written; + continue; + + case 'd': + case 'i': + temp = va_arg(args, int64_t); + if (qualifier == 'l') { + if((str + sizeof(long) - 1) <= end) + *(long *)str = (long)temp; + str += sizeof(long); + written += sizeof(long); + } + else if (qualifier == 'L') { + if((str + sizeof(long long) - 1) <= end) + *(long long *)str = (long long)temp; + str += sizeof(long long); + written += sizeof(long long); + } + else { + if((str + 3) <= end) + *(int32_t *)str = (int32_t)temp; + str += 4; + written += 4; + } + break; + case 'u': + temp = va_arg(args, int64_t); + if((str + 3) <= end) + *(uint32_t *)str = (uint32_t)temp; + str += 4; + written += 4; + break; + case 'b': + temp = va_arg(args, int64_t); + switch(field_width) { + case 1: + if(str <= end) + *(uint8_t *)str = (uint8_t)temp; + ++str; ++written; + break; + case 2: + if((str + 1) <= end) + *(uint16_t *)str = (uint16_t)temp; + str+=2; written += 2; + break; + case 8: + if((str + 7) <= end) + *(uint64_t *)str = (uint64_t)temp; + str+=8; written += 8; + break; + case 4: + default: // "%4b" by default + if((str + 3) <= end) + *(uint32_t *)str = (uint32_t)temp; + str+=4; written += 4; + break; + } + break; + case 'n': + temp = va_arg(args, int64_t); + write_len = str; + write_len_width = field_width; + switch(write_len_width) { + case 1: + ++str; ++written; + break; + case 2: + str += 2; written += 2; + break; + case 4: + default: + str += 4; written += 4; + break; + } + break; + default: + if (str <= end) + *str = '%'; + ++str; ++written; + if (*fmt) { + if (str <= end) + *str = *fmt; + ++str; ++written; + } else { + --fmt; + } + continue; + } + } + + if (str <= end) + *str = '\0'; + else if (size > 0) + *end = '\0'; + + if (write_len) { + switch(write_len_width) { + case 1: + if(write_len <= end) + *(uint8_t *)write_len = (uint8_t)written; + break; + case 2: + if((str + 1) <= end) + *(uint16_t *)write_len = (uint16_t)written; + break; + case 4: + default: // "%4n" by default + if((str + 3) <= end) + *(uint32_t *)write_len = (uint32_t)written; + break; + } + } + return written; +} + +int bin_vscnwrite(char *buf, size_t size, const char *fmt, va_list args) +{ + int i; + + i=bin_vsnwrite(buf, size, fmt, args); + return (i >= size) ? (size - 1) : i; +} + +#ifdef STP_RELAYFS +static inline void check_null_buffer(int cpu) +{ + if (!_stp_pbuf[cpu]) + _stp_pbuf[cpu] = relay_reserve(_stp_chan, STP_PRINT_BUF_LEN); +} +#else +static inline void check_null_buffer(int cpu) {} +#endif /* STP_RELAYFS */ + +/** + * bin_*write() will be similar to _stp_*printf() here. + * It writes data to _stp_pbuf and lets _stp_print_flush() handle the actual transport. + * No seq-id is generated in _stp_print_flush() in a non-relayfs relayfs-mode. + */ +void bin_vswrite(String str, const char *fmt, va_list args) +{ + int cpu, size, num; + char *buf=NULL; + + if (str == _stp_stdout) { + cpu = smp_processor_id(); + check_null_buffer(cpu); + buf = &_stp_pbuf[cpu][0] + _stp_pbuf_len[cpu]; + size = STP_PRINT_BUF_LEN -_stp_pbuf_len[cpu] + 1; + num = bin_vsnwrite(buf, size, fmt, args); + if (num < size) + _stp_pbuf_len[cpu] += num; + else { + _stp_pbuf_len[cpu] = STP_PRINT_BUF_LEN; + _stp_print_flush(); + } + } else { + num = bin_vscnwrite(str->buf + str->len, STP_STRING_SIZE - str->len, fmt, args); + if (num > 0) + str->len += num; + } +} + +#ifdef STP_RELAYFS +#if (RELAYFS_CHANNEL_VERSION >= 4) +static inline void handle_overflow(char *prev_stp_pbuf, int cpu) +{ + struct rchan_buf *buf = _stp_chan->buf[cpu]; + size_t last; + + if ((prev_stp_pbuf != _stp_pbuf[cpu]) && + _stp_pbuf[cpu] == _stp_pbuf_scratch) { + last = (buf->subbufs_produced - 1) % n_subbufs; + buf->padding[last] = STP_PRINT_BUF_LEN - _stp_pbuf_len[cpu]; + buf->prev_padding = buf->padding[last]; + } +} +#else +static inline void handle_overflow(char *prev_stp_pbuf, int cpu) +{ + struct rchan_buf *buf = _stp_chan->buf[cpu]; + size_t produced = atomic_read(&buf->subbufs_produced) - 1; + size_t last; + + if ((prev_stp_pbuf != _stp_pbuf[cpu]) && + _stp_pbuf[cpu] == _stp_pbuf_scratch) { + last = (produced -1) % n_subbufs; + buf->padding[last] = STP_PRINT_BUF_LEN - _stp_pbuf_len[cpu]; + } +} +#endif /* (RELAYFS_CHANNEL_VERSION >= 4) */ +#else +static inline void handle_overflow(char *prev_stp_pbuf, int cpu) {} +#endif /* STP_RELAYFS */ + +#define STP_BIN 1 +#ifndef STP_BIN +static inline void terminate_string(char *buf) +{ + *buf ='\0'; +} +#else +static inline void terminate_string(char *buf) {} +#endif /* STP_BIN */ + +void bin_swrite(String str, const char *fmt, ...) +{ + int num; + va_list args; + + if (str == _stp_stdout) { + char *buf; + int size; + int cpu = smp_processor_id(); + check_null_buffer(cpu); + buf = &_stp_pbuf[cpu][0] + _stp_pbuf_len[cpu]; + size = STP_PRINT_BUF_LEN - _stp_pbuf_len[cpu] + 1; + va_start(args, fmt); + num = bin_vsnwrite(buf, size, fmt, args); + va_end(args); + if (unlikely(num >= size)) { + char *prev_stp_pbuf = _stp_pbuf[cpu]; + /* overflowed the buffer */ + if (_stp_pbuf_len[cpu] == 0) { + _stp_pbuf_len[cpu] = STP_PRINT_BUF_LEN; + _stp_print_flush(); + } else { + terminate_string(buf); + _stp_pbuf_len[cpu] = STP_PRINT_BUF_LEN; + _stp_print_flush(); + va_start(args, fmt); + bin_vswrite(_stp_stdout, fmt, args); + va_end(args); + } + handle_overflow(prev_stp_pbuf, cpu); + } else { + _stp_pbuf_len[cpu] += num; + } + } else { + va_start(args, fmt); + num = bin_vscnwrite(str->buf + str->len, STP_STRING_SIZE - str->len, fmt, args); + va_end(args); + if (likely(num > 0)) + str->len += num; + } +} + +#define bin_write(args...) bin_swrite(_stp_stdout, args) + +#endif//_BIN_WRITE_C diff -Nur src-20060401/runtime/print.c src-modified/runtime/print.c --- src-20060401/runtime/print.c 2005-11-01 03:23:21.000000000 +0800 +++ src-modified/runtime/print.c 2006-04-04 05:15:05.000000000 +0800 @@ -35,6 +35,11 @@ static int _stp_pbuf_len[NR_CPUS]; +int get_stp_pbuf_len(int cpu) +{ + return _stp_pbuf_len[cpu]; +} + #ifndef STP_RELAYFS #define STP_PRINT_BUF_START 0 @@ -71,15 +76,15 @@ #else /* STP_RELAYFS */ /* size of timestamp, in bytes, including space */ -#define TIMESTAMP_SIZE (sizeof(int)) -#define STP_PRINT_BUF_START (TIMESTAMP_SIZE) +#define STP_PRINT_BUF_START 0 /** Size of buffer, not including terminating NULL */ #ifndef STP_PRINT_BUF_LEN -#define STP_PRINT_BUF_LEN (8192 - TIMESTAMP_SIZE - 1) +#define STP_PRINT_BUF_LEN (8192 - sizeof(int)) #endif -static char _stp_pbuf[NR_CPUS][STP_PRINT_BUF_LEN + STP_PRINT_BUF_START + 1]; +static char *_stp_pbuf[NR_CPUS]; +static char _stp_pbuf_scratch[STP_PRINT_BUF_LEN]; /** Send the print buffer to the transport now. * Output accumulates in the print buffer until it @@ -90,25 +95,22 @@ void _stp_print_flush (void) { int cpu = smp_processor_id(); - char *buf = &_stp_pbuf[cpu][0]; - char *ptr = buf + STP_PRINT_BUF_START; int ret; if (_stp_pbuf_len[cpu] == 0) return; - *((int *)buf) = _stp_seq_inc(); - ret = _stp_transport_write(buf, _stp_pbuf_len[cpu] + TIMESTAMP_SIZE + 1); - if (unlikely(ret < 0)) { -#if 0 - if (!atomic_read(&_stp_transport_failures)) - _stp_warn("Transport failure - try using a larger buffer size\n"); -#endif - atomic_inc (&_stp_transport_failures); + if (_stp_pbuf_len[cpu] == STP_PRINT_BUF_LEN) { + int length; + length = relay_switch_subbuf(_stp_chan->buf[cpu], STP_PRINT_BUF_LEN); + if(!length) + return; + _stp_pbuf[cpu] = relay_reserve(_stp_chan, STP_PRINT_BUF_LEN); + if (_stp_pbuf[cpu] == NULL) + _stp_pbuf[cpu] = _stp_pbuf_scratch; + else + _stp_pbuf_len[cpu] = 0; } - - _stp_pbuf_len[cpu] = 0; - *ptr = 0; } #endif /* STP_RELAYFS */ diff -Nur src-20060401/runtime/runtime.h src-modified/runtime/runtime.h --- src-20060401/runtime/runtime.h 2005-11-29 06:08:39.000000000 +0800 +++ src-modified/runtime/runtime.h 2006-04-04 02:19:34.000000000 +0800 @@ -59,6 +59,7 @@ #endif /* RELAYFS */ #include "print.c" +#include "bin_write.c" #include "string.c" #include "arith.c" #include "copy.c" diff -Nur src-20060401/runtime/stpd/Makefile src-modified/runtime/stpd/Makefile --- src-20060401/runtime/stpd/Makefile 2005-08-25 00:27:35.000000000 +0800 +++ src-modified/runtime/stpd/Makefile 2006-04-04 02:19:34.000000000 +0800 @@ -1,6 +1,6 @@ all: stpd stp_merge stp_dump -stpd: stpd.c librelay.c ../transport/transport_msgs.h librelay.h +stpd: stpd.c librelay.c print_binary.c ../transport/transport_msgs.h librelay.h gcc -Wall -O3 -o stpd stpd.c librelay.c -lpthread stp_merge: stp_merge.c diff -Nur src-20060401/runtime/stpd/librelay.c src-modified/runtime/stpd/librelay.c --- src-20060401/runtime/stpd/librelay.c 2006-03-07 04:42:22.000000000 +0800 +++ src-modified/runtime/stpd/librelay.c 2006-04-04 02:19:34.000000000 +0800 @@ -52,7 +52,7 @@ } params; /* temporary per-cpu output written here for relayfs, filebase0...N */ -static char *percpu_tmpfilebase = "stpd_cpu"; +char *percpu_tmpfilebase = "stpd_cpu"; /* procfs files */ static char proc_filebase[128]; @@ -63,7 +63,7 @@ /* internal variables */ static int transport_mode; -static int ncpus; +int ncpus; static int print_totals; static int exiting; static int processing; @@ -99,6 +99,9 @@ unsigned max_backlog; /* max # sub-buffers ready at one time */ } status[NR_CPUS]; +/* for now, so we don't have to mess with build system */ +#include "print_binary.c" + /** * streaming - is the current transport mode streaming or not? * @@ -128,8 +131,6 @@ return write(control_channel, buf, len+4); } - - /** * summarize - print a summary if applicable */ @@ -639,7 +640,7 @@ /* what about child processes? we will wait for them here. */ err = waitpid(-1, NULL, WNOHANG); if (err >= 0) - fprintf(stderr,"\nWaititing for processes to exit\n"); + fprintf(stderr,"\nWaiting for processes to exit\n"); while(wait(NULL) > 0); if (transport_mode == STP_TRANSPORT_RELAYFS) { @@ -662,8 +663,11 @@ if (transport_mode == STP_TRANSPORT_RELAYFS && merge) { close_all_relayfs_files(); - merge_output(); - delete_percpu_files(); + if (0) + merge_output(); + print_binary(); + if (0) + delete_percpu_files(); } dbug("closing control channel\n"); diff -Nur src-20060401/runtime/stpd/print_binary.c src-modified/runtime/stpd/print_binary.c --- src-20060401/runtime/stpd/print_binary.c 1970-01-01 08:00:00.000000000 +0800 +++ src-modified/runtime/stpd/print_binary.c 2006-04-04 02:19:34.000000000 +0800 @@ -0,0 +1,350 @@ +/* + * print_binary - print binary data from bin_write + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) IBM, 2006 + * + * Created by: Tom Zanussi + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* maximum number of CPUs we can handle - change if more */ +#define NR_CPUS 256 + +extern int ncpus; + +/* probe output written here, if non-NULL */ +extern char *outfile_name; + +/* temporary per-cpu output written here for relayfs, filebase0...N */ +extern char *percpu_tmpfilebase; + +#define MAX_EVENTS 256 +#define MAX_EVENT_NAME 256 +#define MAX_FIELD_NAME 32 +#define MAX_FIELD_TYPE 64 +#define MAX_FIELDS 32 + +enum +{ + INT, + UINT, + LONG, + ULONG, + CHAR, + UCHAR, + STRING, + TIMEVAL, +} cached_field_type; + +struct field +{ + char name[MAX_FIELD_NAME]; + char type[MAX_FIELD_TYPE]; + int cached_field_type; +}; + +struct event +{ + unsigned char id; + char name[MAX_EVENT_NAME]; + struct field *field_list[MAX_FIELDS]; + int field_count; +}; + +struct header +{ + unsigned char id; + struct timeval time; +} __attribute__((__packed__)); + +static struct event *events[MAX_EVENTS]; + +/* per-cpu buffer info */ +static struct +{ + off_t total_buf_size; + void *buf; + struct header *next_event; /* NULL if at end of buffer */ +} rbuf_info[NR_CPUS]; + +static int smallest_i; +struct header *next_smallest(int n_cpus_ready) +{ + int i; + struct header *next, *smallest = NULL; + + for (i = 0; i < n_cpus_ready; i++) { + next = rbuf_info[i].next_event; + if (!rbuf_info[i].total_buf_size) + continue; + if (next) { + if (!smallest) { + smallest = next; + smallest_i = i; + continue; + } + if(next->time.tv_sec < + smallest->time.tv_sec) { + smallest = next; + smallest_i = i; + continue; + } + if ((next->time.tv_sec == smallest->time.tv_sec) && + (next->time.tv_usec < smallest->time.tv_usec)) { + smallest = next; + smallest_i = i; + continue; + } + } + } + return smallest; +} + +/** + * print_field - generic field print function, based on field type + */ +static int print_field(FILE *stream, char *buf, struct field *field, + int print_field_name) +{ + int len = 0, offset = 0; + + if (print_field_name) + fprintf(stream, "%s: ", field->name); + + switch(field->cached_field_type) { + case INT: + fprintf(stream, "%d", *((int *)(buf + offset))); + len = sizeof(int); + break; + case UINT: + fprintf(stream, "%u", *((unsigned int *)(buf + offset))); + len = sizeof(unsigned int); + break; + case LONG: + fprintf(stream, "%ld", *((long *)(buf + offset))); + len = sizeof(long); + break; + case ULONG: + fprintf(stream, "%ld", *((unsigned long *)(buf + offset))); + len = sizeof(unsigned long); + break; + case CHAR: + fprintf(stream, "%d", *((char *)(buf + offset))); + len = sizeof(char); + break; + case UCHAR: + fprintf(stream, "%u", *((unsigned char *)(buf + offset))); + len = sizeof(unsigned char); + break; + case STRING: + len = strlen(buf + offset) + 1; + fprintf(stream, "%s", buf + offset); + break; + case TIMEVAL: + fprintf(stream, "%ld.", *((time_t *)(buf + offset))); + fprintf(stream, "%06ld", + *((suseconds_t *)(buf + offset + sizeof(time_t)))); + len = sizeof(struct timeval); + break; + default: + len = 0; + fprintf(stderr, "Couldn't print field %s\n", field->name); + break; + } + + return len; +} + +/** + * add_field - add a field to event + */ +static void add_field(struct event *event, char *name, int type) +{ + struct field *field = malloc(sizeof(struct field)); + + strcpy(field->name, name); + field->cached_field_type = type; + event->field_list[event->field_count++] = field; +} + +/** + * add_event - add a new event + */ +static struct event *add_event(unsigned char id, char *name) +{ + struct event *event = calloc(1, sizeof(struct event)); + + strcpy(event->name, name); + event->id = id; + events[id] = event; + + return event; +} + +/** + * register_event - register a new event type + */ +static int register_event(char *raw_event) +{ + int i, offset; + int n_fields, field_type; + unsigned char new_id; + struct event *event; + + offset = sizeof(struct header); + + new_id = *((unsigned char *)(raw_event + offset)); + offset += sizeof(unsigned char); + + event = add_event(new_id, raw_event + offset); + offset += strlen(raw_event + offset) + 1; + + n_fields = *((int *)(raw_event + offset)); + offset += sizeof(int); + + for (i = 0; i < n_fields; i++) { + field_type = *((int *)(raw_event + offset)); + offset += sizeof(int); + + add_field(event, raw_event + offset, field_type); + offset += strlen(raw_event + offset) + 1; + } + + return offset; +} + +/** + * print_event - generic event print function + */ +static int print_event(FILE *stream, char *buf, struct event *event, + int cpu) +{ + int i; + int size = 0; + + if (ncpus > 1) + fprintf(stream, "<%d> ", cpu); + fprintf(stream, "%s: ", event->name); + for (i = 0; i < MAX_FIELDS; i++) { + if (!event->field_list[i]) + break; + size += print_field(stream, buf + size, event->field_list[i], 1); + fprintf(stream, ", "); + } + fprintf(stream, "\n"); + + return size; +} + +/** + * process_events - process events from file + */ +static int process_events(int n_cpus_ready) +{ + void *buf; + struct header *header; + struct event *event; + int size; + int events_processed = 0; + + while ((buf = header = next_smallest(n_cpus_ready))) { + event = events[header->id]; + if (event) + size = print_event(stdout, buf, event, smallest_i); + else { + if (header->id == MAX_EVENTS - 1) + size = register_event(buf); + else { + fprintf(stderr, "error: unregistered event id %d\n", header->id); + return -1; + } + } + events_processed++; + rbuf_info[smallest_i].next_event = buf + size; + rbuf_info[smallest_i].total_buf_size -= size; + } + + return events_processed; +} + +/** + * postprocess - postprocess event output + */ +int print_binary(void) +{ + int i; + struct stat st; + char tmp[PATH_MAX]; + FILE *ofp; + int fp[ncpus]; + int events_processed = 0; + + for (i = 0; i < ncpus; i++) { + sprintf (tmp, "%s%d", percpu_tmpfilebase, i); + fp[i] = open(tmp, O_RDONLY); + if (!fp[i]) { + fprintf (stderr, "error opening file %s.\n", tmp); + return -1; + } + + if (fstat(fp[i], &st) < 0) + return -1; + + if (!st.st_size) { + rbuf_info[i].next_event = NULL; + continue; + } + + rbuf_info[i].buf = mmap(NULL, st.st_size, PROT_READ, + MAP_PRIVATE, fp[i], 0); + if(rbuf_info[i].buf == MAP_FAILED) + { + printf("Couldn't mmap input for cpu %d, err = %s \n", + i, strerror(errno)); + close(fp[i]); + return -1; + } + + rbuf_info[i].next_event = rbuf_info[i].buf; + rbuf_info[i].total_buf_size = st.st_size; + } + + ofp = fopen (outfile_name, "w"); + if (!ofp) { + fprintf (stderr, "ERROR: couldn't open outfile %s: err = %s\n", + outfile_name, strerror(errno)); + return -1; + } + + events_processed = process_events(ncpus); + if (events_processed < 0) + return -1; + + printf("events_processed: %d\n", events_processed); + + return 0; +} diff -Nur src-20060401/runtime/stpd/stpd.c src-modified/runtime/stpd/stpd.c --- src-20060401/runtime/stpd/stpd.c 2006-03-16 00:15:23.000000000 +0800 +++ src-modified/runtime/stpd/stpd.c 2006-04-04 02:19:34.000000000 +0800 @@ -35,7 +35,7 @@ int print_only = 0; int quiet = 0; -int merge = 1; +int merge = 0; int verbose = 0; int enable_relayfs = 1; int target_pid = 0; diff -Nur src-20060401/runtime/string.c src-modified/runtime/string.c --- src-20060401/runtime/string.c 2006-03-31 04:54:00.000000000 +0800 +++ src-modified/runtime/string.c 2006-04-04 02:19:34.000000000 +0800 @@ -59,9 +59,12 @@ int num; va_list args; if (str == _stp_stdout) { + char *buf; + int size; int cpu = smp_processor_id(); - char *buf = &_stp_pbuf[cpu][STP_PRINT_BUF_START] + _stp_pbuf_len[cpu]; - int size = STP_PRINT_BUF_LEN -_stp_pbuf_len[cpu] + 1; + check_null_buffer(cpu); + buf = &_stp_pbuf[cpu][STP_PRINT_BUF_START] + _stp_pbuf_len[cpu]; + size = STP_PRINT_BUF_LEN -_stp_pbuf_len[cpu] + 1; va_start(args, fmt); num = vsnprintf(buf, size, fmt, args); va_end(args); @@ -98,9 +101,13 @@ { int num; if (str == _stp_stdout) { - int cpu = smp_processor_id(); - char *buf = &_stp_pbuf[cpu][STP_PRINT_BUF_START] + _stp_pbuf_len[cpu]; - int size = STP_PRINT_BUF_LEN -_stp_pbuf_len[cpu] + 1; + char *buf; + int cpu; + int size; + cpu = smp_processor_id(); + check_null_buffer(cpu); + buf = &_stp_pbuf[cpu][STP_PRINT_BUF_START] + _stp_pbuf_len[cpu]; + size = STP_PRINT_BUF_LEN -_stp_pbuf_len[cpu] + 1; num = vsnprintf(buf, size, fmt, args); if (num < size) _stp_pbuf_len[cpu] += num; diff -Nur src-20060401/runtime/transport/transport.c src-modified/runtime/transport/transport.c --- src-20060401/runtime/transport/transport.c 2006-03-16 23:14:39.000000000 +0800 +++ src-modified/runtime/transport/transport.c 2006-04-04 02:19:34.000000000 +0800 @@ -122,6 +122,19 @@ } #endif +extern int get_stp_pbuf_len(int cpu); + +static void _stp_trunc_final(struct rchan *chan) +{ + int i; + struct rchan_buf *buf; + + for_each_online_cpu(i) { + buf = chan->buf[i]; + buf->offset = get_stp_pbuf_len(i) + sizeof(int); + } +} + static void _stp_cleanup_and_exit (int dont_rmmod) { int failures; @@ -138,6 +151,7 @@ #ifdef STP_RELAYFS if (_stp_transport_mode == STP_TRANSPORT_RELAYFS) { + _stp_trunc_final(_stp_chan); relay_flush(_stp_chan); } #endif @@ -264,7 +278,6 @@ return 0; } - /* like relay_write except returns an error code */ #ifdef STP_RELAYFS