diff options
author | Eric Wong <e@80x24.org> | 2023-01-09 05:52:38 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2023-01-09 06:22:09 +0000 |
commit | 4106dfd813ce42678e0395eda42e36149d1ac851 (patch) | |
tree | 2d6c5c088b7ea4da6997604c9a4e6024208d1b9d | |
parent | ee995d418cc8cfcb148159d84c4f1d6f40108b6d (diff) | |
download | mwrap-4106dfd813ce42678e0395eda42e36149d1ac851.tar.gz |
FreeBSD 12.x doesn't seem to work with the `pkg install'-ed ruby
-rw-r--r-- | Documentation/.gitignore | 2 | ||||
-rw-r--r-- | Documentation/GNUmakefile | 63 | ||||
-rw-r--r-- | Documentation/mwrap.pod | 123 | ||||
-rw-r--r-- | MANIFEST | 4 | ||||
-rw-r--r-- | README | 38 | ||||
-rw-r--r-- | mwrap.gemspec | 11 |
6 files changed, 223 insertions, 18 deletions
diff --git a/Documentation/.gitignore b/Documentation/.gitignore new file mode 100644 index 0000000..1b0e502 --- /dev/null +++ b/Documentation/.gitignore @@ -0,0 +1,2 @@ +mwrap.txt +mwrap.1 diff --git a/Documentation/GNUmakefile b/Documentation/GNUmakefile new file mode 100644 index 0000000..14480da --- /dev/null +++ b/Documentation/GNUmakefile @@ -0,0 +1,63 @@ +# Copyright (C) all contributors <mwrap-public@80x24.org> +# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt> +all:: + +INSTALL = install +POD2MAN = pod2man +VERSION := $(shell cd .. && ./VERSION-GEN) +release := mwrap $(VERSION) +POD2MAN_OPTS = -v -r '$(release)' --stderr -d 1993-10-02 -c 'mwrap user manual' +pod2man = $(POD2MAN) $(POD2MAN_OPTS) +POD2TEXT = pod2text +POD2TEXT_OPTS = --stderr +pod2text = $(POD2TEXT) $(POD2TEXT_OPTS) + +m1 = mwrap +m5 = +m7 = + +man1 := $(addsuffix .1, $(m1)) +man5 := $(addsuffix .5, $(m5)) +man7 := $(addsuffix .7, $(m7)) + +all:: man + +man: $(man1) $(man5) $(man7) + +prefix ?= $(HOME) +mandir ?= $(prefix)/share/man +man1dir = $(mandir)/man1 +man5dir = $(mandir)/man5 +man7dir = $(mandir)/man7 + +gem-man: man + $(INSTALL) -d -m 755 ../man + test -z "$(man1)" || $(INSTALL) -m 644 $(man1) ../man + test -z "$(man5)" || $(INSTALL) -m 644 $(man5) ../man + test -z "$(man7)" || $(INSTALL) -m 644 $(man7) ../man + +install-man: man + $(INSTALL) -d -m 755 $(DESTDIR)$(man1dir) + $(INSTALL) -d -m 755 $(DESTDIR)$(man5dir) + test -z "$(man7)" || $(INSTALL) -d -m 755 $(DESTDIR)$(man7dir) + $(INSTALL) -m 644 $(man1) $(DESTDIR)$(man1dir) + $(INSTALL) -m 644 $(man5) $(DESTDIR)$(man5dir) + test -z "$(man7)" || $(INSTALL) -m 644 $(man7) $(DESTDIR)$(man7dir) + +%.1 %.5 %.7 : %.pod + $(pod2man) -s $(subst .,,$(suffix $@)) $< $@+ && mv $@+ $@ + +mantxt = $(addsuffix .txt, $(m1) $(m5) $(m7)) + +txt :: $(mantxt) + +all :: txt + +%.txt : %.pod + $(pod2text) $< $@+ + touch -r $< $@+ + mv $@+ $@ + +clean:: + $(RM) $(man1) $(man5) $(man7) + $(RM) $(addsuffix .txt.gz, $(m1) $(m5) $(m7)) diff --git a/Documentation/mwrap.pod b/Documentation/mwrap.pod new file mode 100644 index 0000000..6832430 --- /dev/null +++ b/Documentation/mwrap.pod @@ -0,0 +1,123 @@ +=head1 NAME + +mwrap - run any command under mwrap + +=head1 SYNOPSIS + + # to trace a long-running program and access it via $DIR/$PID.sock: + MWRAP=socket_dir:$DIR mwrap COMMAND + + # to trace a short-lived command and dump its output to a log: + MWRAP=dump_path:$FILENAME mwrap COMMAND + +=head1 DESCRIPTION + +mwrap is a command-line to automatically add mwrap.so as an +LD_PRELOAD for any command. It will resolve malloc-family calls +to a Ruby file and line number, and it can also provide a backtrace +of native (C/C++) functions for non-Ruby programs. + +=head1 ENVIRONMENT + +C<MWRAP> is the only environment variable read. It contains multiple +options delimited by C<,> with names and values delimited by C<:> + +=over 4 + +=item socket_dir:$DIR + +This launches an embedded HTTP server in each process and binds it +to C<$DIR/$PID.sock>. C<curl --unix-socket $DIR/$PID.sock> +or L<mwrap-rproxy(1p)> (from L<https://80x24.org/mwrap-perl.git>) may +be used to access various endpoints in the HTTP server. + +=item bt:$DEPTH + +The backtrace depth for L<backtrace(3)> in addition to the Perl +file and line number where C<$DEPTH> is a non-negative number. + +The maximum allowed value is 32, though values of 5 or less are +typically useful. Increasing this to even 2 or 3 can significantly +increase the amount of memory mwrap (and liburcu) itself uses. + +This is only useful in conjunction with C<socket_dir> + +This may be changed via POST request (see below). + +Default: 0 + +=item dump_path:$FILENAME + +Dumps the output at exit to a given filename: + + total_bytes call_count location + +In the future, dumping to a self-describing CSV will be supported. + +=item dump_fd:$DESCRIPTOR + +As with dump_path, but dumps the output to a given file descriptor. + +=back + +=head1 HTTP POST API + +In addition to the various GET endpoints linked via C<http://0/$PID/>, +there are some POST endpoints which are typically accessed via +C<curl --unix-socket $DIR/$PID.sock> + +=over 4 + +=item POST http://0/$PID/reset + +C<curl --unix-socket $DIR/$PID.sock -XPOST http://0/$PID/reset> + +Reset all internal counters. This is not done atomically and does +not release any memory. + +=item POST http://0/$PID/trim + +C<curl --unix-socket $DIR/$PID.sock -XPOST http://0/$PID/trim> + +Runs L<malloc_trim(3)> with a 0 pad value to release unused memory +back to the kernel. In our malloc implementation, this is done +lazily to avoid contention and does not happen unless sleeping threads. + +=item POST http://0/$PID/ctl + +Set various internal knobs. Currently, C<X-Mwrap-BT> is the +only knob supported: + +C<curl --unix-socket $DIR/$PID.sock -XPOST -HX-Mwrap-BT:1 http://0/$PID/ctl> + +Using the C<X-Mwrap-BT> header allows changing the aforementioned +C<bt:> value to a specified depth level. As with C<bt:>, only make small +adjustments as the memory cost can increase exponentially with each step. + +It is typically a good idea to reset (C<http://0/$PID/reset>) after changing +the depth on a running process. + +Headers other than C<X-Mwrap-BT> may be accepted in the future to +tweak other settings. + +=back + +=head1 CONTACT + +Feedback welcome via plain-text mail to L<mailto:mwrap-public@80x24.org> + +Mail archives are hosted at L<https://80x24.org/mwrap-public/> + +=head1 COPYRIGHT + +Copyright all contributors L<mailto:mwrap-public@80x24.org> + +License: GPL-3.0+ L<https://www.gnu.org/licenses/gpl-3.0.txt> + +Source code is at L<https://80x24.org/mwrap.git/> + +=head1 SEE ALSO + +L<mwrap-rproxy(1)>, L<Devel::Mwrap(3pm)>, L<https://80x24.org/mwrap-perl.git> + +=cut @@ -2,6 +2,9 @@ .gitignore .olddoc.yml COPYING +Documentation/.gitignore +Documentation/GNUmakefile +Documentation/mwrap.pod MANIFEST README Rakefile @@ -24,4 +27,3 @@ mwrap.gemspec t/httpd.t t/test_common.perl test/test_mwrap.rb -lib/mwrap/version.rb @@ -8,8 +8,8 @@ mwrap wraps all malloc-family calls to trace the Ruby source location of such calls and bytes allocated at each callsite. As of mwrap 2.0.0, it can also function as a leak detector and show live allocations at every call site. Depending on -your application and workload, the overhead is roughly a 50% -increase memory and runtime. +your application and workload, the overhead is roughly a 50-100% +increase memory and runtime with default settings. It works best for allocations under GVL, but tries to track numeric caller addresses for allocations made without GVL so you @@ -22,15 +22,13 @@ Userspace RCU project: https://liburcu.org/ It does not require recompiling or rebuilding Ruby, but only supports Ruby 2.7.0 or later on a few platforms: -* GNU/Linux -* FreeBSD +* GNU/Linux (only tested --without-jemalloc, mwrap 3.x provides its own) -It may work on NetBSD, OpenBSD and DragonFly BSD. +It may work on FreeBSD, NetBSD, OpenBSD and DragonFly BSD if given +appropriate build options. == Install - # FreeBSD: pkg install liburcu - # Debian-based systems: apt-get liburcu-dev # Install mwrap via RubyGems.org @@ -64,24 +62,33 @@ or an address retrieved by backtrace_symbols(3). It is recommended to use the sort(1) command on either of the first two columns to find the hottest malloc locations. -mwrap 2.0.0+ also supports a Rack application endpoint, +mwrap 3.0.0+ also supports an embedded HTTP server it is documented at: -https://80x24.org/mwrap/MwrapRack.html +https://80x24.org/mwrap.git/tree/Documentation/mwrap.pod == Known problems * 32-bit machines are prone to overflow (WONTFIX) -== Public mail archives and contact info: +* signalfd(2)-reliant code will need latest URCU with commit + ea3a28a3f71dd02f (Disable signals in URCU background threads, 2022-09-23) + This doesn't affect C Ruby itself, and signalfd(2) use is rare + 3rd-party processes. + +* Ruby source files over 16.7 million lines long are not supported :P + +== Public mail archives (HTTP, Atom feeds, IMAP mailbox, NNTP group, POP3): * https://80x24.org/mwrap-public/ * nntps://80x24.org/inbox.comp.lang.ruby.mwrap * imaps://;AUTH=ANONYMOUS@80x24.org/inbox.comp.lang.ruby.mwrap.0 * https://80x24.org/mwrap-public/_/text/help/#pop3 -No subscription will ever be required to post, but HTML mail -will be rejected: +No subscription nor real identities will ever be required to obtain support, +but HTML mail is rejected. Memory usage reductions start with you; +only send plain-text mail to us and do not top-post. HTML mail and +top-posting costs everybody memory and bandwidth. mwrap-public@80x24.org @@ -89,9 +96,10 @@ will be rejected: git clone https://80x24.org/mwrap.git -Send all patches and pull requests (use "git request-pull" to format) to -mwrap-public@80x24.org. We do not use centralized or proprietary messaging -systems. +Send all patches ("git format-patch" + "git send-email") and +pull requests (use "git request-pull" to format) via email +to mwrap-perl@80x24.org. We do not and will not use +proprietary messaging systems. == License diff --git a/mwrap.gemspec b/mwrap.gemspec index dc99924..b6f9e71 100644 --- a/mwrap.gemspec +++ b/mwrap.gemspec @@ -1,6 +1,5 @@ git_manifest = `git ls-files 2>/dev/null`.split("\n") git_ok = $?.success? -git_manifest << 'lib/mwrap/version.rb'.freeze # generated by ./VERSION-GEN manifest = File.exist?('MANIFEST') ? File.readlines('MANIFEST').map!(&:chomp).delete_if(&:empty?) : git_manifest if git_ok && manifest != git_manifest @@ -12,11 +11,19 @@ end version = `./VERSION-GEN`.chomp $?.success? or abort './VERSION-GEN failed' +manifest << 'lib/mwrap/version.rb'.freeze + +if system(*%w(make -C Documentation man)) || + system(*%w(gmake -C Documentation man)) + manifest.concat(%w(Documentation/mwrap.1)) +else + warn 'failed to build man-page(s), proceeding without them' +end Gem::Specification.new do |s| s.name = 'mwrap' s.version = version - s.homepage = 'https://80x24.org/mwrap/' + s.homepage = 'https://80x24.org/mwrap.git/' s.authors = ["mwrap hackers"] s.summary = 'LD_PRELOAD malloc wrapper for Ruby' s.executables = %w(mwrap) |