LCOV - code coverage report
Current view: top level - spdk/app/trace - trace.cpp (source / functions) Hit Total Coverage
Test: Combined Lines: 104 282 36.9 %
Date: 2024-08-14 09:16:26 Functions: 10 20 50.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 69 310 22.3 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2016 Intel Corporation.
       3                 :            :  *   All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "spdk/stdinc.h"
       7                 :            : #include "spdk/env.h"
       8                 :            : #include "spdk/json.h"
       9                 :            : #include "spdk/likely.h"
      10                 :            : #include "spdk/string.h"
      11                 :            : #include "spdk/util.h"
      12                 :            : 
      13                 :            : #include <map>
      14                 :            : 
      15                 :            : extern "C" {
      16                 :            : #include "spdk/trace_parser.h"
      17                 :            : #include "spdk/util.h"
      18                 :            : }
      19                 :            : 
      20                 :            : enum print_format_type {
      21                 :            :         PRINT_FMT_JSON,
      22                 :            :         PRINT_FMT_DEFAULT,
      23                 :            : };
      24                 :            : 
      25                 :            : static struct spdk_trace_parser *g_parser;
      26                 :            : static const struct spdk_trace_file *g_file;
      27                 :            : static struct spdk_json_write_ctx *g_json;
      28                 :            : static bool g_print_tsc = false;
      29                 :            : 
      30                 :            : /* This is a bit ugly, but we don't want to include env_dpdk in the app, while spdk_util, which we
      31                 :            :  * do need, uses some of the functions implemented there.  We're not actually using the functions
      32                 :            :  * that depend on those, so just define them as no-ops to allow the app to link.
      33                 :            :  */
      34                 :            : extern "C" {
      35                 :            :         void *
      36                 :          0 :         spdk_realloc(void *buf, size_t size, size_t align)
      37                 :            :         {
      38                 :          0 :                 assert(false);
      39                 :            : 
      40                 :            :                 return NULL;
      41                 :            :         }
      42                 :            : 
      43                 :            :         void
      44                 :          0 :         spdk_free(void *buf)
      45                 :            :         {
      46                 :          0 :                 assert(false);
      47                 :            :         }
      48                 :            : 
      49                 :            :         uint64_t
      50                 :          0 :         spdk_get_ticks(void)
      51                 :            :         {
      52                 :          0 :                 return 0;
      53                 :            :         }
      54                 :            : } /* extern "C" */
      55                 :            : 
      56                 :            : static void usage(void);
      57                 :            : 
      58                 :            : static char *g_exe_name;
      59                 :            : 
      60                 :            : static float
      61                 :    1863326 : get_us_from_tsc(uint64_t tsc, uint64_t tsc_rate)
      62                 :            : {
      63                 :    1863326 :         return ((float)tsc) * 1000 * 1000 / tsc_rate;
      64                 :            : }
      65                 :            : 
      66                 :            : static const char *
      67                 :    1346758 : format_argname(const char *name)
      68                 :            : {
      69                 :            :         static char namebuf[16];
      70                 :            : 
      71         [ -  + ]:    1346758 :         snprintf(namebuf, sizeof(namebuf), "%s: ", name);
      72                 :    1346758 :         return namebuf;
      73                 :            : }
      74                 :            : 
      75                 :            : static void
      76                 :     265388 : print_ptr(const char *arg_string, uint64_t arg)
      77                 :            : {
      78         [ -  + ]:     265388 :         printf("%-7.7s0x%-14jx ", format_argname(arg_string), arg);
      79                 :     265388 : }
      80                 :            : 
      81                 :            : static void
      82                 :     429051 : print_uint64(const char *arg_string, uint64_t arg)
      83                 :            : {
      84                 :            :         /*
      85                 :            :          * Print arg as signed, since -1 is a common value especially
      86                 :            :          *  for FLUSH WRITEBUF when writev() returns -1 due to full
      87                 :            :          *  socket buffer.
      88                 :            :          */
      89         [ -  + ]:     429051 :         printf("%-7.7s%-16jd ", format_argname(arg_string), arg);
      90                 :     429051 : }
      91                 :            : 
      92                 :            : static void
      93                 :          0 : print_string(const char *arg_string, const char *arg)
      94                 :            : {
      95         [ #  # ]:          0 :         printf("%-7.7s%-16.16s ", format_argname(arg_string), arg);
      96                 :          0 : }
      97                 :            : 
      98                 :            : static void
      99                 :    1211007 : print_size(uint32_t size)
     100                 :            : {
     101         [ +  + ]:    1211007 :         if (size > 0) {
     102         [ -  + ]:     616542 :                 printf("size: %6u ", size);
     103                 :            :         } else {
     104         [ -  + ]:     594465 :                 printf("%13s", " ");
     105                 :            :         }
     106                 :    1211007 : }
     107                 :            : 
     108                 :            : static void
     109                 :     997694 : print_object_id(const struct spdk_trace_tpoint *d, struct spdk_trace_parser_entry *entry)
     110                 :            : {
     111                 :            :         /* Set size to 128 and 256 bytes to make sure we can fit all the characters we need */
     112                 :     997694 :         char related_id[128] = {'\0'};
     113                 :     997694 :         char ids[256] = {'\0'};
     114                 :            : 
     115         [ +  + ]:     997694 :         if (entry->related_type != OBJECT_NONE) {
     116                 :     507804 :                 snprintf(related_id, sizeof(related_id), " (%c%jd)",
     117         [ -  + ]:     253902 :                          g_file->object[entry->related_type].id_prefix,
     118                 :            :                          entry->related_index);
     119                 :            :         }
     120                 :            : 
     121         [ -  + ]:     997694 :         snprintf(ids, sizeof(ids), "%c%jd%s", g_file->object[d->object_type].id_prefix,
     122                 :            :                  entry->object_index, related_id);
     123   [ -  +  +  - ]:     997694 :         printf("id:    %-17s", ids);
     124                 :     997694 : }
     125                 :            : 
     126                 :            : static void
     127                 :     652319 : print_float(const char *arg_string, float arg)
     128                 :            : {
     129         [ -  + ]:     652319 :         printf("%-7s%-16.3f ", format_argname(arg_string), arg);
     130                 :     652319 : }
     131                 :            : 
     132                 :            : static void
     133                 :    1211007 : print_event(struct spdk_trace_parser_entry *entry, uint64_t tsc_rate, uint64_t tsc_offset)
     134                 :            : {
     135                 :    1211007 :         struct spdk_trace_entry         *e = entry->entry;
     136                 :            :         struct spdk_trace_owner         *owner;
     137                 :            :         const struct spdk_trace_tpoint  *d;
     138                 :            :         float                           us;
     139                 :            :         size_t                          i;
     140                 :            : 
     141                 :    1211007 :         d = &g_file->tpoint[e->tpoint_id];
     142                 :    1211007 :         us = get_us_from_tsc(e->tsc - tsc_offset, tsc_rate);
     143                 :            : 
     144         [ -  + ]:    1211007 :         printf("%-*s ", (int)sizeof(g_file->tname[entry->lcore]), g_file->tname[entry->lcore]);
     145         [ -  + ]:    1211007 :         printf("%2d: %10.3f ", entry->lcore, us);
     146   [ -  +  -  + ]:    1211007 :         if (g_print_tsc) {
     147         [ #  # ]:          0 :                 printf("(%9ju) ", e->tsc - tsc_offset);
     148                 :            :         }
     149                 :    1211007 :         owner = spdk_get_trace_owner(g_file, e->owner_id);
     150                 :            :         /* For now, only try to print first 64 bytes of description. */
     151   [ +  +  +  - ]:    1211007 :         if (e->owner_id > 0 && owner->tsc < e->tsc) {
     152         [ -  + ]:     937631 :                 printf("%-*s ", 64, owner->description);
     153                 :            :         } else {
     154         [ -  + ]:     273376 :                 printf("%-*s ", 64, "");
     155                 :            :         }
     156                 :            : 
     157         [ -  + ]:    1211007 :         printf("%-*s ", (int)sizeof(d->name), d->name);
     158                 :    1211007 :         print_size(e->size);
     159                 :            : 
     160         [ +  + ]:    1211007 :         if (d->new_object) {
     161                 :     345375 :                 print_object_id(d, entry);
     162         [ +  + ]:     865632 :         } else if (d->object_type != OBJECT_NONE) {
     163         [ +  - ]:     652319 :                 if (entry->object_index != UINT64_MAX) {
     164                 :     652319 :                         us = get_us_from_tsc(e->tsc - entry->object_start, tsc_rate);
     165                 :     652319 :                         print_object_id(d, entry);
     166                 :     652319 :                         print_float("time", us);
     167                 :            :                 } else {
     168         [ #  # ]:          0 :                         printf("id:    %-17s", "N/A");
     169                 :            :                 }
     170         [ +  + ]:     213313 :         } else if (e->object_id != 0) {
     171                 :       2154 :                 print_ptr("object", e->object_id);
     172                 :            :         }
     173                 :            : 
     174         [ +  + ]:    2157194 :         for (i = 0; i < d->num_args; ++i) {
     175   [ -  +  +  + ]:     946187 :                 if (entry->args[i].is_related) {
     176                 :            :                         /* This argument was already implicitly shown by its
     177                 :            :                          * associated related object ID.
     178                 :            :                          */
     179                 :     253902 :                         continue;
     180                 :            :                 }
     181   [ +  +  -  - ]:     692285 :                 switch (d->args[i].type) {
     182                 :     263234 :                 case SPDK_TRACE_ARG_TYPE_PTR:
     183                 :     263234 :                         print_ptr(d->args[i].name, (uint64_t)entry->args[i].u.pointer);
     184                 :     263234 :                         break;
     185                 :     429051 :                 case SPDK_TRACE_ARG_TYPE_INT:
     186                 :     429051 :                         print_uint64(d->args[i].name, entry->args[i].u.integer);
     187                 :     429051 :                         break;
     188                 :          0 :                 case SPDK_TRACE_ARG_TYPE_STR:
     189                 :          0 :                         print_string(d->args[i].name, entry->args[i].u.string);
     190                 :          0 :                         break;
     191                 :            :                 }
     192                 :            :         }
     193                 :    1211007 :         printf("\n");
     194                 :    1211007 : }
     195                 :            : 
     196                 :            : static void
     197                 :          0 : print_event_json(struct spdk_trace_parser_entry *entry, uint64_t tsc_rate, uint64_t tsc_offset)
     198                 :            : {
     199                 :          0 :         struct spdk_trace_entry *e = entry->entry;
     200                 :            :         const struct spdk_trace_tpoint *d;
     201                 :            :         size_t i;
     202                 :            : 
     203                 :          0 :         d = &g_file->tpoint[e->tpoint_id];
     204                 :            : 
     205                 :          0 :         spdk_json_write_object_begin(g_json);
     206                 :          0 :         spdk_json_write_named_uint64(g_json, "lcore", entry->lcore);
     207                 :          0 :         spdk_json_write_named_uint64(g_json, "tpoint", e->tpoint_id);
     208                 :          0 :         spdk_json_write_named_uint64(g_json, "tsc", e->tsc);
     209                 :            : 
     210         [ #  # ]:          0 :         if (g_file->owner_type[d->owner_type].id_prefix) {
     211                 :          0 :                 spdk_json_write_named_string_fmt(g_json, "poller", "%c%02d",
     212                 :          0 :                                                  g_file->owner_type[d->owner_type].id_prefix,
     213                 :          0 :                                                  e->owner_id);
     214                 :            :         }
     215         [ #  # ]:          0 :         if (e->size != 0) {
     216                 :          0 :                 spdk_json_write_named_uint32(g_json, "size", e->size);
     217                 :            :         }
     218   [ #  #  #  #  :          0 :         if (d->new_object || d->object_type != OBJECT_NONE || e->object_id != 0) {
                   #  # ]
     219                 :            :                 char object_type;
     220                 :            : 
     221                 :          0 :                 spdk_json_write_named_object_begin(g_json, "object");
     222         [ #  # ]:          0 :                 if (d->new_object) {
     223                 :          0 :                         object_type =  g_file->object[d->object_type].id_prefix;
     224                 :          0 :                         spdk_json_write_named_string_fmt(g_json, "id", "%c%" PRIu64, object_type,
     225                 :            :                                                          entry->object_index);
     226         [ #  # ]:          0 :                 } else if (d->object_type != OBJECT_NONE) {
     227                 :          0 :                         object_type =  g_file->object[d->object_type].id_prefix;
     228         [ #  # ]:          0 :                         if (entry->object_index != UINT64_MAX) {
     229                 :          0 :                                 spdk_json_write_named_string_fmt(g_json, "id", "%c%" PRIu64,
     230                 :            :                                                                  object_type,
     231                 :            :                                                                  entry->object_index);
     232                 :          0 :                                 spdk_json_write_named_uint64(g_json, "time",
     233                 :          0 :                                                              e->tsc - entry->object_start);
     234                 :            :                         }
     235                 :            :                 }
     236                 :          0 :                 spdk_json_write_named_uint64(g_json, "value", e->object_id);
     237                 :          0 :                 spdk_json_write_object_end(g_json);
     238                 :            :         }
     239                 :            : 
     240                 :            :         /* Print related objects array */
     241         [ #  # ]:          0 :         if (entry->related_index != UINT64_MAX) {
     242                 :          0 :                 spdk_json_write_named_string_fmt(g_json, "related", "%c%" PRIu64,
     243                 :          0 :                                                  g_file->object[entry->related_type].id_prefix,
     244                 :            :                                                  entry->related_index);
     245                 :            :         }
     246                 :            : 
     247         [ #  # ]:          0 :         if (d->num_args > 0) {
     248                 :          0 :                 spdk_json_write_named_array_begin(g_json, "args");
     249         [ #  # ]:          0 :                 for (i = 0; i < d->num_args; ++i) {
     250   [ #  #  #  # ]:          0 :                         switch (d->args[i].type) {
     251                 :          0 :                         case SPDK_TRACE_ARG_TYPE_PTR:
     252                 :          0 :                                 spdk_json_write_uint64(g_json, (uint64_t)entry->args[i].u.pointer);
     253                 :          0 :                                 break;
     254                 :          0 :                         case SPDK_TRACE_ARG_TYPE_INT:
     255                 :          0 :                                 spdk_json_write_uint64(g_json, entry->args[i].u.integer);
     256                 :          0 :                                 break;
     257                 :          0 :                         case SPDK_TRACE_ARG_TYPE_STR:
     258                 :          0 :                                 spdk_json_write_string(g_json, entry->args[i].u.string);
     259                 :          0 :                                 break;
     260                 :            :                         }
     261                 :            :                 }
     262                 :          0 :                 spdk_json_write_array_end(g_json);
     263                 :            :         }
     264                 :            : 
     265                 :          0 :         spdk_json_write_object_end(g_json);
     266                 :          0 : }
     267                 :            : 
     268                 :            : static void
     269                 :          0 : print_tpoint_definitions(void)
     270                 :            : {
     271                 :            :         const struct spdk_trace_tpoint *tpoint;
     272                 :            :         size_t i, j;
     273                 :            : 
     274                 :            :         /* We only care about these when printing JSON */
     275         [ #  # ]:          0 :         if (!g_json) {
     276                 :          0 :                 return;
     277                 :            :         }
     278                 :            : 
     279                 :          0 :         spdk_json_write_named_uint64(g_json, "tsc_rate", g_file->tsc_rate);
     280                 :          0 :         spdk_json_write_named_array_begin(g_json, "tpoints");
     281                 :            : 
     282         [ #  # ]:          0 :         for (i = 0; i < SPDK_COUNTOF(g_file->tpoint); ++i) {
     283                 :          0 :                 tpoint = &g_file->tpoint[i];
     284         [ #  # ]:          0 :                 if (tpoint->tpoint_id == 0) {
     285                 :          0 :                         continue;
     286                 :            :                 }
     287                 :            : 
     288                 :          0 :                 spdk_json_write_object_begin(g_json);
     289                 :          0 :                 spdk_json_write_named_string(g_json, "name", tpoint->name);
     290                 :          0 :                 spdk_json_write_named_uint32(g_json, "id", tpoint->tpoint_id);
     291                 :          0 :                 spdk_json_write_named_bool(g_json, "new_object", tpoint->new_object);
     292                 :            : 
     293                 :          0 :                 spdk_json_write_named_array_begin(g_json, "args");
     294         [ #  # ]:          0 :                 for (j = 0; j < tpoint->num_args; ++j) {
     295                 :          0 :                         spdk_json_write_object_begin(g_json);
     296                 :          0 :                         spdk_json_write_named_string(g_json, "name", tpoint->args[j].name);
     297                 :          0 :                         spdk_json_write_named_uint32(g_json, "type", tpoint->args[j].type);
     298                 :          0 :                         spdk_json_write_named_uint32(g_json, "size", tpoint->args[j].size);
     299                 :          0 :                         spdk_json_write_object_end(g_json);
     300                 :            :                 }
     301                 :          0 :                 spdk_json_write_array_end(g_json);
     302                 :          0 :                 spdk_json_write_object_end(g_json);
     303                 :            :         }
     304                 :            : 
     305                 :          0 :         spdk_json_write_array_end(g_json);
     306                 :            : }
     307                 :            : 
     308                 :            : static int
     309                 :          0 : print_json(void *cb_ctx, const void *data, size_t size)
     310                 :            : {
     311                 :            :         ssize_t rc;
     312                 :            : 
     313         [ #  # ]:          0 :         while (size > 0) {
     314                 :          0 :                 rc = write(STDOUT_FILENO, data, size);
     315         [ #  # ]:          0 :                 if (rc < 0) {
     316         [ #  # ]:          0 :                         fprintf(stderr, "%s: %s\n", g_exe_name, spdk_strerror(errno));
     317                 :          0 :                         abort();
     318                 :            :                 }
     319                 :            : 
     320                 :          0 :                 size -= rc;
     321                 :            :         }
     322                 :            : 
     323                 :          0 :         return 0;
     324                 :            : }
     325                 :            : 
     326                 :            : static int
     327                 :          2 : trace_print(int lcore)
     328                 :            : {
     329                 :          0 :         struct spdk_trace_parser_entry  entry;
     330                 :            :         int             i;
     331                 :            :         uint64_t        tsc_offset, entry_count;
     332                 :          2 :         uint64_t        tsc_rate = g_file->tsc_rate;
     333                 :            : 
     334   [ -  +  +  - ]:          2 :         printf("TSC Rate: %ju\n", tsc_rate);
     335         [ +  + ]:       2050 :         for (i = 0; i < SPDK_TRACE_MAX_LCORE; ++i) {
     336   [ -  +  -  - ]:       2048 :                 if (lcore == SPDK_TRACE_MAX_LCORE || i == lcore) {
     337         [ +  - ]:       2048 :                         entry_count = spdk_trace_parser_get_entry_count(g_parser, i);
     338         [ +  + ]:       2048 :                         if (entry_count > 0) {
     339   [ -  +  +  - ]:          8 :                                 printf("Trace Size of lcore (%d): %ju\n", i, entry_count);
     340                 :            :                         }
     341                 :            :                 }
     342                 :            :         }
     343                 :            : 
     344         [ +  - ]:          2 :         tsc_offset = spdk_trace_parser_get_tsc_offset(g_parser);
     345   [ +  -  +  + ]:    1211015 :         while (spdk_trace_parser_next_entry(g_parser, &entry)) {
     346         [ +  + ]:    1211013 :                 if (entry.entry->tsc < tsc_offset) {
     347                 :          6 :                         continue;
     348                 :            :                 }
     349         [ +  - ]:    1211007 :                 print_event(&entry, tsc_rate, tsc_offset);
     350                 :            :         }
     351                 :            : 
     352                 :          2 :         return 0;
     353                 :            : }
     354                 :            : 
     355                 :            : static int
     356                 :          0 : trace_print_json(void)
     357                 :            : {
     358                 :          0 :         struct spdk_trace_parser_entry  entry;
     359                 :            :         uint64_t        tsc_offset;
     360                 :          0 :         uint64_t        tsc_rate = g_file->tsc_rate;
     361                 :            : 
     362         [ #  # ]:          0 :         g_json = spdk_json_write_begin(print_json, NULL, 0);
     363         [ #  # ]:          0 :         if (g_json == NULL) {
     364   [ #  #  #  #  :          0 :                 fprintf(stderr, "Failed to allocate JSON write context\n");
                   #  # ]
     365                 :          0 :                 return -1;
     366                 :            :         }
     367                 :            : 
     368         [ #  # ]:          0 :         spdk_json_write_object_begin(g_json);
     369         [ #  # ]:          0 :         print_tpoint_definitions();
     370         [ #  # ]:          0 :         spdk_json_write_named_array_begin(g_json, "entries");
     371                 :            : 
     372         [ #  # ]:          0 :         tsc_offset = spdk_trace_parser_get_tsc_offset(g_parser);
     373   [ #  #  #  # ]:          0 :         while (spdk_trace_parser_next_entry(g_parser, &entry)) {
     374         [ #  # ]:          0 :                 if (entry.entry->tsc < tsc_offset) {
     375                 :          0 :                         continue;
     376                 :            :                 }
     377         [ #  # ]:          0 :                 print_event_json(&entry, tsc_rate, tsc_offset);
     378                 :            :         }
     379                 :            : 
     380         [ #  # ]:          0 :         spdk_json_write_array_end(g_json);
     381         [ #  # ]:          0 :         spdk_json_write_object_end(g_json);
     382         [ #  # ]:          0 :         spdk_json_write_end(g_json);
     383                 :            : 
     384                 :          0 :         return 0;
     385                 :            : }
     386                 :            : 
     387                 :            : static void
     388                 :          0 : usage(void)
     389                 :            : {
     390   [ #  #  #  # ]:          0 :         fprintf(stderr, "usage:\n");
     391   [ #  #  #  # ]:          0 :         fprintf(stderr, "   %s <option> <lcore#>\n", g_exe_name);
     392   [ #  #  #  # ]:          0 :         fprintf(stderr, "                 '-c' to display single lcore history\n");
     393   [ #  #  #  # ]:          0 :         fprintf(stderr, "                 '-t' to display TSC offset for each event\n");
     394   [ #  #  #  # ]:          0 :         fprintf(stderr, "                 '-s' to specify spdk_trace shm name for a\n");
     395   [ #  #  #  # ]:          0 :         fprintf(stderr, "                      currently running process\n");
     396   [ #  #  #  # ]:          0 :         fprintf(stderr, "                 '-i' to specify the shared memory ID\n");
     397   [ #  #  #  # ]:          0 :         fprintf(stderr, "                 '-p' to specify the trace PID\n");
     398   [ #  #  #  # ]:          0 :         fprintf(stderr, "                      (If -s is specified, then one of\n");
     399   [ #  #  #  # ]:          0 :         fprintf(stderr, "                       -i or -p must be specified)\n");
     400   [ #  #  #  # ]:          0 :         fprintf(stderr, "                 '-f' to specify a tracepoint file name\n");
     401   [ #  #  #  # ]:          0 :         fprintf(stderr, "                      (-s and -f are mutually exclusive)\n");
     402                 :            : #if defined(__linux__)
     403   [ #  #  #  # ]:          0 :         fprintf(stderr, "                 Without -s or -f, %s will look for\n", g_exe_name);
     404   [ #  #  #  # ]:          0 :         fprintf(stderr, "                      newest trace file in /dev/shm\n");
     405                 :            : #endif
     406   [ #  #  #  # ]:          0 :         fprintf(stderr, "                 '-j' to use JSON to format the output\n");
     407                 :          0 : }
     408                 :            : 
     409                 :            : #if defined(__linux__)
     410                 :            : static time_t g_mtime = 0;
     411                 :            : static char g_newest_file[PATH_MAX] = {};
     412                 :            : 
     413                 :            : static int
     414                 :          0 : get_newest(const char *path, const struct stat *sb, int tflag, struct FTW *ftw)
     415                 :            : {
     416   [ #  #  #  # ]:          0 :         if (tflag == FTW_F && sb->st_mtime > g_mtime &&
     417   [ #  #  #  # ]:          0 :             strstr(path, SPDK_TRACE_SHM_NAME_BASE) != NULL) {
     418                 :          0 :                 g_mtime = sb->st_mtime;
     419         [ #  # ]:          0 :                 strncpy(g_newest_file, path, PATH_MAX - 1);
     420                 :            :         }
     421                 :          0 :         return 0;
     422                 :            : }
     423                 :            : #endif
     424                 :            : 
     425                 :            : int
     426                 :          2 : main(int argc, char **argv)
     427                 :            : {
     428                 :          0 :         struct spdk_trace_parser_opts   opts;
     429                 :          2 :         enum print_format_type  print_format = PRINT_FMT_DEFAULT;
     430                 :          2 :         int                             lcore = SPDK_TRACE_MAX_LCORE;
     431                 :          2 :         const char                      *app_name = NULL;
     432                 :          2 :         const char                      *file_name = NULL;
     433                 :            :         int                             op;
     434                 :          2 :         int                             rc = 0;
     435                 :          0 :         char                            shm_name[64];
     436                 :          2 :         int                             shm_id = -1, shm_pid = -1;
     437                 :            : 
     438                 :          2 :         g_exe_name = argv[0];
     439   [ -  +  +  + ]:          4 :         while ((op = getopt(argc, argv, "c:f:i:jp:s:t")) != -1) {
     440   [ -  -  -  -  :          2 :                 switch (op) {
             +  -  -  - ]
     441                 :          0 :                 case 'c':
     442         [ #  # ]:          0 :                         lcore = atoi(optarg);
     443         [ #  # ]:          0 :                         if (lcore > SPDK_TRACE_MAX_LCORE) {
     444   [ #  #  #  # ]:          0 :                                 fprintf(stderr, "Selected lcore: %d "
     445                 :            :                                         "exceeds maximum %d\n", lcore,
     446                 :            :                                         SPDK_TRACE_MAX_LCORE);
     447                 :          0 :                                 exit(1);
     448                 :            :                         }
     449                 :          0 :                         break;
     450                 :          0 :                 case 'i':
     451         [ #  # ]:          0 :                         shm_id = atoi(optarg);
     452                 :          0 :                         break;
     453                 :          0 :                 case 'p':
     454         [ #  # ]:          0 :                         shm_pid = atoi(optarg);
     455                 :          0 :                         break;
     456                 :          0 :                 case 's':
     457                 :          0 :                         app_name = optarg;
     458                 :          0 :                         break;
     459                 :          2 :                 case 'f':
     460                 :          2 :                         file_name = optarg;
     461                 :          2 :                         break;
     462                 :          0 :                 case 't':
     463                 :          0 :                         g_print_tsc = true;
     464                 :          0 :                         break;
     465                 :          0 :                 case 'j':
     466                 :          0 :                         print_format = PRINT_FMT_JSON;
     467                 :          0 :                         break;
     468                 :          0 :                 default:
     469         [ #  # ]:          0 :                         usage();
     470                 :          0 :                         exit(1);
     471                 :            :                 }
     472                 :            :         }
     473                 :            : 
     474   [ +  -  -  + ]:          2 :         if (file_name != NULL && app_name != NULL) {
     475   [ #  #  #  # ]:          0 :                 fprintf(stderr, "-f and -s are mutually exclusive\n");
     476         [ #  # ]:          0 :                 usage();
     477                 :          0 :                 exit(1);
     478                 :            :         }
     479                 :            : 
     480   [ -  +  -  - ]:          2 :         if (file_name == NULL && app_name == NULL) {
     481                 :            : #if defined(__linux__)
     482         [ #  # ]:          0 :                 nftw("/dev/shm", get_newest, 1, 0);
     483         [ #  # ]:          0 :                 if (strlen(g_newest_file) > 0) {
     484                 :          0 :                         file_name = g_newest_file;
     485         [ #  # ]:          0 :                         printf("Using newest trace file found: %s\n", file_name);
     486                 :            :                 } else {
     487   [ #  #  #  # ]:          0 :                         fprintf(stderr, "No shm file found and -f not specified\n");
     488         [ #  # ]:          0 :                         usage();
     489                 :          0 :                         exit(1);
     490                 :            :                 }
     491                 :            : #else
     492                 :            :                 fprintf(stderr, "One of -f and -s must be specified\n");
     493                 :            :                 usage();
     494                 :            :                 exit(1);
     495                 :            : #endif
     496                 :            :         }
     497                 :            : 
     498         [ -  + ]:          2 :         if (!file_name) {
     499         [ #  # ]:          0 :                 if (shm_id >= 0) {
     500                 :          0 :                         snprintf(shm_name, sizeof(shm_name), "/%s_trace.%d", app_name, shm_id);
     501                 :            :                 } else {
     502                 :          0 :                         snprintf(shm_name, sizeof(shm_name), "/%s_trace.pid%d", app_name, shm_pid);
     503                 :            :                 }
     504                 :          0 :                 file_name = shm_name;
     505                 :            :         }
     506                 :            : 
     507                 :          2 :         opts.filename = file_name;
     508                 :          2 :         opts.lcore = lcore;
     509                 :          2 :         opts.mode = app_name == NULL ? SPDK_TRACE_PARSER_MODE_FILE : SPDK_TRACE_PARSER_MODE_SHM;
     510         [ +  - ]:          2 :         g_parser = spdk_trace_parser_init(&opts);
     511         [ -  + ]:          2 :         if (g_parser == NULL) {
     512   [ #  #  #  # ]:          0 :                 fprintf(stderr, "Failed to initialize trace parser\n");
     513                 :          0 :                 exit(1);
     514                 :            :         }
     515                 :            : 
     516         [ +  - ]:          2 :         g_file = spdk_trace_parser_get_file(g_parser);
     517         [ -  + ]:          2 :         switch (print_format) {
     518                 :          0 :         case PRINT_FMT_JSON:
     519         [ #  # ]:          0 :                 rc = trace_print_json();
     520                 :          0 :                 break;
     521                 :          2 :         case PRINT_FMT_DEFAULT:
     522                 :            :         default:
     523         [ +  - ]:          2 :                 rc = trace_print(lcore);
     524                 :          2 :                 break;
     525                 :            :         }
     526                 :            : 
     527         [ +  - ]:          2 :         spdk_trace_parser_cleanup(g_parser);
     528                 :            : 
     529                 :          2 :         return rc;
     530                 :            : }

Generated by: LCOV version 1.14