Skip to content
  • 4 commits
  • 7 files changed
  • 0 commit comments
  • 1 contributor
View
6 include/trace_parser.h
@@ -166,6 +166,9 @@ typedef struct trace_parser {
int always_hex;
int indent;
int relative_ts;
+ bool_t wait_for_input;
+ int inotify_fd;
+ int inotify_descriptor;
int show_field_names;
bool_t cancel_ongoing_operation;
struct trace_record_matcher_spec_s record_filter;
@@ -174,13 +177,14 @@ typedef struct trace_parser {
} trace_parser_t;
#define SEVERITY_FILTER_LEN (21)
-int TRACE_PARSER__from_file(trace_parser_t *parser, const char *filename, trace_parser_event_handler_t event_handler, void *arg);
+int TRACE_PARSER__from_file(trace_parser_t *parser, bool_t wait_for_input, const char *filename, trace_parser_event_handler_t event_handler, void *arg);
int TRACE_PARSER__process_previous_record_from_file(trace_parser_t *parser);
int TRACE_PARSER__process_next_record_from_file(trace_parser_t *parser);
void TRACE_PARSER__from_external_stream(trace_parser_t *parser, trace_parser_event_handler_t event_handler, void *arg);
void TRACE_PARSER__fini(trace_parser_t *parser);
void TRACE_PARSER__set_color(trace_parser_t *parser, int has_color);
void TRACE_PARSER__set_indent(trace_parser_t *parser, int indent);
+void TRACE_PARSER__set_wait_for_input(trace_parser_t *parser, int wait_for_input);
void TRACE_PARSER__set_verbose(trace_parser_t *parser, int verbose);
void TRACE_PARSER__set_show_field_names(trace_parser_t *parser, int show_field_names);
void TRACE_PARSER__set_relative_ts(trace_parser_t *parser, int relative_ts);
View
2 interactive_reader/_CTraceParser.py
@@ -389,7 +389,7 @@ def __init__(self, filename = None, event_handler = None):
self._event_handler = event_handler
if filename:
- _traces_so.TRACE_PARSER__from_file(byref(self._parser_handle), filename, self._handler, byref(c_int()))
+ _traces_so.TRACE_PARSER__from_file(byref(self._parser_handle), False, filename, self._handler, byref(c_int()))
self.end_offset = self._parser_handle.file_info.end_offset
else:
_traces_so.TRACE_PARSER__from_external_stream(byref(self._parser_handle), self._handler, byref(c_int()))
View
90 libtrace/trace_parser.c
@@ -16,6 +16,7 @@ Copyright 2012 Yotam Rubin <yotamrubin@gmail.com>
***/
#include <sys/types.h>
+#include <sys/inotify.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
@@ -69,21 +70,60 @@ CREATE_LIST_IMPLEMENTATION(RecordsAccumulatorList, struct trace_record_accumulat
#define F_MAGENTA_BOLD(x) parser->color ? _F_MAGENTA_BOLD(x) : x
#define ANSI_DEFAULTS(x) parser->color ? _ANSI_DEFAULTS(x) : x
+static int wait_for_data(trace_parser_t *parser)
+{
+ fd_set read_fdset;
+ struct inotify_event event;
+ while (TRUE) {
+ FD_ZERO(&read_fdset);
+ FD_SET(parser->inotify_fd, &read_fdset);
+
+ int rc = select(parser->inotify_fd + 1, &read_fdset, NULL, NULL, NULL);
+ if (-1 == rc) {
+ return -1;
+ }
+
+ rc = read(parser->inotify_fd, &event, sizeof(event));
+ if (rc != sizeof(event)) {
+ return -1;
+ }
+
+ if (event.mask & IN_MODIFY) {
+ return 0;
+ }
+ }
+}
+
+
+
static int read_next_record(trace_parser_t *parser, struct trace_record *record)
{
int rc;
- rc = cached_file__read(&parser->file_info.cached_file, record, sizeof(*record));
- if (rc == 0) {
- parser->buffer_dump_context.file_offset++;
- record->rec_type = TRACE_REC_TYPE_END_OF_FILE;
- record->ts = 0;
- return 0;
+
+ while (TRUE) {
+ rc = cached_file__read(&parser->file_info.cached_file, record, sizeof(*record));
+ if (rc == 0) {
+ if (parser->wait_for_input) {
+ rc = wait_for_data(parser);
+ if (0 != rc) {
+ return -1;
+ }
+
+ continue;
+ }
+
+ parser->buffer_dump_context.file_offset++;
+ record->rec_type = TRACE_REC_TYPE_END_OF_FILE;
+ record->ts = 0;
+ return 0;
+ }
+
+ break;
+ if (rc != sizeof(*record)) {
+ return -1;
+ }
}
- if (rc != sizeof(*record)) {
- return -1;
- }
-
return 0;
}
@@ -1700,16 +1740,42 @@ long long trace_end_offset(trace_parser_t *parser)
return end_offset;
}
-int TRACE_PARSER__from_file(trace_parser_t *parser, const char *filename, trace_parser_event_handler_t event_handler, void *arg)
+
+static int init_inotify(trace_parser_t *parser, const char *filename)
{
int rc;
+ rc = inotify_init();
+ if (-1 == rc) {
+ return -1;
+ }
+
+ parser->inotify_fd = rc;
+ rc = inotify_add_watch(parser->inotify_fd, filename, IN_MODIFY);
+ if (-1 == rc) {
+ return -1;
+ }
+ parser->inotify_descriptor = rc;
+ return 0;
+}
+
+int TRACE_PARSER__from_file(trace_parser_t *parser, bool_t wait_for_input, const char *filename, trace_parser_event_handler_t event_handler, void *arg)
+{
+ int rc;
trace_parser_init(parser, event_handler, arg, TRACE_INPUT_STREAM_TYPE_SEEKABLE_FILE);
+ printf("%d\n", wait_for_input);
+ if (wait_for_input) {
+ parser->wait_for_input = TRUE;
+ if (0 != init_inotify(parser, filename)) {
+ return -1;
+ }
+ }
+
rc = cached_file__open(&parser->file_info.cached_file, filename, O_RDONLY);
if (0 != rc) {
return -1;
}
-
+
struct trace_record file_header;
rc = read_file_header(parser, &file_header);
View
51 trace_dumper/trace_dumper.c
@@ -697,12 +697,12 @@ static int find_oldest_trace_file(struct trace_dumper_configuration_s *conf, cha
return 0;
}
-static long long total_records_in_logdir(struct trace_dumper_configuration_s *conf)
+static long long total_records_in_logdir(const char *logdir)
{
DIR *dir;
struct dirent *ent;
long long total_bytes = 0;
- dir = opendir(conf->logs_base);
+ dir = opendir(logdir);
if (dir == NULL) {
return -1;
@@ -719,7 +719,7 @@ static long long total_records_in_logdir(struct trace_dumper_configuration_s *co
continue;
}
char full_filename[0x100];
- snprintf(full_filename, sizeof(full_filename), "%s/%s", conf->logs_base, ent->d_name);
+ snprintf(full_filename, sizeof(full_filename), "%s/%s", logdir, ent->d_name);
long long file_size = get_file_size(full_filename);
if (file_size < 0) {
closedir(dir);
@@ -1088,34 +1088,34 @@ static void close_record_file(struct trace_dumper_configuration_s *conf)
static int rotate_trace_file_if_necessary(struct trace_dumper_configuration_s *conf)
{
+ int rc;
if (!conf->write_to_file || conf->fixed_output_filename) {
return 0;
}
-
+
+ while (TRUE) {
+ if (total_records_in_logdir(conf->logs_base) > conf->max_records_per_logdir) {
+ rc = delete_oldest_trace_file(conf);
+ if (0 != rc) {
+ return -1;
+ }
+ } else {
+ break;
+ }
+ }
+
if (conf->record_file.records_written < conf->max_records_per_file) {
return 0;
}
close_record_file(conf);
/* Reopen journal file */
-
- int rc = trace_open_file(conf, &conf->record_file, conf->logs_base);
+ rc = trace_open_file(conf, &conf->record_file, conf->logs_base);
if (0 != rc) {
ERROR("Unable to open trace file:", strerror(errno));
return -1;
}
- while (TRUE) {
- if (total_records_in_logdir(conf) > conf->max_records_per_logdir) {
- rc = delete_oldest_trace_file(conf);
- if (0 != rc) {
- return -1;
- }
- } else {
- break;
- }
- }
-
return 0;
}
@@ -1162,15 +1162,16 @@ static int dump_records(struct trace_dumper_configuration_s *conf)
{
int rc;
while (1) {
+ rc = rotate_trace_file_if_necessary(conf);
+ if (0 != rc) {
+ return -1;
+ }
+
rc = open_trace_file_if_necessary(conf);
if (rc != 0) {
return -1;
}
- rc = rotate_trace_file_if_necessary(conf);
- if (0 != rc) {
- return -1;
- }
rc = trace_flush_buffers(conf);
if (0 != rc) {
return -1;
@@ -1333,9 +1334,15 @@ static unsigned long long calculate_free_percentage(unsigned int percent, const
if (percent > 100 || percent == 0) {
return 0;
}
+
+ long long records_in_logdir = total_records_in_logdir(logdir);
+ if (-1 == records_in_logdir) {
+ records_in_logdir = 0;
+ }
- long long free_bytes = free_bytes_in_fs(logdir);
+ long long free_bytes = free_bytes_in_fs(logdir) + (records_in_logdir * sizeof(struct trace_record));
return (free_bytes / 100) * percent;
+
}
static unsigned long long parse_quota_specification(const char *quota_specification, const char *logdir)
View
9 trace_instrumentor/TraceCall.h
@@ -55,13 +55,16 @@ class TraceParam {
unsigned InlineTraceRepresentDiag;
unsigned MultipleReprCallsDiag;
-
+ unsigned EmptyLiteralStringDiag;
TraceParam(llvm::raw_ostream &out, DiagnosticsEngine &_Diags, ASTContext &_ast, Rewriter *rewriter, std::set<const Type *> &_referencedTypes, std::set<TraceCall *> &global_traces): Out(out), Diags(_Diags), ast(_ast), Rewrite(rewriter), referencedTypes(_referencedTypes), globalTraces(global_traces), type_name("0"), trace_call(NULL) {
clear();
InlineTraceRepresentDiag = Diags.getCustomDiagID(DiagnosticsEngine::Error,
"inline __repr__ may cause obscure compilation errors");
MultipleReprCallsDiag = Diags.getCustomDiagID(DiagnosticsEngine::Error,
"a __repr__ function may have only a single call to REPR() (showing last call to REPR)");
+ EmptyLiteralStringDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
+ "Empty literal string in trace has no effect");
+
}
bool fromType(QualType type, bool fill_unknown);
@@ -203,7 +206,7 @@ TraceParam(llvm::raw_ostream &out, DiagnosticsEngine &_Diags, ASTContext &_ast,
}
private:
- std::string getLiteralString(const CastExpr *expr);
+ std::string getLiteralString(const Expr *expr);
void referenceType(const Type *type);
bool parseHexBufParam(const Expr *expr);
bool parseStringParam(QualType type);
@@ -253,7 +256,7 @@ TraceCall(llvm::raw_ostream &out, DiagnosticsEngine &_Diags, ASTContext &_ast, R
enum trace_severity functionNameToTraceSeverity(std::string function_name);
bool parseTraceParams(CallExpr *S, std::vector<TraceParam> &args);
- std::string getLiteralString(const CastExpr *expr);
+ std::string getLiteralString(const Expr *expr);
void createTraceDeclaration(CallExpr *S, unsigned int severity, std::vector<TraceParam> &args);
bool prepareSingleTraceParam(const Expr *trace_param, TraceParam &parsed_trace_param);
void replaceExpr(const Expr *expr, std::string replacement);
View
22 trace_instrumentor/trace_instrumentor.cpp
@@ -433,7 +433,7 @@ std::string TraceCall::getTraceWriteExpression()
start_record << "{ " << param.type_name << " _s_ = (" << param.expression << ");";
start_record << "unsigned int rlen = _s_ ? __builtin_strlen(" << castTo(ast.getLangOptions(), "_s_", "const char *") << "): 0;";
- start_record << "while (rlen) { ";
+ start_record << "do { ";
start_record << "unsigned int copy_size = " << genMIN(rlen_str, buf_left_str) << ";";
start_record << "__builtin_memcpy(&((*typed_buf)[1]), _s_, copy_size);";
start_record << "(*typed_buf)[0] = copy_size;";
@@ -442,9 +442,9 @@ std::string TraceCall::getTraceWriteExpression()
start_record << "rlen -= copy_size;";
start_record << "(*buf_left) -= copy_size + 1;";
start_record << "_s_ += copy_size;";
- start_record << "if (rlen) {";
+ start_record << "if (rlen || buf_left == 0) {";
start_record << commitAndAllocateRecord(severity);
- start_record << "}}}";
+ start_record << "}} while (rlen); }";
}
if (param.trace_call) {
@@ -624,15 +624,14 @@ bool TraceParam::parseHexBufParam(const Expr *expr)
return true;
}
-std::string TraceParam::getLiteralString(const CastExpr *expr)
+std::string TraceParam::getLiteralString(const Expr *expr)
{
- const Expr *sub_expr = expr->getSubExpr();
std::string empty_string;
- if (!isa<StringLiteral>(sub_expr)) {
+ if (!isa<StringLiteral>(expr)) {
return empty_string;
}
- const StringLiteral *string_literal = dyn_cast<StringLiteral>(sub_expr);
+ const StringLiteral *string_literal = dyn_cast<StringLiteral>(expr);
return string_literal->getString();
}
@@ -667,13 +666,16 @@ bool TraceParam::parseStringParam(const Expr *expr)
return false;
}
- if (isa<CastExpr>(expr)) {
- const CastExpr *cast_expr = dyn_cast<CastExpr>(expr);
- std::string literalString = getLiteralString(cast_expr);
+ const Expr *stripped_expr = expr->IgnoreImpCasts();
+ if (isa<StringLiteral>(stripped_expr)) {
+ std::string literalString = getLiteralString(stripped_expr);
if (literalString.length() != 0) {
type_name = expr->getType().getCanonicalType().getAsString();
const_str = literalString;
return true;
+ } else {
+ Diags.Report(ast.getFullLoc(stripped_expr->getLocStart()), EmptyLiteralStringDiag) << stripped_expr->getSourceRange();
+ return false;
}
}
View
24 trace_reader/simple_trace_reader.c
@@ -45,6 +45,7 @@ static const char *usage =
" -t --time Dump all records beginning at timestamp (in nsecs) \n"
" -o --show-field-names Show field names for all trace records \n"
" -r --relative-timestamp Print timestamps relative to boot time \n"
+ " -i --tail Display last records and wait for more data \n"
" -g --grep [expression] Display records whose constant string matches the expression \n"
" -s --print-stats Print per-log occurrence count \n"
" -m --dump-metadata Dump metadata \n"
@@ -61,6 +62,7 @@ static const struct option longopts[] = {
{ "show-field-name", 0, 0, 'o'},
{ "relative-timestamp", required_argument, 0, 't'},
{ "grep", required_argument, 0, 'g'},
+ { "tail", 0, 0, 'i'},
{ 0, 0, 0, 0}
};
@@ -69,7 +71,7 @@ static void print_usage(void)
printf(usage, "simple_trace_reader");
}
-static const char shortopts[] = "g:moft:hdnesr";
+static const char shortopts[] = "ig:moft:hdnesr";
static int parse_command_line(struct trace_reader_conf *conf, int argc, char **argv)
{
@@ -99,6 +101,9 @@ static int parse_command_line(struct trace_reader_conf *conf, int argc, char **a
case 'r':
conf->relative_ts = 1;
break;
+ case 'i':
+ conf->tail = 1;
+ break;
case 't':
conf->from_time = strtoll(optarg, NULL, 10);
if (conf->from_time == LLONG_MIN || conf->from_time == LLONG_MAX) {
@@ -198,14 +203,21 @@ static int dump_all_files(struct trace_reader_conf *conf)
for (i = 0; i < FilenameList__element_count(&conf->files_to_process); i++) {
FilenameList__get_element(&conf->files_to_process, i, &filename);
-
- int rc = TRACE_PARSER__from_file(&parser, filename, read_event_handler, NULL);
+ int rc = TRACE_PARSER__from_file(&parser, conf->tail, filename, read_event_handler, NULL);
if (0 != rc) {
fprintf(stderr, "Error opening file %s\n", filename);
return -1;
}
-
set_parser_params(conf, &parser);
+
+
+ if (conf->tail) {
+ TRACE_PARSER__seek_to_time(&parser, LLONG_MAX, &error_occurred);
+ if (error_occurred) {
+ fprintf(stderr, "Error seeking to end of file %llu\n", conf->from_time);
+ }
+ }
+
if (conf->from_time) {
TRACE_PARSER__seek_to_time(&parser, conf->from_time, &error_occurred);
if (error_occurred) {
@@ -230,7 +242,7 @@ static int dump_statistics_for_all_files(struct trace_reader_conf *conf)
for (i = 0; i < FilenameList__element_count(&conf->files_to_process); i++) {
FilenameList__get_element(&conf->files_to_process, i, &filename);
- int rc = TRACE_PARSER__from_file(&parser, filename, read_event_handler, NULL);
+ int rc = TRACE_PARSER__from_file(&parser, FALSE, filename, read_event_handler, NULL);
set_parser_params(conf, &parser);
if (0 != rc) {
@@ -255,7 +267,7 @@ static int dump_metadata_for_files(struct trace_reader_conf *conf)
for (i = 0; i < FilenameList__element_count(&conf->files_to_process); i++) {
FilenameList__get_element(&conf->files_to_process, i, &filename);
- int rc = TRACE_PARSER__from_file(&parser, filename, read_event_handler, NULL);
+ int rc = TRACE_PARSER__from_file(&parser, FALSE, filename, read_event_handler, NULL);
set_parser_params(conf, &parser);
if (0 != rc) {

No commit comments for this range

Something went wrong with that request. Please try again.