From 3c70c05e1f330ed0034319252c3dcd565cf13d6b Mon Sep 17 00:00:00 2001 From: Ole Troan Date: Mon, 10 Aug 2020 16:25:21 +0200 Subject: stats: name and error index client memory leak Type: fix Change-Id: I6c9999b93d4f4ad4b8540a21e793c9a90e7c8ecf Signed-off-by: Ole Troan --- src/vpp-api/CMakeLists.txt | 5 +++ src/vpp-api/client/stat_client.c | 10 ++++- src/vpp-api/client/test.c | 89 ++++++++++++++++++++++++++++------------ 3 files changed, 77 insertions(+), 27 deletions(-) diff --git a/src/vpp-api/CMakeLists.txt b/src/vpp-api/CMakeLists.txt index 0f2510d513d..72cc1b29cfd 100644 --- a/src/vpp-api/CMakeLists.txt +++ b/src/vpp-api/CMakeLists.txt @@ -29,5 +29,10 @@ add_vpp_headers(vpp-api client/stat_client.h ) +add_vpp_executable(test_vppapiclient NO_INSTALL + SOURCES client/test.c + LINK_LIBRARIES vppinfra pthread vppapiclient +) + add_subdirectory(vapi) add_subdirectory(python) diff --git a/src/vpp-api/client/stat_client.c b/src/vpp-api/client/stat_client.c index 9c6ff33c2d1..3d1bffc2d5f 100644 --- a/src/vpp-api/client/stat_client.c +++ b/src/vpp-api/client/stat_client.c @@ -301,8 +301,16 @@ stat_segment_data_free (stat_segment_data_t * res) vec_free (res[i].combined_counter_vec[j]); vec_free (res[i].combined_counter_vec); break; + case STAT_DIR_TYPE_NAME_VECTOR: + for (j = 0; j < vec_len (res[i].name_vector); j++) + vec_free (res[i].name_vector[j]); + vec_free (res[i].name_vector); + break; + case STAT_DIR_TYPE_ERROR_INDEX: + vec_free (res[i].error_vector); + break; default: - ; + assert (0); } free (res[i].name); } diff --git a/src/vpp-api/client/test.c b/src/vpp-api/client/test.c index 308492d5f11..6e74761fe24 100644 --- a/src/vpp-api/client/test.c +++ b/src/vpp-api/client/test.c @@ -1,6 +1,6 @@ /* *------------------------------------------------------------------ - * test.c + * test.c -- VPP API/Stats tests * * Copyright (c) 2016 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,6 +18,7 @@ */ #include #include +#include #include #include #include @@ -25,18 +26,16 @@ #include #include -#include /* time_t, time (for timestamp in second) */ -#include /* ftime, timeb (for timestamp in millisecond) */ -#include /* gettimeofday, timeval (for timestamp in microsecond) */ #include #include #include #include - +#include #include #include #include "vppapiclient.h" +#include "stat_client.h" #define vl_typedefs /* define message structures */ #include @@ -65,7 +64,6 @@ volatile u16 result_msg_id; void wrap_vac_callback (unsigned char *data, int len) { - //printf("Callback %d\n", len); result_ready = 1; result_msg_id = ntohs(*((u16 *)data)); } @@ -97,16 +95,8 @@ test_messages (void) printf("Connect failed: %d\n", rv); exit(rv); } - struct timeb timer_msec; - long long int timestamp_msec_start; /* timestamp in millisecond. */ - if (!ftime(&timer_msec)) { - timestamp_msec_start = ((long long int) timer_msec.time) * 1000ll + - (long long int) timer_msec.millitm; - } - else { - timestamp_msec_start = -1; - } + double timestamp_start = unix_time_now_nsec() * 1e-6; /* * Test vpe_api_write and vpe_api_read to send and recv message for an @@ -136,23 +126,70 @@ test_messages (void) while (result_msg_id != VL_API_CONTROL_PING_REPLY); } - long long int timestamp_msec_end; /* timestamp in millisecond. */ - if (!ftime(&timer_msec)) { - timestamp_msec_end = ((long long int) timer_msec.time) * 1000ll + - (long long int) timer_msec.millitm; - } - else { - timestamp_msec_end = -1; - } - - printf("Took %lld msec, %lld msgs/msec \n", (timestamp_msec_end - timestamp_msec_start), - no_msgs/(timestamp_msec_end - timestamp_msec_start)); + double timestamp_end = unix_time_now_nsec() * 1e-6; + printf("\nTook %.2f msec, %.0f msgs/msec \n", (timestamp_end - timestamp_start), + no_msgs/(timestamp_end - timestamp_start)); printf("Exiting...\n"); vac_disconnect(); } +static void +test_stats (void) +{ + clib_mem_trace_enable_disable(1); + clib_mem_trace (1); + + int rv = stat_segment_connect (STAT_SEGMENT_SOCKET_FILE); + assert(rv == 0); + + u32 *dir; + int i, j, k; + stat_segment_data_t *res; + u8 **pattern = 0; + vec_add1(pattern, (u8 *)"/if/names"); + vec_add1(pattern, (u8 *)"/err"); + + dir = stat_segment_ls ((u8 **)pattern); + + res = stat_segment_dump (dir); + for (i = 0; i < vec_len (res); i++) { + switch (res[i].type) { + case STAT_DIR_TYPE_NAME_VECTOR: + if (res[i].name_vector == 0) + continue; + for (k = 0; k < vec_len (res[i].name_vector); k++) + if (res[i].name_vector[k]) + fformat (stdout, "[%d]: %s %s\n", k, res[i].name_vector[k], + res[i].name); + break; + case STAT_DIR_TYPE_ERROR_INDEX: + for (j = 0; j < vec_len (res[i].error_vector); j++) + fformat (stdout, "%llu %s\n", res[i].error_vector[j], + res[i].name); + break; + default: + assert(0); + } + } + stat_segment_data_free (res); + stat_segment_disconnect(); + + vec_free(pattern); + vec_free(dir); + + (void) clib_mem_trace_enable_disable (0); + u8 *leak_report = format (0, "%U", format_mheap, clib_mem_get_heap (), + 1 /* verbose, i.e. print leaks */ ); + printf("%s", leak_report); + vec_free (leak_report); + clib_mem_trace (0); +} + int main (int argc, char ** argv) { + clib_mem_init (0, 3ULL << 30); + test_stats(); + int i; for (i = 0; i < 1000; i++) { -- cgit 1.2.3-korg