blob: 112173c19db716cdb7f8c7f84f9585a3f83d5506 [file] [log] [blame]
Robert Tarasovdf3962b2019-07-28 00:56:25 -07001
2/**************************************************************************
3 *
4 * Copyright 2011 Jose Fonseca
5 * Copyright 2010 VMware, Inc.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29#include <string.h>
30#include <limits.h> // for CHAR_MAX
31#include <getopt.h>
32#ifndef _WIN32
33#include <unistd.h> // for isatty()
34#endif
35
36#include <memory>
37#include <fstream>
38#include <string>
Robert Tarasovdf3962b2019-07-28 00:56:25 -070039
40#include "cxx_compat.hpp" // for std::to_string, std::make_unique
41
42#include "cli.hpp"
43#include "cli_pager.hpp"
44
45#include "trace_parser.hpp"
Robert Tarasovdf3962b2019-07-28 00:56:25 -070046#include "trace_option.hpp"
47
Robert Tarasov34921b22020-11-14 18:04:40 -080048static const char *synopsis = "Print given trace file(s) information.";
Robert Tarasovdf3962b2019-07-28 00:56:25 -070049
50static void
51usage(void)
52{
53 std::cout
54 << "usage: apitrace info [OPTIONS] TRACE_FILE...\n"
55 << synopsis << "\n"
56 "\n"
Robert Tarasovaaa95fc2020-01-30 14:26:37 +000057 " -h, --help show this help message and exit\n"
Robert Tarasov67634522020-06-24 16:17:48 -070058 " --dump-frames dump per frame information\n"
Robert Tarasovdf3962b2019-07-28 00:56:25 -070059 "\n"
60 ;
61}
62
63enum {
Robert Tarasov67634522020-06-24 16:17:48 -070064 DUMP_FRAMES_OPT = CHAR_MAX + 1,
Robert Tarasovdf3962b2019-07-28 00:56:25 -070065};
66
67const static char *
Robert Tarasovaaa95fc2020-01-30 14:26:37 +000068shortOptions = "h";
Robert Tarasovdf3962b2019-07-28 00:56:25 -070069
70const static struct option
71longOptions[] = {
72 {"help", no_argument, 0, 'h'},
Robert Tarasov67634522020-06-24 16:17:48 -070073 {"dump-frames", no_argument, 0, DUMP_FRAMES_OPT},
Robert Tarasovdf3962b2019-07-28 00:56:25 -070074 {0, 0, 0, 0}
75};
76
Robert Tarasovaaa95fc2020-01-30 14:26:37 +000077static const char*
78getApiName(int api) {
79 if (api < trace::API_UNKNOWN || api >= trace::API_MAX)
80 api = trace::API_UNKNOWN;
81 return trace::API_NAMES[api];
Robert Tarasovdf3962b2019-07-28 00:56:25 -070082}
83
Robert Tarasov67634522020-06-24 16:17:48 -070084struct FrameEntry {
85 size_t firstCallId, lastCallId;
86 size_t totalCalls;
87 size_t sizeInBytes;
88};
89
Robert Tarasovdf3962b2019-07-28 00:56:25 -070090static int
91command(int argc, char *argv[])
92{
Robert Tarasov67634522020-06-24 16:17:48 -070093 bool flagDumpFrames = false;
Robert Tarasovdf3962b2019-07-28 00:56:25 -070094 int opt;
95 while ((opt = getopt_long(argc, argv, shortOptions, longOptions, NULL)) != -1) {
96 switch (opt) {
97 case 'h':
98 usage();
99 return 0;
Robert Tarasov67634522020-06-24 16:17:48 -0700100 case DUMP_FRAMES_OPT:
101 flagDumpFrames = true;
Robert Tarasovdf3962b2019-07-28 00:56:25 -0700102 break;
103 default:
104 std::cerr << "error: unexpected option `" << (char)opt << "`\n";
105 usage();
106 return 1;
107 }
108 }
109
Robert Tarasov67634522020-06-24 16:17:48 -0700110 typedef std::vector<FrameEntry> FrameEntries;
111 FrameEntries frames;
112
Robert Tarasovdf3962b2019-07-28 00:56:25 -0700113 for (int i = optind; i < argc; ++i) {
Robert Tarasovaaa95fc2020-01-30 14:26:37 +0000114 unsigned long framesCount = 0;
115 trace::API api = trace::API_UNKNOWN;
Robert Tarasovdf3962b2019-07-28 00:56:25 -0700116 trace::Parser p;
117
Robert Tarasovaaa95fc2020-01-30 14:26:37 +0000118 if (!p.open(argv[i])) {
Robert Tarasovdf3962b2019-07-28 00:56:25 -0700119 return 1;
120 }
121
122 trace::Call *call;
Robert Tarasov67634522020-06-24 16:17:48 -0700123 size_t callsInFrame = 0;
124 size_t firstCallId = 0;
125 size_t frameBytesOffset = 0;
126 bool endFrame = true;
Robert Tarasovdf3962b2019-07-28 00:56:25 -0700127 while ((call = p.parse_call())) {
Robert Tarasov67634522020-06-24 16:17:48 -0700128 if (flagDumpFrames) {
129 ++callsInFrame;
130 if (endFrame) {
131 firstCallId = call->no;
132 endFrame = false;
133 }
134 }
Robert Tarasovaaa95fc2020-01-30 14:26:37 +0000135 if (api == trace::API_UNKNOWN && p.api != trace::API_UNKNOWN)
Robert Tarasov67634522020-06-24 16:17:48 -0700136 api = p.api;
137 if (call->flags & trace::CALL_FLAG_END_FRAME) {
138 ++framesCount;
139 if (flagDumpFrames) {
140 size_t curBytesOffset = p.dataBytesRead();
141 frames.push_back(
142 FrameEntry {
143 firstCallId,
144 call->no,
145 callsInFrame,
146 curBytesOffset-frameBytesOffset
147 }
148 );
149 frameBytesOffset = curBytesOffset;
150 endFrame = true;
151 callsInFrame = 0;
152 }
153 }
Robert Tarasovdf3962b2019-07-28 00:56:25 -0700154 delete call;
155 }
156
Robert Tarasov67634522020-06-24 16:17:48 -0700157 std::cout <<
158 "{" << std::endl <<
159 " \"FileName\": \"" << argv[i] << "\"," << std::endl <<
160 " \"ContainerVersion\": " << p.getVersion() << "," << std::endl <<
161 " \"ContainerType\": \"" << p.containerType() << "\"," << std::endl <<
162 " \"API\": \"" << getApiName(api) << "\"," << std::endl <<
163 " \"FramesCount\": " << framesCount << "," << std::endl <<
164 " \"ActualDataSize\": " << p.dataBytesRead() << "," << std::endl <<
165 " \"ContainerSize\": " << p.containerSizeInBytes();
166 if (flagDumpFrames) {
167 std::cout << "," << std::endl;
Robert Tarasovaaa95fc2020-01-30 14:26:37 +0000168 std::cout <<
Robert Tarasov67634522020-06-24 16:17:48 -0700169 " \"Frames\": [{" << std::endl;
170 for (auto it = frames.begin(); it != frames.end(); ++it) {
171 std::cout <<
172 " \"FirstCallId\": " << it->firstCallId << "," << std::endl <<
173 " \"LastCallId\": " << it->lastCallId << "," << std::endl <<
174 " \"TotalCalls\": " << it->totalCalls << "," << std::endl <<
175 " \"SizeInBytes\": " << it->sizeInBytes << std::endl;
176 if (it != std::prev(frames.end())) {
177 std::cout << " }, {" << std::endl;
178 }
179 }
180 std::cout << " }]" << std::endl;
Robert Tarasovdf3962b2019-07-28 00:56:25 -0700181 } else {
Robert Tarasov67634522020-06-24 16:17:48 -0700182 std::cout << std::endl;
Robert Tarasovdf3962b2019-07-28 00:56:25 -0700183 }
Robert Tarasov67634522020-06-24 16:17:48 -0700184 std::cout << "}" << std::endl;
Robert Tarasovdf3962b2019-07-28 00:56:25 -0700185 }
186
Robert Tarasovaaa95fc2020-01-30 14:26:37 +0000187 return 0;
Robert Tarasovdf3962b2019-07-28 00:56:25 -0700188}
189
190const Command info_command = {
191 "info",
192 synopsis,
193 usage,
194 command
195};