control.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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. #include "trace/control.h"
  10. TraceEvent *trace_event_name(const char *name)
  11. {
  12. assert(name != NULL);
  13. TraceEventID i;
  14. for (i = 0; i < trace_event_count(); i++) {
  15. TraceEvent *ev = trace_event_id(i);
  16. if (strcmp(trace_event_get_name(ev), name) == 0) {
  17. return ev;
  18. }
  19. }
  20. return NULL;
  21. }
  22. static bool pattern_glob(const char *pat, const char *ev)
  23. {
  24. while (*pat != '\0' && *ev != '\0') {
  25. if (*pat == *ev) {
  26. pat++;
  27. ev++;
  28. }
  29. else if (*pat == '*') {
  30. if (pattern_glob(pat, ev+1)) {
  31. return true;
  32. } else if (pattern_glob(pat+1, ev)) {
  33. return true;
  34. } else {
  35. return false;
  36. }
  37. } else {
  38. return false;
  39. }
  40. }
  41. while (*pat == '*') {
  42. pat++;
  43. }
  44. if (*pat == '\0' && *ev == '\0') {
  45. return true;
  46. } else {
  47. return false;
  48. }
  49. }
  50. TraceEvent *trace_event_pattern(const char *pat, TraceEvent *ev)
  51. {
  52. assert(pat != NULL);
  53. TraceEventID i;
  54. if (ev == NULL) {
  55. i = -1;
  56. } else {
  57. i = trace_event_get_id(ev);
  58. }
  59. i++;
  60. while (i < trace_event_count()) {
  61. TraceEvent *res = trace_event_id(i);
  62. if (pattern_glob(pat, trace_event_get_name(res))) {
  63. return res;
  64. }
  65. i++;
  66. }
  67. return NULL;
  68. }
  69. void trace_backend_init_events(const char *fname)
  70. {
  71. if (fname == NULL) {
  72. return;
  73. }
  74. FILE *fp = fopen(fname, "r");
  75. if (!fp) {
  76. fprintf(stderr, "error: could not open trace events file '%s': %s\n",
  77. fname, strerror(errno));
  78. exit(1);
  79. }
  80. char line_buf[1024];
  81. while (fgets(line_buf, sizeof(line_buf), fp)) {
  82. size_t len = strlen(line_buf);
  83. if (len > 1) { /* skip empty lines */
  84. line_buf[len - 1] = '\0';
  85. if ('#' == line_buf[0]) { /* skip commented lines */
  86. continue;
  87. }
  88. const bool enable = ('-' != line_buf[0]);
  89. char *line_ptr = enable ? line_buf : line_buf + 1;
  90. if (trace_event_is_pattern(line_ptr)) {
  91. TraceEvent *ev = NULL;
  92. while ((ev = trace_event_pattern(line_ptr, ev)) != NULL) {
  93. if (trace_event_get_state_static(ev)) {
  94. trace_event_set_state_dynamic(ev, enable);
  95. }
  96. }
  97. } else {
  98. TraceEvent *ev = trace_event_name(line_ptr);
  99. if (ev == NULL) {
  100. fprintf(stderr,
  101. "error: trace event '%s' does not exist\n", line_ptr);
  102. exit(1);
  103. }
  104. if (!trace_event_get_state_static(ev)) {
  105. fprintf(stderr,
  106. "error: trace event '%s' is not traceable\n", line_ptr);
  107. exit(1);
  108. }
  109. trace_event_set_state_dynamic(ev, enable);
  110. }
  111. }
  112. }
  113. if (fclose(fp) != 0) {
  114. fprintf(stderr, "error: closing file '%s': %s\n",
  115. fname, strerror(errno));
  116. exit(1);
  117. }
  118. }