source: rtems-tools/trace/record/record-main-lttng.c @ f9dce02

5
Last change on this file since f9dce02 was f9dce02, checked in by Sebastian Huber <sebastian.huber@…>, on 01/14/19 at 12:28:31

record: New program

Update #3665.

  • Property mode set to 100644
File size: 4.8 KB
Line 
1/*
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (C) 2018, 2019 embedded brains GmbH
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <rtems/recorddata.h>
29#include <rtems/recordclient.h>
30
31#include <sys/queue.h>
32#include <sys/socket.h>
33
34#include <assert.h>
35#include <getopt.h>
36#include <stdbool.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <unistd.h>
41#include <inttypes.h>
42
43#include <netinet/in.h>
44#include <arpa/inet.h>
45
46static const struct option longopts[] = {
47  { "help", 0, NULL, 'h' },
48  { "host", 1, NULL, 'H' },
49  { "port", 1, NULL, 'p' },
50  { NULL, 0, NULL, 0 }
51};
52
53typedef struct client_item {
54  uint64_t           ns;
55  uint32_t           cpu;
56  rtems_record_event event;
57  uint64_t           data;
58} client_item;
59
60typedef struct client_context {
61  int dummy;
62} client_context;
63
64static void usage( char **argv )
65{
66  printf(
67    "%s [--host=HOST] [--port=PORT]\n"
68    "\n"
69    "Mandatory arguments to long options are mandatory for short options too.\n"
70    "  -h, --help                 print this help text\n"
71    "  -H, --host=HOST            the host IPv4 address of the record server\n"
72    "  -p, --port=PORT            the TCP port of the record server\n"
73    argv[ 0 ]
74  );
75}
76
77static int connect_client( const char *host, uint16_t port )
78{
79  struct sockaddr_in in_addr;
80  int fd;
81  int rv;
82
83  fd = socket( PF_INET, SOCK_STREAM, 0 );
84  assert( fd >= 0 );
85
86  memset( &in_addr, 0, sizeof( in_addr ) );
87  in_addr.sin_family = AF_INET;
88  in_addr.sin_port = htons( port );
89  in_addr.sin_addr.s_addr = inet_addr( host );
90  rv = connect( fd, (struct sockaddr *) &in_addr, sizeof( in_addr ) );
91  assert( rv == 0 );
92
93  return fd;
94}
95
96static void print_item( FILE *f, const client_item *item )
97{
98  if ( item->ns != 0 ) {
99    uint32_t seconds;
100    uint32_t nanoseconds;
101
102    seconds = (uint32_t) ( item->ns / 1000000000 );
103    nanoseconds = (uint32_t) ( item->ns % 1000000000 );
104    fprintf( f, "%" PRIu32 ".%09" PRIu32 ":", seconds, nanoseconds );
105  } else {
106    fprintf( f, "*:" );
107  }
108
109  fprintf(
110    f,
111    "%" PRIu32 ":%s:%" PRIx64 "\n",
112    item->cpu,
113    rtems_record_event_text( item->event ),
114    item->data
115  );
116}
117
118static rtems_record_client_status handler(
119  uint64_t            bt,
120  uint32_t            cpu,
121  rtems_record_event  event,
122  uint64_t            data,
123  void               *arg
124)
125{
126  client_context *cctx;
127  client_item     item;
128
129  cctx = arg;
130  (void) cctx;
131
132  item.ns = rtems_record_client_bintime_to_nanoseconds( bt );
133  item.cpu = cpu;
134  item.event = event;
135  item.data = data;
136
137  print_item( stdout, &item );
138
139  return RTEMS_RECORD_CLIENT_SUCCESS;
140}
141
142int main( int argc, char **argv )
143{
144  rtems_record_client_context ctx;
145  client_context cctx;
146  const char *host;
147  uint16_t port;
148  int fd;
149  int rv;
150  int opt;
151  int longindex;
152
153  host = "127.0.0.1";
154  port = 1234;
155
156  while (
157    ( opt = getopt_long( argc, argv, "hH:p:", &longopts[0], &longindex ) )
158      != -1
159  ) {
160    switch ( opt ) {
161      case 'h':
162        usage( argv );
163        exit( EXIT_SUCCESS );
164        break;
165      case 'H':
166        host = optarg;
167        break;
168      case 'p':
169        port = (uint16_t) strtoul( optarg, NULL, 10 );
170        break;
171      default:
172        exit( EXIT_FAILURE );
173        break;
174    }
175  }
176
177  memset( &cctx, 0, sizeof( cctx ) );
178
179  fd = connect_client( host, port );
180  rtems_record_client_init( &ctx, handler, &cctx );
181
182  while ( true ) {
183    int buf[ 8192 ];
184    ssize_t n;
185
186    n = recv( fd, buf, sizeof( buf ), 0 );
187    if ( n >= 0 ) {
188      rtems_record_client_run( &ctx, buf, (size_t) n );
189    } else {
190      break;
191    }
192  }
193
194  rv = close( fd );
195  assert( rv == 0 );
196
197  return 0;
198}
Note: See TracBrowser for help on using the repository browser.