Example #1
0
/*
 * \brief This method should be called when a trace should be dumped.
 *
 * (Based upon a different application calling trace_flush() or so.)
 */
static void bfscope_trace_dump(void)
{
    if(dump_in_progress) {
        // Currently there is already a dump in progress, do nothing.
        return;
    }

    int number_of_events = 0;
    // Acquire the trace buffer
    trace_length = trace_dump(trace_buf, BFSCOPE_BUFLEN, &number_of_events);

    DEBUG("bfscope: trace length %lu, nr. of events %d\n", trace_length, number_of_events);

    if (trace_length <= 0 || number_of_events <= 0) {
        DEBUG("bfscope: trace length too small, not dumping.\n");
        return;
    }

    dump_in_progress = true;


    if (bfscope_client != NULL) {
        // We have a connected client, dump to network
        bfscope_trace_dump_network();
    } else {
        // There is no client, just dump to console
        bfscope_trace_dump_console();
    }
}
Example #2
0
static void handle_cache_load_done(void)
{
	if (!are_all_pages_loaded()) {
		return;
	}
    DEBUGPRINT("initial_cache_load: entire cache loaded done\n");
    cache_loading_phase = false;

    /* FIXME: stop the trace. */
#if ENABLE_WEB_TRACING
    trace_event(TRACE_SUBSYS_NET, TRACE_EVENT_NET_STOP, 0);

    char *buf = malloc(4096*4096);
    trace_dump(buf, 4096*4096, NULL);
    printf("%s\n", buf);

#endif // ENABLE_WEB_TRACING


    // lwip_benchmark_control(1, BMS_STOP_REQUEST, 0, 0);
    // Report the cache loading time
    printf("Cache loading time %"PU"\n", in_seconds(rdtsc() - last_ts));
//    lwip_print_interesting_stats();

    /* continue with the web-server initialization. */
    init_callback(); /* do remaining initialization! */
}
Example #3
0
/* ARGSUSED */
void
sigtrace_dump(int s)
{
	trace_dump();
	if (signal(s, sigtrace_dump) == SIG_ERR)
		msglog("signal: %s", rip_strerror(errno));
}
Example #4
0
/*
 * To write a register, start transaction, transfer data to the TPM, deassert
 * CS when done.
 *
 * Returns one to indicate success, zero to indicate failure.
 */
static int tpm2_write_reg(unsigned reg_number, const void *buffer, size_t bytes)
{
	struct spi_slave *spi_slave = car_get_var_ptr(&g_spi_slave);
	trace_dump("W", reg_number, bytes, buffer, 0);
	if (!start_transaction(false, bytes, reg_number))
		return 0;
	write_bytes(buffer, bytes);
	spi_release_bus(spi_slave);
	return 1;
}
Example #5
0
// This function is called whenever new data arrives for client
void handle_data_arrived(char *payload, size_t data_len)
{

    volatile uint8_t *b =(uint8_t *)payload;
    if (read_incoming) {
        for (int i = 0; i< data_len; i++) {
            acc += (b[i]);
        }
    }

    if (is_server) {
        return;
    }

#if TRACE_ONLY_LLNET
    trace_event(TRACE_SUBSYS_LLNET, TRACE_EVENT_LLNET_APPRX, 0);
#endif // TRACE_ONLY_LLNET


    // record completion time
    cycles_t tsc = rdtsc();
    cycles_t result[1] = {
        tsc - sent_at,
    };

    if (bench_ctl_add_run(bench_ctl, result)) {
        uint64_t tscperus = tscperms / 1000;
        printf("cycles per us %"PRIu64"\n", tscperus);

        // Output our results
       bench_ctl_dump_csv_bincounting(bench_ctl, 0, 100, 9 * tscperus,
                    25 * tscperus, out_prefix, tscperus);

       bench_ctl_dump_analysis(bench_ctl, 0,  out_prefix, tscperus);

       // bench_ctl_dump_csv(bench_ctl, out_prefix, tscperus);

#if TRACE_ONLY_LLNET
            trace_event(TRACE_SUBSYS_LLNET, TRACE_EVENT_LLNET_STOP, 0);
            size_t trsz = trace_dump(trbuf, sizeof(trbuf) - 1, NULL);
            trbuf[trsz] = 0;
            printf("\n\n\n\nTrace results:\n%s\n\n\n", trbuf);
#endif // TRACE_ONLY_LLNET



        bench_ctl_destroy(bench_ctl);
        terminate_benchmark();
        printf("pkt content some is %zd\n", acc);
        return;
    }

    start_next_iteration();
} // end function: handle_data_arrived
Example #6
0
/*
 * To read a register, start transaction, transfer data from the TPM, deassert
 * CS when done.
 *
 * Returns one to indicate success, zero to indicate failure. In case of
 * failure zero out the user buffer.
 */
