1 /* 2 * Interface for configuring and controlling the state of tracing events. 3 * 4 * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu> 5 * 6 * This work is licensed under the terms of the GNU GPL, version 2 or later. 7 * See the COPYING file in the top-level directory. 8 */ 9 10 #include "trace/control.h" 11 12 13 TraceEvent *trace_event_name(const char *name) 14 { 15 assert(name != NULL); 16 17 TraceEventID i; 18 for (i = 0; i < trace_event_count(); i++) { 19 TraceEvent *ev = trace_event_id(i); 20 if (strcmp(trace_event_get_name(ev), name) == 0) { 21 return ev; 22 } 23 } 24 return NULL; 25 } 26 27 static bool pattern_glob(const char *pat, const char *ev) 28 { 29 while (*pat != '\0' && *ev != '\0') { 30 if (*pat == *ev) { 31 pat++; 32 ev++; 33 } 34 else if (*pat == '*') { 35 if (pattern_glob(pat, ev+1)) { 36 return true; 37 } else if (pattern_glob(pat+1, ev)) { 38 return true; 39 } else { 40 return false; 41 } 42 } else { 43 return false; 44 } 45 } 46 47 while (*pat == '*') { 48 pat++; 49 } 50 51 if (*pat == '\0' && *ev == '\0') { 52 return true; 53 } else { 54 return false; 55 } 56 } 57 58 TraceEvent *trace_event_pattern(const char *pat, TraceEvent *ev) 59 { 60 assert(pat != NULL); 61 62 TraceEventID i; 63 64 if (ev == NULL) { 65 i = -1; 66 } else { 67 i = trace_event_get_id(ev); 68 } 69 i++; 70 71 while (i < trace_event_count()) { 72 TraceEvent *res = trace_event_id(i); 73 if (pattern_glob(pat, trace_event_get_name(res))) { 74 return res; 75 } 76 i++; 77 } 78 79 return NULL; 80 } 81 82 void trace_backend_init_events(const char *fname) 83 { 84 if (fname == NULL) { 85 return; 86 } 87 88 FILE *fp = fopen(fname, "r"); 89 if (!fp) { 90 fprintf(stderr, "error: could not open trace events file '%s': %s\n", 91 fname, strerror(errno)); 92 exit(1); 93 } 94 char line_buf[1024]; 95 while (fgets(line_buf, sizeof(line_buf), fp)) { 96 size_t len = strlen(line_buf); 97 if (len > 1) { /* skip empty lines */ 98 line_buf[len - 1] = '\0'; 99 if ('#' == line_buf[0]) { /* skip commented lines */ 100 continue; 101 } 102 const bool enable = ('-' != line_buf[0]); 103 char *line_ptr = enable ? line_buf : line_buf + 1; 104 if (trace_event_is_pattern(line_ptr)) { 105 TraceEvent *ev = NULL; 106 while ((ev = trace_event_pattern(line_ptr, ev)) != NULL) { 107 if (trace_event_get_state_static(ev)) { 108 trace_event_set_state_dynamic(ev, enable); 109 } 110 } 111 } else { 112 TraceEvent *ev = trace_event_name(line_ptr); 113 if (ev == NULL) { 114 fprintf(stderr, 115 "error: trace event '%s' does not exist\n", line_ptr); 116 exit(1); 117 } 118 if (!trace_event_get_state_static(ev)) { 119 fprintf(stderr, 120 "error: trace event '%s' is not traceable\n", line_ptr); 121 exit(1); 122 } 123 trace_event_set_state_dynamic(ev, enable); 124 } 125 } 126 } 127 if (fclose(fp) != 0) { 128 fprintf(stderr, "error: closing file '%s': %s\n", 129 fname, strerror(errno)); 130 exit(1); 131 } 132 } 133