From: Ben Pfaff Date: Tue, 23 Apr 2013 21:52:41 +0000 (-0700) Subject: leak-checker: Remove because it cannot be made thread-safe. X-Git-Tag: sliver-openvswitch-1.10.90-3~6^2~103 X-Git-Url: http://git.onelab.eu/?p=sliver-openvswitch.git;a=commitdiff_plain;h=825da1c6d1c7b9bc5128d7588b8bad6efaae650e leak-checker: Remove because it cannot be made thread-safe. The underlying glibc interface is deprecated because the interface itself is not thread-safe. That means that there's no way for a layer on top of it to be thread-safe. Signed-off-by: Ben Pfaff Acked-by: Ethan Jackson --- diff --git a/debian/openvswitch-common.install b/debian/openvswitch-common.install index e2c0454ad..f2a0d48d7 100644 --- a/debian/openvswitch-common.install +++ b/debian/openvswitch-common.install @@ -2,7 +2,6 @@ usr/bin/ovs-appctl usr/bin/ovs-benchmark usr/bin/ovs-ofctl usr/bin/ovs-parse-backtrace -usr/bin/ovs-parse-leaks usr/bin/ovs-pki usr/bin/ovsdb-client usr/sbin/ovs-bugtool diff --git a/debian/openvswitch-common.manpages b/debian/openvswitch-common.manpages index 59696774c..a219722d5 100644 --- a/debian/openvswitch-common.manpages +++ b/debian/openvswitch-common.manpages @@ -6,4 +6,3 @@ _debian/utilities/ovs-ofctl.8 _debian/utilities/ovs-pki.8 _debian/utilities/bugtool/ovs-bugtool.8 utilities/ovs-parse-backtrace.8 -utilities/ovs-parse-leaks.8 diff --git a/lib/automake.mk b/lib/automake.mk index bcaa1f8e5..8b4cd9279 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -69,8 +69,6 @@ lib_libopenvswitch_a_SOURCES = \ lib/jsonrpc.h \ lib/lacp.c \ lib/lacp.h \ - lib/leak-checker.c \ - lib/leak-checker.h \ lib/learn.c \ lib/learn.h \ lib/learning-switch.c \ @@ -291,7 +289,6 @@ MAN_FRAGMENTS += \ lib/coverage-unixctl.man \ lib/daemon.man \ lib/daemon-syn.man \ - lib/leak-checker.man \ lib/memory-unixctl.man \ lib/ofp-version.man \ lib/ovs.tmac \ diff --git a/lib/leak-checker.c b/lib/leak-checker.c deleted file mode 100644 index 1fd3d5b5f..000000000 --- a/lib/leak-checker.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010 Nicira, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include "leak-checker.h" -#include -#include "backtrace.h" -#include "vlog.h" - -VLOG_DEFINE_THIS_MODULE(leak_checker); - -#ifndef HAVE_MALLOC_HOOKS -void -leak_checker_start(const char *file_name OVS_UNUSED) -{ - VLOG_WARN("not enabling leak checker because the libc in use does not " - "have the required hooks"); -} - -void -leak_checker_set_limit(off_t max_size OVS_UNUSED) -{ -} - -void -leak_checker_claim(const void *p OVS_UNUSED) -{ -} - -void -leak_checker_usage(void) -{ - printf(" --check-leaks=FILE (accepted but ignored in this build)\n"); -} -#else /* HAVE_MALLOC_HOOKS */ -#include -#include -#include -#include - -typedef void *malloc_hook_type(size_t, const void *); -typedef void *realloc_hook_type(void *, size_t, const void *); -typedef void free_hook_type(void *, const void *); - -struct hooks { - malloc_hook_type *malloc_hook_func; - realloc_hook_type *realloc_hook_func; - free_hook_type *free_hook_func; -}; - -static malloc_hook_type hook_malloc; -static realloc_hook_type hook_realloc; -static free_hook_type hook_free; - -static struct hooks libc_hooks; -static const struct hooks our_hooks = { hook_malloc, hook_realloc, hook_free }; - -static FILE *file; -static off_t limit = 10 * 1000 * 1000; - -static void -get_hooks(struct hooks *hooks) -{ - hooks->malloc_hook_func = __malloc_hook; - hooks->realloc_hook_func = __realloc_hook; - hooks->free_hook_func = __free_hook; -} - -static void -set_hooks(const struct hooks *hooks) -{ - __malloc_hook = hooks->malloc_hook_func; - __realloc_hook = hooks->realloc_hook_func; - __free_hook = hooks->free_hook_func; -} - -void -leak_checker_start(const char *file_name) -{ - if (!file) { - file = fopen(file_name, "w"); - if (!file) { - VLOG_WARN("failed to create \"%s\": %s", - file_name, strerror(errno)); - return; - } - setvbuf(file, NULL, _IOLBF, 0); - VLOG_WARN("enabled memory leak logging to \"%s\"", file_name); - get_hooks(&libc_hooks); - set_hooks(&our_hooks); - } -} - -void -leak_checker_stop(void) -{ - if (file) { - fclose(file); - file = NULL; - set_hooks(&libc_hooks); - VLOG_WARN("disabled memory leak logging"); - } -} - -void -leak_checker_set_limit(off_t limit_) -{ - limit = limit_; -} - -void -leak_checker_usage(void) -{ - printf(" --check-leaks=FILE log malloc and free calls to FILE\n"); -} - -static void PRINTF_FORMAT(1, 2) -log_callers(const char *format, ...) -{ - struct backtrace backtrace; - va_list args; - int i; - - va_start(args, format); - vfprintf(file, format, args); - va_end(args); - - putc(':', file); - backtrace_capture(&backtrace); - for (i = 0; i < backtrace.n_frames; i++) { - fprintf(file, " 0x%"PRIxPTR, backtrace.frames[i]); - } - putc('\n', file); -} - -static void -reset_hooks(void) -{ - static int count; - - if (file) { - if (ferror(file)) { - VLOG_WARN("error writing leak checker log file"); - leak_checker_stop(); - return; - } - - if (count++ >= 100 && limit) { - struct stat s; - count = 0; - if (fstat(fileno(file), &s) < 0) { - VLOG_WARN("cannot fstat leak checker log file: %s", - strerror(errno)); - leak_checker_stop(); - return; - } - if (s.st_size > limit) { - VLOG_WARN("leak checker log file size exceeded limit"); - leak_checker_stop(); - return; - } - } - } - if (file) { - set_hooks(&our_hooks); - } -} - -static void * -hook_malloc(size_t size, const void *caller OVS_UNUSED) -{ - void *p; - - set_hooks(&libc_hooks); - p = malloc(size); - get_hooks(&libc_hooks); - - log_callers("malloc(%zu) -> %p", size, p); - - reset_hooks(); - return p; -} - -void -leak_checker_claim(const void *p) -{ - if (!file) { - return; - } - - if (p) { - set_hooks(&libc_hooks); - log_callers("claim(%p)", p); - reset_hooks(); - } -} - -static void -hook_free(void *p, const void *caller OVS_UNUSED) -{ - if (!p) { - return; - } - - set_hooks(&libc_hooks); - log_callers("free(%p)", p); - free(p); - get_hooks(&libc_hooks); - - reset_hooks(); -} - -static void * -hook_realloc(void *p, size_t size, const void *caller OVS_UNUSED) -{ - void *q; - - set_hooks(&libc_hooks); - q = realloc(p, size); - get_hooks(&libc_hooks); - - if (p != q) { - log_callers("realloc(%p, %zu) -> %p", p, size, q); - } - - reset_hooks(); - - return q; -} -#endif /* HAVE_MALLOC_HOOKS */ diff --git a/lib/leak-checker.h b/lib/leak-checker.h deleted file mode 100644 index e74cd9d80..000000000 --- a/lib/leak-checker.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2011 Nicira, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef LEAK_CHECKER_H -#define LEAK_CHECKER_H 1 - -#include - -#define LEAK_CHECKER_OPTION_ENUMS \ - OPT_CHECK_LEAKS, \ - OPT_LEAK_LIMIT -#define LEAK_CHECKER_LONG_OPTIONS \ - {"check-leaks", required_argument, NULL, OPT_CHECK_LEAKS}, \ - {"leak-limit", required_argument, NULL, OPT_LEAK_LIMIT} -#define LEAK_CHECKER_OPTION_HANDLERS \ - case OPT_CHECK_LEAKS: \ - leak_checker_start(optarg); \ - break; \ - case OPT_LEAK_LIMIT: \ - leak_checker_set_limit(atol(optarg)); \ - break; -void leak_checker_start(const char *file_name); -void leak_checker_set_limit(off_t limit); -void leak_checker_stop(void); -void leak_checker_claim(const void *); -void leak_checker_usage(void); - -#endif /* leak-checker.h */ diff --git a/lib/leak-checker.man b/lib/leak-checker.man deleted file mode 100644 index beba9e137..000000000 --- a/lib/leak-checker.man +++ /dev/null @@ -1,15 +0,0 @@ -.TP -\fB\-\-check\-leaks=\fIfile\fR -. -Logs information about memory allocation and deallocation to -\fIfile\fR, to allow for debugging memory leaks in \fB\*(PN\fR. This -option slows down \fB\*(PN\fR considerably, so it should only be used -when a memory leak is suspected. Use the \fBovs\-parse\-leaks\fR script -to interpret the leak file. -.TP -\fB\-\-leak\-limit=\fIsize\fR -. -Limits size of the leak file as specified by \fB\-\-check\-leaks\fR to -\fIsize\fR bytes. Finding leaks sometimes requires allowing the leak -file to grow very large, up to 1GB. By default, files are limited -to 10MB. diff --git a/lib/stream-fd.c b/lib/stream-fd.c index 90d328acc..df5e8b0e8 100644 --- a/lib/stream-fd.c +++ b/lib/stream-fd.c @@ -24,7 +24,6 @@ #include #include #include "fatal-signal.h" -#include "leak-checker.h" #include "poll-loop.h" #include "socket-util.h" #include "stress.h" diff --git a/lib/stream-ssl.c b/lib/stream-ssl.c index 5caac4975..c373ca960 100644 --- a/lib/stream-ssl.c +++ b/lib/stream-ssl.c @@ -35,7 +35,6 @@ #include "coverage.h" #include "dynamic-string.h" #include "entropy.h" -#include "leak-checker.h" #include "ofpbuf.h" #include "openflow/openflow.h" #include "packets.h" @@ -674,7 +673,6 @@ ssl_send(struct stream *stream, const void *buffer, size_t n) ssl_clear_txbuf(sslv); return n; case EAGAIN: - leak_checker_claim(buffer); return n; default: sslv->txbuf = NULL; diff --git a/lib/vconn-stream.c b/lib/vconn-stream.c index e91d92c08..08ec7bf6b 100644 --- a/lib/vconn-stream.c +++ b/lib/vconn-stream.c @@ -22,7 +22,6 @@ #include #include #include "fatal-signal.h" -#include "leak-checker.h" #include "ofpbuf.h" #include "openflow/openflow.h" #include "poll-loop.h" @@ -210,7 +209,6 @@ vconn_stream_send(struct vconn *vconn, struct ofpbuf *buffer) ofpbuf_delete(buffer); return 0; } else if (retval >= 0 || retval == -EAGAIN) { - leak_checker_claim(buffer); s->txbuf = buffer; if (retval > 0) { ofpbuf_pull(buffer, retval); diff --git a/manpages.mk b/manpages.mk index a14f9688d..ed0d999e0 100644 --- a/manpages.mk +++ b/manpages.mk @@ -229,7 +229,6 @@ vswitchd/ovs-vswitchd.8: \ lib/common.man \ lib/coverage-unixctl.man \ lib/daemon.man \ - lib/leak-checker.man \ lib/memory-unixctl.man \ lib/ssl-bootstrap.man \ lib/ssl.man \ @@ -244,7 +243,6 @@ vswitchd/ovs-vswitchd.8.in: lib/common.man: lib/coverage-unixctl.man: lib/daemon.man: -lib/leak-checker.man: lib/memory-unixctl.man: lib/ssl-bootstrap.man: lib/ssl.man: diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c index 394f5a515..b31560b3a 100644 --- a/ovsdb/ovsdb-server.c +++ b/ovsdb/ovsdb-server.c @@ -32,7 +32,6 @@ #include "json.h" #include "jsonrpc.h" #include "jsonrpc-server.h" -#include "leak-checker.h" #include "list.h" #include "memory.h" #include "ovsdb.h" @@ -1013,7 +1012,6 @@ parse_options(int *argcp, char **argvp[], OPT_BOOTSTRAP_CA_CERT, OPT_ENABLE_DUMMY, VLOG_OPTION_ENUMS, - LEAK_CHECKER_OPTION_ENUMS, DAEMON_OPTION_ENUMS }; static const struct option long_options[] = { @@ -1024,7 +1022,6 @@ parse_options(int *argcp, char **argvp[], {"version", no_argument, NULL, 'V'}, DAEMON_LONG_OPTIONS, VLOG_LONG_OPTIONS, - LEAK_CHECKER_LONG_OPTIONS, {"bootstrap-ca-cert", required_argument, NULL, OPT_BOOTSTRAP_CA_CERT}, {"private-key", required_argument, NULL, 'p'}, {"certificate", required_argument, NULL, 'c'}, @@ -1067,7 +1064,6 @@ parse_options(int *argcp, char **argvp[], VLOG_OPTION_HANDLERS DAEMON_OPTION_HANDLERS - LEAK_CHECKER_OPTION_HANDLERS case 'p': private_key_file = optarg; @@ -1122,7 +1118,6 @@ usage(void) " --unixctl=SOCKET override default control socket name\n" " -h, --help display this help message\n" " -V, --version display version information\n"); - leak_checker_usage(); exit(EXIT_SUCCESS); } diff --git a/rhel/openvswitch-fedora.spec.in b/rhel/openvswitch-fedora.spec.in index 6c225f7ca..dc40403ee 100644 --- a/rhel/openvswitch-fedora.spec.in +++ b/rhel/openvswitch-fedora.spec.in @@ -1,6 +1,6 @@ # Spec file for Open vSwitch. -# Copyright (C) 2009, 2010 Nicira Networks, Inc. +# Copyright (C) 2009, 2010, 2013 Nicira Networks, Inc. # # Copying and distribution of this file, with or without modification, # are permitted in any medium without royalty provided the copyright @@ -169,7 +169,6 @@ systemctl start openvswitch.service %doc /usr/share/man/man8/ovs-dpctl.8.gz %doc /usr/share/man/man8/ovs-ofctl.8.gz %doc /usr/share/man/man8/ovs-parse-backtrace.8.gz -%doc /usr/share/man/man8/ovs-parse-leaks.8.gz %doc /usr/share/man/man8/ovs-vsctl.8.gz %doc /usr/share/man/man8/ovs-vswitchd.8.gz %doc /usr/share/man/man8/ovs-test.8.gz @@ -179,7 +178,6 @@ systemctl start openvswitch.service %exclude /etc/openvswitch %exclude /usr/bin/ovs-benchmark %exclude /usr/bin/ovs-parse-backtrace -%exclude /usr/bin/ovs-parse-leaks %exclude /usr/bin/ovs-pcap %exclude /usr/bin/ovs-tcpundump %exclude /usr/bin/ovs-vlan-test diff --git a/rhel/openvswitch.spec.in b/rhel/openvswitch.spec.in index 9f4088196..53512bc5c 100644 --- a/rhel/openvswitch.spec.in +++ b/rhel/openvswitch.spec.in @@ -1,6 +1,6 @@ # Spec file for Open vSwitch on Red Hat Enterprise Linux. -# Copyright (C) 2009, 2010, 2011, 2012 Nicira, Inc. +# Copyright (C) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. # # Copying and distribution of this file, with or without modification, # are permitted in any medium without royalty provided the copyright @@ -116,7 +116,6 @@ exit 0 /usr/bin/ovs-dpctl /usr/bin/ovs-ofctl /usr/bin/ovs-parse-backtrace -/usr/bin/ovs-parse-leaks /usr/bin/ovs-pcap /usr/bin/ovs-pki /usr/bin/ovs-tcpundump @@ -140,7 +139,6 @@ exit 0 /usr/share/man/man8/ovs-dpctl.8.gz /usr/share/man/man8/ovs-ofctl.8.gz /usr/share/man/man8/ovs-parse-backtrace.8.gz -/usr/share/man/man8/ovs-parse-leaks.8.gz /usr/share/man/man8/ovs-pki.8.gz /usr/share/man/man8/ovs-vlan-test.8.gz /usr/share/man/man8/ovs-vsctl.8.gz diff --git a/utilities/.gitignore b/utilities/.gitignore index ad99dda69..a0bd97fd3 100644 --- a/utilities/.gitignore +++ b/utilities/.gitignore @@ -19,7 +19,6 @@ /ovs-ofctl /ovs-ofctl.8 /ovs-parse-backtrace -/ovs-parse-leaks /ovs-pcap /ovs-pcap.1 /ovs-pki diff --git a/utilities/automake.mk b/utilities/automake.mk index ab8774a9a..797748c6b 100644 --- a/utilities/automake.mk +++ b/utilities/automake.mk @@ -4,7 +4,7 @@ bin_PROGRAMS += \ utilities/ovs-dpctl \ utilities/ovs-ofctl \ utilities/ovs-vsctl -bin_SCRIPTS += utilities/ovs-pki utilities/ovs-parse-leaks +bin_SCRIPTS += utilities/ovs-pki if HAVE_PYTHON bin_SCRIPTS += \ utilities/ovs-l3ping \ @@ -26,7 +26,6 @@ EXTRA_DIST += \ utilities/ovs-l3ping.in \ utilities/ovs-lib.in \ utilities/ovs-parse-backtrace.in \ - utilities/ovs-parse-leaks.in \ utilities/ovs-pcap.in \ utilities/ovs-pki.in \ utilities/ovs-save \ @@ -42,7 +41,6 @@ MAN_ROOTS += \ utilities/ovs-l3ping.8.in \ utilities/ovs-ofctl.8.in \ utilities/ovs-parse-backtrace.8 \ - utilities/ovs-parse-leaks.8 \ utilities/ovs-pcap.1.in \ utilities/ovs-pki.8.in \ utilities/ovs-tcpundump.1.in \ @@ -63,7 +61,6 @@ DISTCLEANFILES += \ utilities/ovs-lib \ utilities/ovs-ofctl.8 \ utilities/ovs-parse-backtrace \ - utilities/ovs-parse-leaks \ utilities/ovs-pcap \ utilities/ovs-pcap.1 \ utilities/ovs-pki \ @@ -85,7 +82,6 @@ man_MANS += \ utilities/ovs-l3ping.8 \ utilities/ovs-ofctl.8 \ utilities/ovs-parse-backtrace.8 \ - utilities/ovs-parse-leaks.8 \ utilities/ovs-pcap.1 \ utilities/ovs-pki.8 \ utilities/ovs-tcpundump.1 \ diff --git a/utilities/ovs-parse-leaks.8 b/utilities/ovs-parse-leaks.8 deleted file mode 100644 index e7bd1c5ec..000000000 --- a/utilities/ovs-parse-leaks.8 +++ /dev/null @@ -1,35 +0,0 @@ -.TH ovs\-parse\-leaks 8 "August 2010" "Open vSwitch" "Open vSwitch Manual" -. -.SH NAME -ovs\-parse\-leaks \- parses OVS leak checker log files -. -.SH SYNOPSIS -\fBovs\-parse\-leaks\fR [\fIbinary\fR] \fB< \fIlog\fR -. -.SH DESCRIPTION -Many Open vSwitch daemons accept a \fB\-\-check\-leaks\fR option that -writes information about memory allocation and deallocation to a log -file. \fBovs\-parse\-leaks\fR parses log files produced by this -option and prints a summary of the results. The most interesting part -of the output is a list of memory blocks that were allocated but not -freed, which Open vSwitch developers can use to find and fix memory -leaks. -.PP -The log file must be supplied on standard input. The binary that -produced the output should be supplied as the sole non-option -argument. For best results, the binary should have debug symbols. -. -.SH OPTIONS -.TP -\fB\-\-help\fR -Prints a usage message and exits. -.SH BUGS -The output can be hard to interpret, especially for a daemon that does -not exit in normal operation. Using \fBovs\-appctl\fR(8) to invoke -the \fBexit\fR command that some Open vSwitch daemons support -sometimes helps with this. -.PP -\fBovs\-parse\-leaks\fR usually incorrectly reports one or more ``bad -frees of not-allocated address'' errors at the beginning of output. -These reflect frees of data that were allocated before the leak -checker was turned on during program initialization. diff --git a/utilities/ovs-parse-leaks.in b/utilities/ovs-parse-leaks.in deleted file mode 100755 index 72417e511..000000000 --- a/utilities/ovs-parse-leaks.in +++ /dev/null @@ -1,299 +0,0 @@ -#! @PERL@ - -# Copyright (c) 2009, 2010 Nicira, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -use strict; -use warnings; - -if (grep($_ eq '--help', @ARGV)) { - print < 1; -die "$0: $ARGV[0] does not exist" if @ARGV > 0 && ! -e $ARGV[0]; - -our ($binary); -our ($a2l) = search_path("addr2line"); -my ($no_syms) = "symbols will not be translated (use --help for help)"; -if (!@ARGV) { - print "no binary specified; $no_syms\n"; -} elsif (! -e $ARGV[0]) { - print "$ARGV[0] does not exist; $no_syms"; -} elsif (!defined($a2l)) { - print "addr2line not found in PATH; $no_syms"; -} else { - $binary = $ARGV[0]; -} - -our ($objdump) = search_path("objdump"); -print "objdump not found; dynamic library symbols will not be translated\n" - if !defined($objdump); - -our %blocks; -our @segments; -while () { - my $ptr = "((?:0x)?[0-9a-fA-F]+|\\(nil\\))"; - my $callers = ":((?: $ptr)+)"; - if (/^malloc\((\d+)\) -> $ptr$callers$/) { - allocated($., $2, $1, $3); - } elsif (/^claim\($ptr\)$callers$/) { - claimed($., $1, $2); - } elsif (/realloc\($ptr, (\d+)\) -> $ptr$callers$/) { - my ($callers) = $4; - freed($., $1, $callers); - allocated($., $3, $2, $callers); - } elsif (/^free\($ptr\)$callers$/) { - freed($., $1, $2); - } elsif (/^segment: $ptr-$ptr $ptr [-r][-w][-x][sp] (.*)/) { - add_segment(hex($1), hex($2), hex($3), $4); - } else { - print "stdin:$.: syntax error\n"; - } -} -if (%blocks) { - my $n_blocks = scalar(keys(%blocks)); - my $n_bytes = 0; - $n_bytes += $_->{SIZE} foreach values(%blocks); - print "$n_bytes bytes in $n_blocks blocks not freed at end of run\n"; - my %blocks_by_callers; - foreach my $block (values(%blocks)) { - my ($trimmed_callers) = trim_callers($block->{CALLERS}); - push (@{$blocks_by_callers{$trimmed_callers}}, $block); - } - foreach my $callers (sort {@{$b} <=> @{$a}} (values(%blocks_by_callers))) { - $n_blocks = scalar(@{$callers}); - $n_bytes = 0; - $n_bytes += $_->{SIZE} foreach @{$callers}; - print "$n_bytes bytes in these $n_blocks blocks were not freed:\n"; - my $i = 0; - my $max = 5; - foreach my $block (sort {$a->{LINE} <=> $b->{LINE}} (@{$callers})) { - printf "\t%d-byte block at 0x%08x allocated on stdin:%d\n", - $block->{SIZE}, $block->{BASE}, $block->{LINE}; - last if $i++ > $max; - } - print "\t...and ", $n_blocks - $max, " others...\n" - if $n_blocks > $max; - print "The blocks listed above were allocated by:\n"; - print_callers("\t", ${$callers}[0]->{CALLERS}); - } -} -sub interp_pointer { - my ($s_ptr) = @_; - return $s_ptr eq '(nil)' ? 0 : hex($s_ptr); -} - -sub allocated { - my ($line, $s_base, $size, $callers) = @_; - my ($base) = interp_pointer($s_base); - return if !$base; - my ($info) = {LINE => $line, - BASE => $base, - SIZE => $size, - CALLERS => $callers}; - if (exists($blocks{$base})) { - print "In-use address returned by allocator:\n"; - print "\tInitial allocation:\n"; - print_block("\t\t", $blocks{$base}); - print "\tNew allocation:\n"; - print_block("\t\t", $info); - } - $blocks{$base} = $info; -} - -sub claimed { - my ($line, $s_base, $callers) = @_; - my ($base) = interp_pointer($s_base); - return if !$base; - if (exists($blocks{$base})) { - $blocks{$base}{LINE} = $line; - $blocks{$base}{CALLERS} = $callers; - } else { - printf "Claim asserted on not-in-use block 0x%08x by:\n", $base; - print_callers('', $callers); - } -} - -sub freed { - my ($line, $s_base, $callers) = @_; - my ($base) = interp_pointer($s_base); - return if !$base; - - if (!delete($blocks{$base})) { - printf "Bad free of not-allocated address 0x%08x on stdin:%d by:\n", $base, $line; - print_callers('', $callers); - } -} - -sub print_block { - my ($prefix, $info) = @_; - printf '%s%d-byte block at 0x%08x allocated on stdin:%d by:' . "\n", - $prefix, $info->{SIZE}, $info->{BASE}, $info->{LINE}; - print_callers($prefix, $info->{CALLERS}); -} - -sub print_callers { - my ($prefix, $callers) = @_; - foreach my $pc (split(' ', $callers)) { - print "$prefix\t", lookup_pc($pc), "\n"; - } -} - -our (%cache); -sub lookup_pc { - my ($s_pc) = @_; - if (defined($binary)) { - my ($pc) = hex($s_pc); - my ($output) = "$s_pc: "; - if (!exists($cache{$pc})) { - open(A2L, "$a2l -fe $binary --demangle $s_pc|"); - chomp(my $function = ); - chomp(my $line = ); - close(A2L); - if ($function eq '??') { - ($function, $line) = lookup_pc_by_segment($pc); - } - $line =~ s/^(\.\.\/)*//; - $line = "..." . substr($line, -25) if length($line) > 28; - $cache{$pc} = "$s_pc: $function ($line)"; - } - return $cache{$pc}; - } else { - return "$s_pc"; - } -} - -sub trim_callers { - my ($in) = @_; - my (@out); - foreach my $pc (split(' ', $in)) { - my $xlated = lookup_pc($pc); - if ($xlated =~ /\?\?/) { - push(@out, "...") if !@out || $out[$#out] ne '...'; - } else { - push(@out, $pc); - } - } - return join(' ', @out); -} - -sub search_path { - my ($target) = @_; - for my $dir (split (':', $ENV{PATH})) { - my ($file) = "$dir/$target"; - return $file if -e $file; - } - return undef; -} - -sub add_segment { - my ($vm_start, $vm_end, $vm_pgoff, $file) = @_; - for (my $i = 0; $i <= $#segments; $i++) { - my ($s) = $segments[$i]; - next if $vm_end <= $s->{START} || $vm_start >= $s->{END}; - if ($vm_start <= $s->{START} && $vm_end >= $s->{END}) { - splice(@segments, $i, 1); - --$i; - } else { - $s->{START} = $vm_end if $vm_end > $s->{START}; - $s->{END} = $vm_start if $vm_start <= $s->{END}; - } - } - push(@segments, {START => $vm_start, - END => $vm_end, - PGOFF => $vm_pgoff, - FILE => $file}); - @segments = sort { $a->{START} <=> $b->{START} } @segments; -} - -sub binary_search { - my ($array, $value) = @_; - my $l = 0; - my $r = $#{$array}; - while ($l <= $r) { - my $m = int(($l + $r) / 2); - my $e = $array->[$m]; - if ($value < $e->{START}) { - $r = $m - 1; - } elsif ($value >= $e->{END}) { - $l = $m + 1; - } else { - return $e; - } - } - return undef; -} - -sub read_sections { - my ($file) = @_; - my (@sections); - open(OBJDUMP, "$objdump -h $file|"); - while () { - my $ptr = "([0-9a-fA-F]+)"; - my ($name, $size, $vma, $lma, $file_off) - = /^\s*\d+\s+(\S+)\s+$ptr\s+$ptr\s+$ptr\s+$ptr/ - or next; - push(@sections, {START => hex($file_off), - END => hex($file_off) + hex($size), - NAME => $name}); - } - close(OBJDUMP); - return [sort { $a->{START} <=> $b->{START} } @sections ]; -} - -our %file_to_sections; -sub segment_to_section { - my ($file, $file_offset) = @_; - if (!defined($file_to_sections{$file})) { - $file_to_sections{$file} = read_sections($file); - } - return binary_search($file_to_sections{$file}, $file_offset); -} - -sub address_to_segment { - my ($pc) = @_; - return binary_search(\@segments, $pc); -} - -sub lookup_pc_by_segment { - return ('??', 0) if !defined($objdump); - - my ($pc) = @_; - my ($segment) = address_to_segment($pc); - return ('??', 0) if !defined($segment) || $segment->{FILE} eq ''; - - my ($file_offset) = $pc - $segment->{START} + $segment->{PGOFF}; - my ($section) = segment_to_section($segment->{FILE}, $file_offset); - return ('??', 0) if !defined($section); - - my ($section_offset) = $file_offset - $section->{START}; - open(A2L, sprintf("%s -fe %s --demangle --section=$section->{NAME} 0x%x|", - $a2l, $segment->{FILE}, $section_offset)); - chomp(my $function = ); - chomp(my $line = ); - close(A2L); - - return ($function, $line); -} - -# Local Variables: -# mode: perl -# End: diff --git a/vswitchd/ovs-vswitchd.8.in b/vswitchd/ovs-vswitchd.8.in index efa4c7e4f..86500c98b 100644 --- a/vswitchd/ovs-vswitchd.8.in +++ b/vswitchd/ovs-vswitchd.8.in @@ -98,7 +98,6 @@ configuration. .so lib/ssl-bootstrap.man .so lib/vlog.man .so lib/common.man -.so lib/leak-checker.man . .SH "RUNTIME MANAGEMENT COMMANDS" \fBovs\-appctl\fR(8) can send commands to a running diff --git a/vswitchd/ovs-vswitchd.c b/vswitchd/ovs-vswitchd.c index e11febd4d..80c8fedae 100644 --- a/vswitchd/ovs-vswitchd.c +++ b/vswitchd/ovs-vswitchd.c @@ -32,7 +32,6 @@ #include "dirs.h" #include "dpif.h" #include "dummy.h" -#include "leak-checker.h" #include "memory.h" #include "netdev.h" #include "openflow/openflow.h" @@ -152,7 +151,6 @@ parse_options(int argc, char *argv[], char **unixctl_pathp) OPT_MLOCKALL, OPT_UNIXCTL, VLOG_OPTION_ENUMS, - LEAK_CHECKER_OPTION_ENUMS, OPT_BOOTSTRAP_CA_CERT, OPT_ENABLE_DUMMY, OPT_DISABLE_SYSTEM, @@ -165,7 +163,6 @@ parse_options(int argc, char *argv[], char **unixctl_pathp) {"unixctl", required_argument, NULL, OPT_UNIXCTL}, DAEMON_LONG_OPTIONS, VLOG_LONG_OPTIONS, - LEAK_CHECKER_LONG_OPTIONS, STREAM_SSL_LONG_OPTIONS, {"peer-ca-cert", required_argument, NULL, OPT_PEER_CA_CERT}, {"bootstrap-ca-cert", required_argument, NULL, OPT_BOOTSTRAP_CA_CERT}, @@ -201,7 +198,6 @@ parse_options(int argc, char *argv[], char **unixctl_pathp) VLOG_OPTION_HANDLERS DAEMON_OPTION_HANDLERS - LEAK_CHECKER_OPTION_HANDLERS STREAM_SSL_OPTION_HANDLERS case OPT_PEER_CA_CERT: @@ -260,7 +256,6 @@ usage(void) " --unixctl=SOCKET override default control socket name\n" " -h, --help display this help message\n" " -V, --version display version information\n"); - leak_checker_usage(); exit(EXIT_SUCCESS); } diff --git a/xenserver/openvswitch-xen.spec.in b/xenserver/openvswitch-xen.spec.in index 4e8f57605..dff18d0b5 100644 --- a/xenserver/openvswitch-xen.spec.in +++ b/xenserver/openvswitch-xen.spec.in @@ -1,6 +1,6 @@ # Spec file for Open vSwitch. -# Copyright (C) 2009, 2010, 2011, 2012 Nicira, Inc. +# Copyright (C) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. # # Copying and distribution of this file, with or without modification, # are permitted in any medium without royalty provided the copyright @@ -428,7 +428,6 @@ exit 0 /usr/bin/ovs-dpctl /usr/bin/ovs-ofctl /usr/bin/ovs-parse-backtrace -/usr/bin/ovs-parse-leaks /usr/bin/ovs-pcap /usr/bin/ovs-tcpundump /usr/bin/ovs-vlan-test @@ -446,7 +445,6 @@ exit 0 /usr/share/man/man8/ovs-dpctl.8.gz /usr/share/man/man8/ovs-ofctl.8.gz /usr/share/man/man8/ovs-parse-backtrace.8.gz -/usr/share/man/man8/ovs-parse-leaks.8.gz /usr/share/man/man1/ovs-pcap.1.gz /usr/share/man/man1/ovs-tcpundump.1.gz /usr/share/man/man8/ovs-vlan-bug-workaround.8.gz