Add a debug-CLI leak-checker
leak-check { <any-debug-cli-command-and-args> } Hint: "set term history off" or you'll have to sort through a bunch of bogus leaks related to the debug cli history mechanism. Cleaned up a set of reported leaks in the "show interface" command. At some point, we thought about making a per-thread vlib_mains vector, but we never did that. Several interface-related CLI's maintained local static cache vectors. Not a bad idea, but not useful as things shook out. Removed the static vectors. Change-Id: I756bf2721a0d91993ecfded34c79da406f30a548 Signed-off-by: Dave Barach <dave@barachs.net>
This commit is contained in:
Dave Barach
committed by
Dave Wallace
parent
ce5c2ce518
commit
8fdde3c22f
@ -552,6 +552,31 @@ vlib_cli_dispatch_sub_commands (vlib_main_t * vm,
|
||||
parent_command_index);
|
||||
unformat_free (&sub_input);
|
||||
}
|
||||
else if (unformat (input, "leak-check %U",
|
||||
unformat_vlib_cli_sub_input, &sub_input))
|
||||
{
|
||||
u8 *leak_report;
|
||||
clib_mem_trace (1);
|
||||
error =
|
||||
vlib_cli_dispatch_sub_commands (vm, cm, &sub_input,
|
||||
parent_command_index);
|
||||
unformat_free (&sub_input);
|
||||
|
||||
/* Otherwise, the clib_error_t shows up as a leak... */
|
||||
if (error)
|
||||
{
|
||||
vlib_cli_output (vm, "%v", error->what);
|
||||
clib_error_free (error);
|
||||
error = 0;
|
||||
}
|
||||
|
||||
(void) clib_mem_trace_enable_disable (0);
|
||||
leak_report = format (0, "%U", format_mheap, clib_mem_get_heap (),
|
||||
1 /* verbose, i.e. print leaks */ );
|
||||
clib_mem_trace (0);
|
||||
vlib_cli_output (vm, "%v", leak_report);
|
||||
vec_free (leak_report);
|
||||
}
|
||||
|
||||
else
|
||||
if (unformat_user (input, unformat_vlib_cli_sub_command, vm, parent, &c))
|
||||
|
@ -661,52 +661,34 @@ vl_api_sw_interface_clear_stats_t_handler (vl_api_sw_interface_clear_stats_t *
|
||||
vnet_interface_main_t *im = &vnm->interface_main;
|
||||
vlib_simple_counter_main_t *sm;
|
||||
vlib_combined_counter_main_t *cm;
|
||||
static vnet_main_t **my_vnet_mains;
|
||||
int i, j, n_counters;
|
||||
int j, n_counters;
|
||||
int rv = 0;
|
||||
|
||||
if (mp->sw_if_index != ~0)
|
||||
VALIDATE_SW_IF_INDEX (mp);
|
||||
|
||||
vec_reset_length (my_vnet_mains);
|
||||
|
||||
for (i = 0; i < vec_len (vnet_mains); i++)
|
||||
{
|
||||
if (vnet_mains[i])
|
||||
vec_add1 (my_vnet_mains, vnet_mains[i]);
|
||||
}
|
||||
|
||||
if (vec_len (vnet_mains) == 0)
|
||||
vec_add1 (my_vnet_mains, vnm);
|
||||
|
||||
n_counters = vec_len (im->combined_sw_if_counters);
|
||||
|
||||
for (j = 0; j < n_counters; j++)
|
||||
{
|
||||
for (i = 0; i < vec_len (my_vnet_mains); i++)
|
||||
{
|
||||
im = &my_vnet_mains[i]->interface_main;
|
||||
cm = im->combined_sw_if_counters + j;
|
||||
if (mp->sw_if_index == (u32) ~ 0)
|
||||
vlib_clear_combined_counters (cm);
|
||||
else
|
||||
vlib_zero_combined_counter (cm, ntohl (mp->sw_if_index));
|
||||
}
|
||||
im = &vnm->interface_main;
|
||||
cm = im->combined_sw_if_counters + j;
|
||||
if (mp->sw_if_index == (u32) ~ 0)
|
||||
vlib_clear_combined_counters (cm);
|
||||
else
|
||||
vlib_zero_combined_counter (cm, ntohl (mp->sw_if_index));
|
||||
}
|
||||
|
||||
n_counters = vec_len (im->sw_if_counters);
|
||||
|
||||
for (j = 0; j < n_counters; j++)
|
||||
{
|
||||
for (i = 0; i < vec_len (my_vnet_mains); i++)
|
||||
{
|
||||
im = &my_vnet_mains[i]->interface_main;
|
||||
sm = im->sw_if_counters + j;
|
||||
if (mp->sw_if_index == (u32) ~ 0)
|
||||
vlib_clear_simple_counters (sm);
|
||||
else
|
||||
vlib_zero_simple_counter (sm, ntohl (mp->sw_if_index));
|
||||
}
|
||||
im = &vnm->interface_main;
|
||||
sm = im->sw_if_counters + j;
|
||||
if (mp->sw_if_index == (u32) ~ 0)
|
||||
vlib_clear_simple_counters (sm);
|
||||
else
|
||||
vlib_zero_simple_counter (sm, ntohl (mp->sw_if_index));
|
||||
}
|
||||
|
||||
BAD_SW_IF_INDEX_LABEL;
|
||||
|
@ -304,6 +304,7 @@ show_sw_interfaces (vlib_main_t * vm,
|
||||
verbose = 1;
|
||||
else
|
||||
{
|
||||
vec_free (sorted_sis);
|
||||
error = clib_error_return (0, "unknown input `%U'",
|
||||
format_unformat_error, linput);
|
||||
goto done;
|
||||
@ -314,7 +315,10 @@ show_sw_interfaces (vlib_main_t * vm,
|
||||
if (show_features || show_tag)
|
||||
{
|
||||
if (sw_if_index == ~(u32) 0)
|
||||
return clib_error_return (0, "Interface not specified...");
|
||||
{
|
||||
vec_free (sorted_sis);
|
||||
return clib_error_return (0, "Interface not specified...");
|
||||
}
|
||||
}
|
||||
|
||||
if (show_features)
|
||||
@ -335,6 +339,7 @@ show_sw_interfaces (vlib_main_t * vm,
|
||||
vlib_cli_output (vm, "%10s (%s)", "VTR", "--internal--");
|
||||
vlib_cli_output (vm, "%U", format_l2_output_features,
|
||||
l2_output->feature_bitmap, 1);
|
||||
vec_free (sorted_sis);
|
||||
return 0;
|
||||
}
|
||||
if (show_tag)
|
||||
@ -344,6 +349,7 @@ show_sw_interfaces (vlib_main_t * vm,
|
||||
vlib_cli_output (vm, "%U: %s",
|
||||
format_vnet_sw_if_index_name, vnm, sw_if_index,
|
||||
tag ? (char *) tag : "(none)");
|
||||
vec_free (sorted_sis);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -497,42 +503,24 @@ clear_interface_counters (vlib_main_t * vm,
|
||||
vnet_interface_main_t *im = &vnm->interface_main;
|
||||
vlib_simple_counter_main_t *sm;
|
||||
vlib_combined_counter_main_t *cm;
|
||||
static vnet_main_t **my_vnet_mains;
|
||||
int i, j, n_counters;
|
||||
|
||||
vec_reset_length (my_vnet_mains);
|
||||
|
||||
for (i = 0; i < vec_len (vnet_mains); i++)
|
||||
{
|
||||
if (vnet_mains[i])
|
||||
vec_add1 (my_vnet_mains, vnet_mains[i]);
|
||||
}
|
||||
|
||||
if (vec_len (vnet_mains) == 0)
|
||||
vec_add1 (my_vnet_mains, vnm);
|
||||
int j, n_counters;
|
||||
|
||||
n_counters = vec_len (im->combined_sw_if_counters);
|
||||
|
||||
for (j = 0; j < n_counters; j++)
|
||||
{
|
||||
for (i = 0; i < vec_len (my_vnet_mains); i++)
|
||||
{
|
||||
im = &my_vnet_mains[i]->interface_main;
|
||||
cm = im->combined_sw_if_counters + j;
|
||||
vlib_clear_combined_counters (cm);
|
||||
}
|
||||
im = &vnm->interface_main;
|
||||
cm = im->combined_sw_if_counters + j;
|
||||
vlib_clear_combined_counters (cm);
|
||||
}
|
||||
|
||||
n_counters = vec_len (im->sw_if_counters);
|
||||
|
||||
for (j = 0; j < n_counters; j++)
|
||||
{
|
||||
for (i = 0; i < vec_len (my_vnet_mains); i++)
|
||||
{
|
||||
im = &my_vnet_mains[i]->interface_main;
|
||||
sm = im->sw_if_counters + j;
|
||||
vlib_clear_simple_counters (sm);
|
||||
}
|
||||
im = &vnm->interface_main;
|
||||
sm = im->sw_if_counters + j;
|
||||
vlib_clear_simple_counters (sm);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -219,66 +219,46 @@ format_vnet_sw_interface_cntrs (u8 * s, vnet_interface_main_t * im,
|
||||
vnet_sw_interface_t * si)
|
||||
{
|
||||
u32 indent, n_printed;
|
||||
int i, j, n_counters;
|
||||
static vnet_main_t **my_vnet_mains;
|
||||
|
||||
vec_reset_length (my_vnet_mains);
|
||||
int j, n_counters;
|
||||
u8 *n = 0;
|
||||
|
||||
indent = format_get_indent (s);
|
||||
n_printed = 0;
|
||||
|
||||
{
|
||||
vlib_combined_counter_main_t *cm;
|
||||
vlib_counter_t v, vtotal;
|
||||
u8 *n = 0;
|
||||
n_counters = vec_len (im->combined_sw_if_counters);
|
||||
|
||||
for (i = 0; i < vec_len (vnet_mains); i++)
|
||||
{
|
||||
if (vnet_mains[i])
|
||||
vec_add1 (my_vnet_mains, vnet_mains[i]);
|
||||
}
|
||||
/* rx, tx counters... */
|
||||
for (j = 0; j < n_counters; j++)
|
||||
{
|
||||
vlib_combined_counter_main_t *cm;
|
||||
vlib_counter_t v, vtotal;
|
||||
vtotal.packets = 0;
|
||||
vtotal.bytes = 0;
|
||||
|
||||
if (vec_len (my_vnet_mains) == 0)
|
||||
vec_add1 (my_vnet_mains, &vnet_main);
|
||||
cm = im->combined_sw_if_counters + j;
|
||||
vlib_get_combined_counter (cm, si->sw_if_index, &v);
|
||||
vtotal.packets += v.packets;
|
||||
vtotal.bytes += v.bytes;
|
||||
|
||||
/* Each vnet_main_t has its own copy of the interface counters */
|
||||
n_counters = vec_len (im->combined_sw_if_counters);
|
||||
/* Only display non-zero counters. */
|
||||
if (vtotal.packets == 0)
|
||||
continue;
|
||||
|
||||
/* rx, tx counters... */
|
||||
for (j = 0; j < n_counters; j++)
|
||||
{
|
||||
vtotal.packets = 0;
|
||||
vtotal.bytes = 0;
|
||||
|
||||
for (i = 0; i < vec_len (my_vnet_mains); i++)
|
||||
{
|
||||
im = &my_vnet_mains[i]->interface_main;
|
||||
cm = im->combined_sw_if_counters + j;
|
||||
vlib_get_combined_counter (cm, si->sw_if_index, &v);
|
||||
vtotal.packets += v.packets;
|
||||
vtotal.bytes += v.bytes;
|
||||
}
|
||||
|
||||
/* Only display non-zero counters. */
|
||||
if (vtotal.packets == 0)
|
||||
continue;
|
||||
|
||||
if (n_printed > 0)
|
||||
s = format (s, "\n%U", format_white_space, indent);
|
||||
n_printed += 2;
|
||||
|
||||
if (n)
|
||||
_vec_len (n) = 0;
|
||||
n = format (n, "%s packets", cm->name);
|
||||
s = format (s, "%-16v%16Ld", n, vtotal.packets);
|
||||
if (n_printed > 0)
|
||||
s = format (s, "\n%U", format_white_space, indent);
|
||||
n_printed += 2;
|
||||
|
||||
if (n)
|
||||
_vec_len (n) = 0;
|
||||
n = format (n, "%s bytes", cm->name);
|
||||
s = format (s, "\n%U%-16v%16Ld",
|
||||
format_white_space, indent, n, vtotal.bytes);
|
||||
}
|
||||
vec_free (n);
|
||||
}
|
||||
n = format (n, "%s packets", cm->name);
|
||||
s = format (s, "%-16v%16Ld", n, vtotal.packets);
|
||||
|
||||
_vec_len (n) = 0;
|
||||
n = format (n, "%s bytes", cm->name);
|
||||
s = format (s, "\n%U%-16v%16Ld",
|
||||
format_white_space, indent, n, vtotal.bytes);
|
||||
}
|
||||
vec_free (n);
|
||||
|
||||
{
|
||||
vlib_simple_counter_main_t *cm;
|
||||
@ -290,14 +270,10 @@ format_vnet_sw_interface_cntrs (u8 * s, vnet_interface_main_t * im,
|
||||
{
|
||||
vtotal = 0;
|
||||
|
||||
for (i = 0; i < vec_len (my_vnet_mains); i++)
|
||||
{
|
||||
im = &my_vnet_mains[i]->interface_main;
|
||||
cm = im->sw_if_counters + j;
|
||||
cm = im->sw_if_counters + j;
|
||||
|
||||
v = vlib_get_simple_counter (cm, si->sw_if_index);
|
||||
vtotal += v;
|
||||
}
|
||||
v = vlib_get_simple_counter (cm, si->sw_if_index);
|
||||
vtotal += v;
|
||||
|
||||
/* Only display non-zero counters. */
|
||||
if (vtotal == 0)
|
||||
|
@ -41,7 +41,6 @@
|
||||
#include <vnet/ip/ip.h>
|
||||
|
||||
vnet_main_t vnet_main;
|
||||
vnet_main_t **vnet_mains;
|
||||
|
||||
vnet_main_t *
|
||||
vnet_get_main (void)
|
||||
|
@ -81,7 +81,6 @@ typedef struct vnet_main_t
|
||||
} vnet_main_t;
|
||||
|
||||
extern vnet_main_t vnet_main;
|
||||
extern vnet_main_t **vnet_mains;
|
||||
|
||||
#include <vnet/interface_funcs.h>
|
||||
#include <vnet/global_funcs.h>
|
||||
|
@ -406,6 +406,8 @@ typedef struct
|
||||
clib_error_t *clib_mem_vm_ext_map (clib_mem_vm_map_t * a);
|
||||
void clib_mem_vm_randomize_va (uword * requested_va, u32 log2_page_size);
|
||||
void mheap_trace (void *v, int enable);
|
||||
uword clib_mem_trace_enable_disable (uword enable);
|
||||
void clib_mem_trace (int enable);
|
||||
|
||||
#include <vppinfra/error.h> /* clib_panic */
|
||||
|
||||
|
Reference in New Issue
Block a user