static int tpm2_read_reg(unsigned reg_number, void *buffer, size_t bytes)
{
	struct spi_slave *spi_slave = car_get_var_ptr(&g_spi_slave);
	if (!start_transaction(true, bytes, reg_number)) {
		memset(buffer, 0, bytes);
		return 0;
	}
	read_bytes(buffer, bytes);
	spi_release_bus(spi_slave);
	trace_dump("R", reg_number, bytes, buffer, 0);
	return 1;
}
Example #7
0
int main(int argc, char *argv[])
{
    volatile uint64_t workcnt = 0;
    int nthreads;

    debug_printf("bomptest started.\n");

    bench_init();

#if CONFIG_TRACE
    errval_t err = trace_control(TRACE_EVENT(TRACE_SUBSYS_ROUTE,
                                             TRACE_EVENT_ROUTE_BENCH_START, 0),
                                 TRACE_EVENT(TRACE_SUBSYS_ROUTE,
                                             TRACE_EVENT_ROUTE_BENCH_STOP, 0), 0);
    assert(err_is_ok(err));
#endif

    if(argc == 2) {
        nthreads = atoi(argv[1]);
        backend_span_domain(nthreads, STACK_SIZE);
        bomp_custom_init(NULL);
        omp_set_num_threads(nthreads);
    } else {
        assert(!"Specify number of threads");
    }

    trace_event(TRACE_SUBSYS_ROUTE, TRACE_EVENT_ROUTE_BENCH_START, 0);

    uint64_t start = bench_tsc();
#pragma omp parallel
    while(rdtsc() < start + 805000000ULL) {
        workcnt++;
    }
    uint64_t end = bench_tsc();

    trace_event(TRACE_SUBSYS_ROUTE, TRACE_EVENT_ROUTE_BENCH_STOP, 0);

    printf("done. time taken: %" PRIu64 " cycles.\n", end - start);

#if CONFIG_TRACE
        char *buf = malloc(4096*4096);
        trace_dump(buf, 4096*4096, NULL);
        printf("%s\n", buf);
#endif

    for(;;);
    return 0;
}
Example #8
0
void *zpu_thread(void*data)
{
	int r;
	do {
		r = execute();
		if (r==0) { // Requested halt

			pthread_mutex_lock(&zpu_halted_lock);
			zpu_halted_flag=1;
			pthread_mutex_unlock(&zpu_halted_lock);
			pthread_cond_broadcast(&zpu_halted_cond);
			// Wait for resume
			printf("ZPU core halted\n");
			pthread_mutex_lock(&zpu_resume_lock);
			while (!zpu_resume_flag)
				pthread_cond_wait(&zpu_resume_cond,&zpu_resume_lock);
			zpu_resume_flag=0;
			pthread_mutex_lock(&zpu_halted_lock);
			zpu_halted_flag=0;
			pthread_mutex_unlock(&zpu_halted_lock);
			
			pthread_mutex_unlock(&zpu_resume_lock);
			if (do_exit)
				return NULL;
		} else {
			// We caught a BREAK instruction
			printf("BREAK instruction, PC %08x SP %08x\n",_upc,_usp);
			trace_dump();
			//abort();
			pthread_mutex_lock(&zpu_halted_lock);
			zpu_halted_flag=1;
			pthread_mutex_unlock(&zpu_halted_lock);
			pthread_cond_broadcast(&zpu_halted_cond);
			// Wait for resume
			printf("ZPU core halted\n");
			pthread_mutex_lock(&zpu_resume_lock);
			while (!zpu_resume_flag)
				pthread_cond_wait(&zpu_resume_cond,&zpu_resume_lock);
			zpu_resume_flag=0;
			pthread_mutex_lock(&zpu_halted_lock);
			zpu_halted_flag=0;
			pthread_mutex_unlock(&zpu_halted_lock);
			
			pthread_mutex_unlock(&zpu_resume_lock);
		}
	} while(1);
	return NULL;
}
Example #9
0
/* log a change in tracing */
void
tracelevel_msg(const char *pat,
    int dump)		/* -1=no dump, 0=default, 1=force */
{
	static const char *off_msgs[MAX_TRACELEVEL] = {
		"Tracing actions stopped",
		"Tracing packets stopped",
		"Tracing packet contents stopped",
		"Tracing kernel changes stopped",
		"Tracing routing socket messages stopped",
	};
	static const char *on_msgs[MAX_TRACELEVEL] = {
		"Tracing actions started",
		"Tracing packets started",
		"Tracing packet contents started",
		"Tracing kernel changes started",
		"Tracing routing socket messages started",
	};
	uint_t old_tracelevel = tracelevel;


	if (new_tracelevel < 0)
		new_tracelevel = 0;
	else if (new_tracelevel > MAX_TRACELEVEL)
		new_tracelevel = MAX_TRACELEVEL;

	if (new_tracelevel < tracelevel) {
		if (new_tracelevel <= 0) {
			trace_off(pat, off_msgs[0]);
		} else {
			do {
				tmsg(pat, off_msgs[tracelevel]);
			} while (--tracelevel != new_tracelevel);
		}

	} else if (new_tracelevel > tracelevel) {
		do {
			tmsg(pat, on_msgs[tracelevel++]);
		} while (tracelevel != new_tracelevel);
	}

	if (dump > 0 ||
	    (dump == 0 && old_tracelevel == 0 && tracelevel != 0))
		trace_dump();
}
Example #10
0
// continue experiment
static void experiment_cont(void* arg)
{

    errval_t err;
    static bool flag = false;
    static int message_type = 0;

    // Experiment finished (with this message type)
    if (i == MAX_COUNT - 1) {

#if CONFIG_TRACE
#else
        // print measured times
        for (int j = MAX_COUNT / 10; j < MAX_COUNT; j++) {

            printf(
                    "page %d took %"PRIuCYCLES"\n",
                    j,
                    timestamps[j].time1 - bench_tscoverhead()
                            - timestamps[j].time0);
        }
#endif
        // go to next message type
        message_type++;
        flag = false;
        i = 0;
        if (message_type > 13) {

            // stop tracing
            err = trace_event(TRACE_SUBSYS_MULTIHOP,
                    TRACE_EVENT_MULTIHOP_BENCH_STOP, 0);
            if (err_is_fail(err)) {
                USER_PANIC_ERR(err, "trace_event failed");
            }

#if CONFIG_TRACE
            // dump trace
            char *buf = malloc(50*4096*4096);
            size_t length = trace_dump(buf, 20*4096*4096, NULL);
            printf("%s\n", buf);
            printf("length of buffer %lu\n", length);
#endif
            printf("client done!\n");
            return;
        }
    }

    if (!flag) { // Start experiment

#if CONFIG_TRACE
#else
        printf("Running latency test for message %s...\n",
                get_message_name(message_type));
#endif
        flag = true;
        timestamps[i].time0 = bench_tsc();
    } else { // Continue experiment
        i++;
        timestamps[i].time0 = bench_tsc();
    }

    // trace send event
    err = trace_event(TRACE_SUBSYS_MULTIHOP, TRACE_EVENT_MULTIHOP_MESSAGE_SEND,
            message_type);
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "trace_event failed");
    }

    // send next message
    switch (message_type) {
    case 0:
        err = binding->tx_vtbl.fsb_empty_request(binding, NOP_CONT);
        break;
    case 1:
        err = binding->tx_vtbl.fsb_payload32_1_request(binding, NOP_CONT, 1);
        break;

    case 2:
        err = binding->tx_vtbl.fsb_payload32_2_request(binding, NOP_CONT, 1, 2);
        break;

    case 3:
        err = binding->tx_vtbl.fsb_payload32_4_request(binding, NOP_CONT, 1, 2,
                3, 4);
        break;

    case 4:
        err = binding->tx_vtbl.fsb_payload32_8_request(binding, NOP_CONT, 1, 2,
                3, 4, 5, 6, 7, 8);
        break;

    case 5:
        err = binding->tx_vtbl.fsb_payload32_16_request(binding, NOP_CONT, 1, 2,
                3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
        break;

    case 6:
        err = binding->tx_vtbl.fsb_payload64_1_request(binding, NOP_CONT, 1);
        break;

    case 7:
        err = binding->tx_vtbl.fsb_payload64_2_request(binding, NOP_CONT, 1, 2);
        break;

    case 8:
        err = binding->tx_vtbl.fsb_payload64_4_request(binding, NOP_CONT, 1, 2,
                3, 4);
        break;

    case 9:
        err = binding->tx_vtbl.fsb_payload64_8_request(binding, NOP_CONT, 1, 2,
                3, 4, 5, 6, 7, 8);
        break;

    case 10:
        err = binding->tx_vtbl.fsb_payload64_16_request(binding, NOP_CONT, 1, 2,
                3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
        break;

    case 11:
        err = binding->tx_vtbl.fsb_buffer_request(binding, NOP_CONT, &buffer,
                1);
        break;

    case 12:
        err = binding->tx_vtbl.fsb_buffer_request(binding, NOP_CONT, buffer2,
                100);
        break;

    case 13:
        err = binding->tx_vtbl.fsb_buffer_request(binding, NOP_CONT, buffer3,
                1000);
        break;

    default:
        printf("unknown message type\n");
        abort();
        break;
    }

    // make sure send was successful
    if (err_is_fail(err)) {
        USER_PANIC_ERR(err, "while running experiment\n");
    }

    // receive reply (by dispatching events from the
    // waitset we use for the benchmark)
    while (reply_received == false) {
        event_dispatch(&signal_waitset);
    }

    experiment();
}
Example #11
0
void
set_tracefile(const char *filename,
	      const char *pat,
	      int dump)			/* -1=no dump, 0=default, 1=force */
{
	struct stat stbuf;
	FILE *n_ftrace;
	const char *fn;


	/* Allow a null filename to increase the level if the trace file
	 * is already open or if coming from a trusted source, such as
	 * a signal or the command line.
	 */
	if (filename == NULL || filename[0] == '\0') {
		filename = NULL;
		if (ftrace == NULL) {
			if (inittracename[0] == '\0') {
				msglog("missing trace file name");
				return;
			}
			fn = inittracename;
		} else {
			fn = NULL;
		}

	} else if (!strcmp(filename,"dump/../table")) {
		trace_dump();
		return;

	} else {
		/* Allow the file specified with "-T file" to be reopened,
		 * but require all other names specified over the net to
		 * match the official path.  The path can specify a directory
		 * in which the file is to be created.
		 */
		if (strcmp(filename, inittracename)
#ifdef _PATH_TRACE
		    && (strncmp(filename, _PATH_TRACE, sizeof(_PATH_TRACE)-1)
			|| strstr(filename,"../")
			|| 0 > stat(_PATH_TRACE, &stbuf))
#endif
		    ) {
			msglog("wrong trace file \"%s\"", filename);
			return;
		}

		/* If the new tracefile exists, it must be a regular file.
		 */
		if (stat(filename, &stbuf) >= 0 && !S_ISREG(stbuf.st_mode)) {
			msglog("wrong type (%#x) of trace file \"%s\"",
			       stbuf.st_mode, filename);
			return;
		}

		fn = filename;
	}

	if (fn != NULL) {
		n_ftrace = fopen(fn, "a");
		if (n_ftrace == NULL) {
			msglog("failed to open trace file \"%s\" %s",
			       fn, strerror(errno));
			if (fn == inittracename)
				inittracename[0] = '\0';
			return;
		}

		tmsg("switch to trace file %s", fn);

		trace_close(file_trace = 1);

		if (fn != savetracename)
			strncpy(savetracename, fn, sizeof(savetracename)-1);
		ftrace = n_ftrace;

		fflush(stdout);
		fflush(stderr);
		dup2(fileno(ftrace), STDOUT_FILENO);
		dup2(fileno(ftrace), STDERR_FILENO);
	}

	if (new_tracelevel == 0 || filename == NULL)
		new_tracelevel++;
	tracelevel_msg(pat, dump != 0 ? dump : (filename != NULL));
}
Example #12
0
size_t tpm2_process_command(const void *tpm2_command, size_t command_size,
			    void *tpm2_response, size_t max_response)
{
	uint32_t status;
	uint32_t expected_status_bits;
	size_t payload_size;
	size_t bytes_to_go;
	const uint8_t *cmd_body = tpm2_command;
	uint8_t *rsp_body = tpm2_response;
	union fifo_transfer_buffer fifo_buffer;
	const int HEADER_SIZE = 6;
	struct tpm2_info *tpm_info = car_get_var_ptr(&g_tpm_info);

	/* Do not try using an uninitialized TPM. */
	if (!tpm_info->vendor_id)
		return 0;

	/* Skip the two byte tag, read the size field. */
	payload_size = read_be32(cmd_body + 2);

	/* Sanity check. */
	if (payload_size != command_size) {
		printk(BIOS_ERR,
		       "Command size mismatch: encoded %zd != requested %zd\n",
		       payload_size, command_size);
		trace_dump("W", TPM_DATA_FIFO_REG, command_size, cmd_body, 1);
		printk(BIOS_DEBUG, "\n");
		return 0;
	}

	/* Let the TPM know that the command is coming. */
	write_tpm_sts(TPM_STS_COMMAND_READY);

	/*
	 * TPM commands and responses written to and read from the FIFO
	 * register (0x24) are datagrams of variable size, prepended by a 6
	 * byte header.
	 *
	 * The specification description of the state machine is a bit vague,
	 * but from experience it looks like there is no need to wait for the
	 * sts.expect bit to be set, at least with the 9670 and cr50 devices.
	 * Just write the command into FIFO, making sure not to exceed the
	 * burst count or the maximum PDU size, whatever is smaller.
	 */
	fifo_buffer.tx_buffer = cmd_body;
	fifo_transfer(command_size, fifo_buffer, fifo_transmit);

	/* Now tell the TPM it can start processing the command. */
	write_tpm_sts(TPM_STS_GO);

	/* Now wait for it to report that the response is ready. */
	expected_status_bits = TPM_STS_VALID | TPM_STS_DATA_AVAIL;
	if (!wait_for_status(expected_status_bits, expected_status_bits)) {
		/*
		 * If timed out, which should never happen, let's at least
		 * print out the offending command.
		 */
		trace_dump("W", TPM_DATA_FIFO_REG, command_size, cmd_body, 1);
		printk(BIOS_DEBUG, "\n");
		return 0;
	}

	/*
	 * The response is ready, let's read it. First we read the FIFO
	 * payload header, to see how much data to expect. The response header
	 * size is fixed to six bytes, the total payload size is stored in
	 * network order in the last four bytes.
	 */
	tpm2_read_reg(TPM_DATA_FIFO_REG, rsp_body, HEADER_SIZE);

	/* Find out the total payload size, skipping the two byte tag. */
	payload_size = read_be32(rsp_body + 2);

	if (payload_size > max_response) {
		/*
		 * TODO(vbendeb): at least drain the FIFO here or somehow let
		 * the TPM know that the response can be dropped.
		 */
		printk(BIOS_ERR, " TPM response too long (%zd bytes)",
		       payload_size);
		return 0;
	}

	/*
	 * Now let's read all but the last byte in the FIFO to make sure the
	 * status register is showing correct flow control bits: 'more data'
	 * until the last byte and then 'no more data' once the last byte is
	 * read.
	 */
	bytes_to_go = payload_size - 1 - HEADER_SIZE;
	fifo_buffer.rx_buffer = rsp_body + HEADER_SIZE;
	fifo_transfer(bytes_to_go, fifo_buffer, fifo_receive);

	/* Verify that there is still data to read. */
	read_tpm_sts(&status);
	if ((status & expected_status_bits) != expected_status_bits) {
		printk(BIOS_ERR, "unexpected intermediate status %#x\n",
		       status);
		return 0;
	}

	/* Read the last byte of the PDU. */
	tpm2_read_reg(TPM_DATA_FIFO_REG, rsp_body + payload_size - 1, 1);

	/* Terminate the dump, if enabled. */
	if (debug_level_)
		printk(BIOS_DEBUG, "\n");

	/* Verify that 'data available' is not asseretd any more. */
	read_tpm_sts(&status);
	if ((status & expected_status_bits) != TPM_STS_VALID) {
		printk(BIOS_ERR, "unexpected final status %#x\n", status);
		return 0;
	}

	/* Move the TPM back to idle state. */
	write_tpm_sts(TPM_STS_COMMAND_READY);

	return payload_size;
}
Example #13
0
void
set_tracefile(const char *filename,
    const char *pat,
    int dump)			/* -1=no dump, 0=default, 1=force */
{
	struct stat stbuf;
	struct stat stbuf2;
	FILE *n_ftrace;
	const char *fn;
	int nfd;
	boolean_t allow_create;

	/*
	 * main() calls this routine with "dump == -1".  All others
	 * call it with 0, so we take dump == -1 to mean "can create
	 * the file."
	 */
	allow_create = (dump == -1);

	/*
	 * Allow a null filename to increase the level if the trace file
	 * is already open or if coming from a trusted source, such as
	 * a signal or the command line.
	 */
	if (filename == NULL || filename[0] == '\0') {
		filename = NULL;
		if (ftrace == NULL) {
			if (inittracename[0] == '\0') {
				msglog("missing trace file name");
				return;
			}
			fn = inittracename;
		} else {
			goto set_tracelevel;
		}

	} else if (strcmp(filename, "dump/../table") == 0) {
		trace_dump();
		return;

	} else {
		/*
		 * Allow the file specified with "-T file" to be reopened,
		 * but require all other names specified over the net to
		 * match the official path.  The path can specify a directory
		 * in which the file is to be created.
		 */

		if (strcmp(filename, inittracename) != 0) {
			if (strncmp(filename, PATH_TRACE,
			    sizeof (PATH_TRACE)-1) != 0 ||
			    (strstr(filename, "../") != NULL)) {
				msglog("wrong trace file \"%s\"", filename);
				return;
			}
			if (stat(PATH_TRACE, &stbuf) == -1) {
				fn = PATH_TRACE;
				goto missing_file;
			}
			if (filename[sizeof (PATH_TRACE) - 1] != '\0' &&
			    (filename[sizeof (PATH_TRACE) - 1] != '/' ||
			    !S_ISDIR(stbuf.st_mode))) {
				goto bad_file_type;
			}
			if (S_ISDIR(stbuf.st_mode))
				allow_create = _B_TRUE;
		}

		fn = filename;
	}
	/* fn cannot be null here */

	/* If the new tracefile exists, it must be a regular file. */
	if (lstat(fn, &stbuf) == -1) {
		if (!allow_create)
			goto missing_file;
		nfd = open(fn, O_CREAT|O_EXCL|O_WRONLY, 0644);
		if (nfd != -1 && fstat(nfd, &stbuf) == -1) {
			(void) close(nfd);
			goto missing_file;
		}
	} else if (S_ISREG(stbuf.st_mode)) {
		nfd = open(fn, O_APPEND|O_WRONLY, 0644);
	} else {
		goto bad_file_type;
	}

	if (nfd == -1 || (n_ftrace = fdopen(nfd, "a")) == NULL) {
		msglog("failed to open trace file \"%s\" %s", fn,
		    rip_strerror(errno));
		if (fn == inittracename)
			inittracename[0] = '\0';
		if (nfd != -1)
			(void) close(nfd);
		return;
	}

	if (fstat(nfd, &stbuf2) == -1 || !S_ISREG(stbuf2.st_mode) ||
	    stbuf2.st_dev != stbuf.st_dev || stbuf2.st_ino != stbuf.st_ino) {
		msglog("trace file \"%s\" moved", fn);
		(void) fclose(n_ftrace);
		return;
	}

	tmsg("switch to trace file %s", fn);
	trace_close(file_trace = _B_TRUE);
	(void) dup2(nfd, STDOUT_FILENO);
	(void) dup2(nfd, STDERR_FILENO);

	if (fn != savetracename)
		(void) strlcpy(savetracename, fn, sizeof (savetracename) - 1);
	ftrace = n_ftrace;

set_tracelevel:
	if (new_tracelevel == 0 || filename == NULL)
		new_tracelevel++;
	tracelevel_msg(pat, dump != 0 ? dump : (filename != NULL));
	return;

missing_file:
	msglog("trace \"%s\" missing", fn);
	return;

bad_file_type:
	msglog("wrong type (%#x) of trace file \"%s\"", stbuf.st_mode, fn);
}