about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2023-01-09 05:52:38 +0000
committerEric Wong <e@80x24.org>2023-01-09 06:22:09 +0000
commit4106dfd813ce42678e0395eda42e36149d1ac851 (patch)
tree2d6c5c088b7ea4da6997604c9a4e6024208d1b9d
parentee995d418cc8cfcb148159d84c4f1d6f40108b6d (diff)
downloadmwrap-4106dfd813ce42678e0395eda42e36149d1ac851.tar.gz
FreeBSD 12.x doesn't seem to work with the `pkg install'-ed
ruby
-rw-r--r--Documentation/.gitignore2
-rw-r--r--Documentation/GNUmakefile63
-rw-r--r--Documentation/mwrap.pod123
-rw-r--r--MANIFEST4
-rw-r--r--README38
-rw-r--r--mwrap.gemspec11
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
diff --git a/MANIFEST b/MANIFEST
index 4c5be8b..8d4cdd6 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -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
diff --git a/README b/README
index 382c5a0..761f87e 100644
--- a/README
+++ b/README
@@ -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)