Acked-by: Ethan Jackson <[email protected]>
On Thu, Jun 13, 2013 at 5:16 PM, Ben Pfaff <[email protected]> wrote: > 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 <[email protected]> > --- > debian/openvswitch-common.install | 1 - > debian/openvswitch-common.manpages | 1 - > lib/automake.mk | 3 - > lib/leak-checker.c | 243 ----------------------------- > lib/leak-checker.h | 41 ----- > lib/leak-checker.man | 15 -- > lib/stream-fd.c | 1 - > lib/stream-ssl.c | 2 - > lib/vconn-stream.c | 2 - > manpages.mk | 2 - > ovsdb/ovsdb-server.c | 5 - > rhel/openvswitch-fedora.spec.in | 4 +- > rhel/openvswitch.spec.in | 4 +- > utilities/.gitignore | 1 - > utilities/automake.mk | 6 +- > utilities/ovs-parse-leaks.8 | 35 ---- > utilities/ovs-parse-leaks.in | 299 > ------------------------------------ > vswitchd/ovs-vswitchd.8.in | 1 - > vswitchd/ovs-vswitchd.c | 5 - > xenserver/openvswitch-xen.spec.in | 4 +- > 20 files changed, 4 insertions(+), 671 deletions(-) > delete mode 100644 lib/leak-checker.c > delete mode 100644 lib/leak-checker.h > delete mode 100644 lib/leak-checker.man > delete mode 100644 utilities/ovs-parse-leaks.8 > delete mode 100755 utilities/ovs-parse-leaks.in > > diff --git a/debian/openvswitch-common.install > b/debian/openvswitch-common.install > index e2c0454..f2a0d48 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 5969677..a219722 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 bcaa1f8..8b4cd92 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 1fd3d5b..0000000 > --- 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 <config.h> > -#include "leak-checker.h" > -#include <inttypes.h> > -#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 <errno.h> > -#include <fcntl.h> > -#include <malloc.h> > -#include <sys/stat.h> > - > -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 e74cd9d..0000000 > --- 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 <sys/types.h> > - > -#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 beba9e1..0000000 > --- 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 90d328a..df5e8b0 100644 > --- a/lib/stream-fd.c > +++ b/lib/stream-fd.c > @@ -24,7 +24,6 @@ > #include <sys/types.h> > #include <unistd.h> > #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 5caac49..c373ca9 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 e91d92c..08ec7bf 100644 > --- a/lib/vconn-stream.c > +++ b/lib/vconn-stream.c > @@ -22,7 +22,6 @@ > #include <sys/types.h> > #include <unistd.h> > #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 a14f968..ed0d999 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 394f5a5..b31560b 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 6c225f7..dc40403 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 9f40881..53512bc 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 ad99dda..a0bd97f 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 ab8774a..797748c 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 e7bd1c5..0000000 > --- 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 72417e5..0000000 > --- 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 <<EOF; > -$0, for parsing leak checker logs > -usage: $0 [BINARY] < LOG > -where LOG is a file produced by an Open vSwitch program's --check-leaks > option > - and BINARY is the binary that wrote LOG. > -EOF > - exit 0; > -} > - > -die "$0: zero or one arguments required; use --help for help\n" if @ARGV > 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 (<STDIN>) { > - 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 = <A2L>); > - chomp(my $line = <A2L>); > - 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 (<OBJDUMP>) { > - 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 = <A2L>); > - chomp(my $line = <A2L>); > - 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 efa4c7e..86500c9 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 e11febd..80c8fed 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 4e8f576..dff18d0 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 > -- > 1.7.2.5 > > _______________________________________________ > dev mailing list > [email protected] > http://openvswitch.org/mailman/listinfo/dev _______________________________________________ dev mailing list [email protected] http://openvswitch.org/mailman/listinfo/dev
