mwrap 2.2.0.1.g867b → 3.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/COPYING +617 -282
- data/Documentation/.gitignore +2 -0
- data/Documentation/GNUmakefile +63 -0
- data/Documentation/mwrap.1 +242 -0
- data/Documentation/mwrap.pod +123 -0
- data/MANIFEST +15 -0
- data/README +25 -17
- data/Rakefile +10 -2
- data/VERSION-GEN +36 -0
- data/bin/mwrap +19 -0
- data/ext/mwrap/check.h +23 -0
- data/ext/mwrap/dlmalloc_c.h +6294 -0
- data/ext/mwrap/extconf.rb +7 -11
- data/ext/mwrap/gcc.h +13 -0
- data/ext/mwrap/httpd.h +1367 -0
- data/ext/mwrap/mwrap.c +44 -1138
- data/ext/mwrap/mwrap_core.h +1095 -0
- data/ext/mwrap/mymalloc.h +299 -0
- data/ext/mwrap/picohttpparser.h +92 -0
- data/ext/mwrap/picohttpparser_c.h +670 -0
- data/lib/mwrap/.gitignore +1 -0
- data/lib/mwrap/version.rb +1 -0
- data/lib/mwrap_rack.rb +14 -58
- data/mwrap.gemspec +15 -5
- data/t/httpd.t +191 -0
- data/t/test_common.perl +54 -0
- data/test/test_mwrap.rb +34 -50
- metadata +22 -5
@@ -0,0 +1,63 @@
|
|
1
|
+
# Copyright (C) all contributors <mwrap-public@80x24.org>
|
2
|
+
# License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
|
3
|
+
all::
|
4
|
+
|
5
|
+
INSTALL = install
|
6
|
+
POD2MAN = pod2man
|
7
|
+
VERSION := $(shell cd .. && ./VERSION-GEN)
|
8
|
+
release := mwrap $(VERSION)
|
9
|
+
POD2MAN_OPTS = -v -r '$(release)' --stderr -d 1993-10-02 -c 'mwrap user manual'
|
10
|
+
pod2man = $(POD2MAN) $(POD2MAN_OPTS)
|
11
|
+
POD2TEXT = pod2text
|
12
|
+
POD2TEXT_OPTS = --stderr
|
13
|
+
pod2text = $(POD2TEXT) $(POD2TEXT_OPTS)
|
14
|
+
|
15
|
+
m1 = mwrap
|
16
|
+
m5 =
|
17
|
+
m7 =
|
18
|
+
|
19
|
+
man1 := $(addsuffix .1, $(m1))
|
20
|
+
man5 := $(addsuffix .5, $(m5))
|
21
|
+
man7 := $(addsuffix .7, $(m7))
|
22
|
+
|
23
|
+
all:: man
|
24
|
+
|
25
|
+
man: $(man1) $(man5) $(man7)
|
26
|
+
|
27
|
+
prefix ?= $(HOME)
|
28
|
+
mandir ?= $(prefix)/share/man
|
29
|
+
man1dir = $(mandir)/man1
|
30
|
+
man5dir = $(mandir)/man5
|
31
|
+
man7dir = $(mandir)/man7
|
32
|
+
|
33
|
+
gem-man: man
|
34
|
+
$(INSTALL) -d -m 755 ../man
|
35
|
+
test -z "$(man1)" || $(INSTALL) -m 644 $(man1) ../man
|
36
|
+
test -z "$(man5)" || $(INSTALL) -m 644 $(man5) ../man
|
37
|
+
test -z "$(man7)" || $(INSTALL) -m 644 $(man7) ../man
|
38
|
+
|
39
|
+
install-man: man
|
40
|
+
$(INSTALL) -d -m 755 $(DESTDIR)$(man1dir)
|
41
|
+
$(INSTALL) -d -m 755 $(DESTDIR)$(man5dir)
|
42
|
+
test -z "$(man7)" || $(INSTALL) -d -m 755 $(DESTDIR)$(man7dir)
|
43
|
+
$(INSTALL) -m 644 $(man1) $(DESTDIR)$(man1dir)
|
44
|
+
$(INSTALL) -m 644 $(man5) $(DESTDIR)$(man5dir)
|
45
|
+
test -z "$(man7)" || $(INSTALL) -m 644 $(man7) $(DESTDIR)$(man7dir)
|
46
|
+
|
47
|
+
%.1 %.5 %.7 : %.pod
|
48
|
+
$(pod2man) -s $(subst .,,$(suffix $@)) $< $@+ && mv $@+ $@
|
49
|
+
|
50
|
+
mantxt = $(addsuffix .txt, $(m1) $(m5) $(m7))
|
51
|
+
|
52
|
+
txt :: $(mantxt)
|
53
|
+
|
54
|
+
all :: txt
|
55
|
+
|
56
|
+
%.txt : %.pod
|
57
|
+
$(pod2text) $< $@+
|
58
|
+
touch -r $< $@+
|
59
|
+
mv $@+ $@
|
60
|
+
|
61
|
+
clean::
|
62
|
+
$(RM) $(man1) $(man5) $(man7)
|
63
|
+
$(RM) $(addsuffix .txt.gz, $(m1) $(m5) $(m7))
|
@@ -0,0 +1,242 @@
|
|
1
|
+
.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40)
|
2
|
+
.\"
|
3
|
+
.\" Standard preamble:
|
4
|
+
.\" ========================================================================
|
5
|
+
.de Sp \" Vertical space (when we can't use .PP)
|
6
|
+
.if t .sp .5v
|
7
|
+
.if n .sp
|
8
|
+
..
|
9
|
+
.de Vb \" Begin verbatim text
|
10
|
+
.ft CW
|
11
|
+
.nf
|
12
|
+
.ne \\$1
|
13
|
+
..
|
14
|
+
.de Ve \" End verbatim text
|
15
|
+
.ft R
|
16
|
+
.fi
|
17
|
+
..
|
18
|
+
.\" Set up some character translations and predefined strings. \*(-- will
|
19
|
+
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
|
20
|
+
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
|
21
|
+
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
|
22
|
+
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
|
23
|
+
.\" nothing in troff, for use with C<>.
|
24
|
+
.tr \(*W-
|
25
|
+
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
|
26
|
+
.ie n \{\
|
27
|
+
. ds -- \(*W-
|
28
|
+
. ds PI pi
|
29
|
+
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
|
30
|
+
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
|
31
|
+
. ds L" ""
|
32
|
+
. ds R" ""
|
33
|
+
. ds C` ""
|
34
|
+
. ds C' ""
|
35
|
+
'br\}
|
36
|
+
.el\{\
|
37
|
+
. ds -- \|\(em\|
|
38
|
+
. ds PI \(*p
|
39
|
+
. ds L" ``
|
40
|
+
. ds R" ''
|
41
|
+
. ds C`
|
42
|
+
. ds C'
|
43
|
+
'br\}
|
44
|
+
.\"
|
45
|
+
.\" Escape single quotes in literal strings from groff's Unicode transform.
|
46
|
+
.ie \n(.g .ds Aq \(aq
|
47
|
+
.el .ds Aq '
|
48
|
+
.\"
|
49
|
+
.\" If the F register is >0, we'll generate index entries on stderr for
|
50
|
+
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
|
51
|
+
.\" entries marked with X<> in POD. Of course, you'll have to process the
|
52
|
+
.\" output yourself in some meaningful fashion.
|
53
|
+
.\"
|
54
|
+
.\" Avoid warning from groff about undefined register 'F'.
|
55
|
+
.de IX
|
56
|
+
..
|
57
|
+
.nr rF 0
|
58
|
+
.if \n(.g .if rF .nr rF 1
|
59
|
+
.if (\n(rF:(\n(.g==0)) \{\
|
60
|
+
. if \nF \{\
|
61
|
+
. de IX
|
62
|
+
. tm Index:\\$1\t\\n%\t"\\$2"
|
63
|
+
..
|
64
|
+
. if !\nF==2 \{\
|
65
|
+
. nr % 0
|
66
|
+
. nr F 2
|
67
|
+
. \}
|
68
|
+
. \}
|
69
|
+
.\}
|
70
|
+
.rr rF
|
71
|
+
.\"
|
72
|
+
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
|
73
|
+
.\" Fear. Run. Save yourself. No user-serviceable parts.
|
74
|
+
. \" fudge factors for nroff and troff
|
75
|
+
.if n \{\
|
76
|
+
. ds #H 0
|
77
|
+
. ds #V .8m
|
78
|
+
. ds #F .3m
|
79
|
+
. ds #[ \f1
|
80
|
+
. ds #] \fP
|
81
|
+
.\}
|
82
|
+
.if t \{\
|
83
|
+
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
|
84
|
+
. ds #V .6m
|
85
|
+
. ds #F 0
|
86
|
+
. ds #[ \&
|
87
|
+
. ds #] \&
|
88
|
+
.\}
|
89
|
+
. \" simple accents for nroff and troff
|
90
|
+
.if n \{\
|
91
|
+
. ds ' \&
|
92
|
+
. ds ` \&
|
93
|
+
. ds ^ \&
|
94
|
+
. ds , \&
|
95
|
+
. ds ~ ~
|
96
|
+
. ds /
|
97
|
+
.\}
|
98
|
+
.if t \{\
|
99
|
+
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
|
100
|
+
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
|
101
|
+
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
|
102
|
+
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
|
103
|
+
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
|
104
|
+
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
|
105
|
+
.\}
|
106
|
+
. \" troff and (daisy-wheel) nroff accents
|
107
|
+
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
|
108
|
+
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
|
109
|
+
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
|
110
|
+
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
|
111
|
+
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
|
112
|
+
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
|
113
|
+
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
|
114
|
+
.ds ae a\h'-(\w'a'u*4/10)'e
|
115
|
+
.ds Ae A\h'-(\w'A'u*4/10)'E
|
116
|
+
. \" corrections for vroff
|
117
|
+
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
|
118
|
+
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
|
119
|
+
. \" for low resolution devices (crt and lpr)
|
120
|
+
.if \n(.H>23 .if \n(.V>19 \
|
121
|
+
\{\
|
122
|
+
. ds : e
|
123
|
+
. ds 8 ss
|
124
|
+
. ds o a
|
125
|
+
. ds d- d\h'-1'\(ga
|
126
|
+
. ds D- D\h'-1'\(hy
|
127
|
+
. ds th \o'bp'
|
128
|
+
. ds Th \o'LP'
|
129
|
+
. ds ae ae
|
130
|
+
. ds Ae AE
|
131
|
+
.\}
|
132
|
+
.rm #[ #] #H #V #F C
|
133
|
+
.\" ========================================================================
|
134
|
+
.\"
|
135
|
+
.IX Title "MWRAP 1"
|
136
|
+
.TH MWRAP 1 "1993-10-02" "mwrap 2.3.0.155.g0de44f7" "mwrap user manual"
|
137
|
+
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
138
|
+
.\" way too many mistakes in technical documents.
|
139
|
+
.if n .ad l
|
140
|
+
.nh
|
141
|
+
.SH "NAME"
|
142
|
+
mwrap \- run any command under mwrap
|
143
|
+
.SH "SYNOPSIS"
|
144
|
+
.IX Header "SYNOPSIS"
|
145
|
+
.Vb 2
|
146
|
+
\& # to trace a long\-running program and access it via $DIR/$PID.sock:
|
147
|
+
\& MWRAP=socket_dir:$DIR mwrap COMMAND
|
148
|
+
\&
|
149
|
+
\& # to trace a short\-lived command and dump its output to a log:
|
150
|
+
\& MWRAP=dump_path:$FILENAME mwrap COMMAND
|
151
|
+
.Ve
|
152
|
+
.SH "DESCRIPTION"
|
153
|
+
.IX Header "DESCRIPTION"
|
154
|
+
mwrap is a command-line to automatically add mwrap.so as an
|
155
|
+
\&\s-1LD_PRELOAD\s0 for any command. It will resolve malloc-family calls
|
156
|
+
to a Ruby file and line number, and it can also provide a backtrace
|
157
|
+
of native (C/\*(C+) functions for non-Ruby programs.
|
158
|
+
.SH "ENVIRONMENT"
|
159
|
+
.IX Header "ENVIRONMENT"
|
160
|
+
\&\f(CW\*(C`MWRAP\*(C'\fR is the only environment variable read. It contains multiple
|
161
|
+
options delimited by \f(CW\*(C`,\*(C'\fR with names and values delimited by \f(CW\*(C`:\*(C'\fR
|
162
|
+
.IP "socket_dir:$DIR" 4
|
163
|
+
.IX Item "socket_dir:$DIR"
|
164
|
+
This launches an embedded \s-1HTTP\s0 server in each process and binds it
|
165
|
+
to \f(CW\*(C`$DIR/$PID.sock\*(C'\fR. \f(CW\*(C`curl \-\-unix\-socket $DIR/$PID.sock\*(C'\fR
|
166
|
+
or \fBmwrap\-rproxy\fR\|(1p) (from <https://80x24.org/mwrap\-perl.git>) may
|
167
|
+
be used to access various endpoints in the \s-1HTTP\s0 server.
|
168
|
+
.IP "bt:$DEPTH" 4
|
169
|
+
.IX Item "bt:$DEPTH"
|
170
|
+
The backtrace depth for \fBbacktrace\fR\|(3) in addition to the Perl
|
171
|
+
file and line number where \f(CW$DEPTH\fR is a non-negative number.
|
172
|
+
.Sp
|
173
|
+
The maximum allowed value is 32, though values of 5 or less are
|
174
|
+
typically useful. Increasing this to even 2 or 3 can significantly
|
175
|
+
increase the amount of memory mwrap (and liburcu) itself uses.
|
176
|
+
.Sp
|
177
|
+
This is only useful in conjunction with \f(CW\*(C`socket_dir\*(C'\fR
|
178
|
+
.Sp
|
179
|
+
This may be changed via \s-1POST\s0 request (see below).
|
180
|
+
.Sp
|
181
|
+
Default: 0
|
182
|
+
.IP "dump_path:$FILENAME" 4
|
183
|
+
.IX Item "dump_path:$FILENAME"
|
184
|
+
Dumps the output at exit to a given filename:
|
185
|
+
.Sp
|
186
|
+
.Vb 1
|
187
|
+
\& total_bytes call_count location
|
188
|
+
.Ve
|
189
|
+
.Sp
|
190
|
+
In the future, dumping to a self-describing \s-1CSV\s0 will be supported.
|
191
|
+
.IP "dump_fd:$DESCRIPTOR" 4
|
192
|
+
.IX Item "dump_fd:$DESCRIPTOR"
|
193
|
+
As with dump_path, but dumps the output to a given file descriptor.
|
194
|
+
.SH "HTTP POST API"
|
195
|
+
.IX Header "HTTP POST API"
|
196
|
+
In addition to the various \s-1GET\s0 endpoints linked via \f(CW\*(C`http://0/$PID/\*(C'\fR,
|
197
|
+
there are some \s-1POST\s0 endpoints which are typically accessed via
|
198
|
+
\&\f(CW\*(C`curl \-\-unix\-socket $DIR/$PID.sock\*(C'\fR
|
199
|
+
.IP "\s-1POST\s0 http://0/$PID/reset" 4
|
200
|
+
.IX Item "POST http://0/$PID/reset"
|
201
|
+
\&\f(CW\*(C`curl \-\-unix\-socket $DIR/$PID.sock \-XPOST http://0/$PID/reset\*(C'\fR
|
202
|
+
.Sp
|
203
|
+
Reset all internal counters. This is not done atomically and does
|
204
|
+
not release any memory.
|
205
|
+
.IP "\s-1POST\s0 http://0/$PID/trim" 4
|
206
|
+
.IX Item "POST http://0/$PID/trim"
|
207
|
+
\&\f(CW\*(C`curl \-\-unix\-socket $DIR/$PID.sock \-XPOST http://0/$PID/trim\*(C'\fR
|
208
|
+
.Sp
|
209
|
+
Runs \fBmalloc_trim\fR\|(3) with a 0 pad value to release unused memory
|
210
|
+
back to the kernel. In our malloc implementation, this is done
|
211
|
+
lazily to avoid contention and does not happen unless sleeping threads.
|
212
|
+
.IP "\s-1POST\s0 http://0/$PID/ctl" 4
|
213
|
+
.IX Item "POST http://0/$PID/ctl"
|
214
|
+
Set various internal knobs. Currently, \f(CW\*(C`X\-Mwrap\-BT\*(C'\fR is the
|
215
|
+
only knob supported:
|
216
|
+
.Sp
|
217
|
+
\&\f(CW\*(C`curl \-\-unix\-socket $DIR/$PID.sock \-XPOST \-HX\-Mwrap\-BT:1 http://0/$PID/ctl\*(C'\fR
|
218
|
+
.Sp
|
219
|
+
Using the \f(CW\*(C`X\-Mwrap\-BT\*(C'\fR header allows changing the aforementioned
|
220
|
+
\&\f(CW\*(C`bt:\*(C'\fR value to a specified depth level. As with \f(CW\*(C`bt:\*(C'\fR, only make small
|
221
|
+
adjustments as the memory cost can increase exponentially with each step.
|
222
|
+
.Sp
|
223
|
+
It is typically a good idea to reset (\f(CW\*(C`http://0/$PID/reset\*(C'\fR) after changing
|
224
|
+
the depth on a running process.
|
225
|
+
.Sp
|
226
|
+
Headers other than \f(CW\*(C`X\-Mwrap\-BT\*(C'\fR may be accepted in the future to
|
227
|
+
tweak other settings.
|
228
|
+
.SH "CONTACT"
|
229
|
+
.IX Header "CONTACT"
|
230
|
+
Feedback welcome via plain-text mail to <mailto:mwrap\-public@80x24.org>
|
231
|
+
.PP
|
232
|
+
Mail archives are hosted at <https://80x24.org/mwrap\-public/>
|
233
|
+
.SH "COPYRIGHT"
|
234
|
+
.IX Header "COPYRIGHT"
|
235
|
+
Copyright all contributors <mailto:mwrap\-public@80x24.org>
|
236
|
+
.PP
|
237
|
+
License: \s-1GPL\-3.0+\s0 <https://www.gnu.org/licenses/gpl\-3.0.txt>
|
238
|
+
.PP
|
239
|
+
Source code is at <https://80x24.org/mwrap.git/>
|
240
|
+
.SH "SEE ALSO"
|
241
|
+
.IX Header "SEE ALSO"
|
242
|
+
\&\fBmwrap\-rproxy\fR\|(1), \fBDevel::Mwrap\fR\|(3pm), <https://80x24.org/mwrap\-perl.git>
|
@@ -0,0 +1,123 @@
|
|
1
|
+
=head1 NAME
|
2
|
+
|
3
|
+
mwrap - run any command under mwrap
|
4
|
+
|
5
|
+
=head1 SYNOPSIS
|
6
|
+
|
7
|
+
# to trace a long-running program and access it via $DIR/$PID.sock:
|
8
|
+
MWRAP=socket_dir:$DIR mwrap COMMAND
|
9
|
+
|
10
|
+
# to trace a short-lived command and dump its output to a log:
|
11
|
+
MWRAP=dump_path:$FILENAME mwrap COMMAND
|
12
|
+
|
13
|
+
=head1 DESCRIPTION
|
14
|
+
|
15
|
+
mwrap is a command-line to automatically add mwrap.so as an
|
16
|
+
LD_PRELOAD for any command. It will resolve malloc-family calls
|
17
|
+
to a Ruby file and line number, and it can also provide a backtrace
|
18
|
+
of native (C/C++) functions for non-Ruby programs.
|
19
|
+
|
20
|
+
=head1 ENVIRONMENT
|
21
|
+
|
22
|
+
C<MWRAP> is the only environment variable read. It contains multiple
|
23
|
+
options delimited by C<,> with names and values delimited by C<:>
|
24
|
+
|
25
|
+
=over 4
|
26
|
+
|
27
|
+
=item socket_dir:$DIR
|
28
|
+
|
29
|
+
This launches an embedded HTTP server in each process and binds it
|
30
|
+
to C<$DIR/$PID.sock>. C<curl --unix-socket $DIR/$PID.sock>
|
31
|
+
or L<mwrap-rproxy(1p)> (from L<https://80x24.org/mwrap-perl.git>) may
|
32
|
+
be used to access various endpoints in the HTTP server.
|
33
|
+
|
34
|
+
=item bt:$DEPTH
|
35
|
+
|
36
|
+
The backtrace depth for L<backtrace(3)> in addition to the Perl
|
37
|
+
file and line number where C<$DEPTH> is a non-negative number.
|
38
|
+
|
39
|
+
The maximum allowed value is 32, though values of 5 or less are
|
40
|
+
typically useful. Increasing this to even 2 or 3 can significantly
|
41
|
+
increase the amount of memory mwrap (and liburcu) itself uses.
|
42
|
+
|
43
|
+
This is only useful in conjunction with C<socket_dir>
|
44
|
+
|
45
|
+
This may be changed via POST request (see below).
|
46
|
+
|
47
|
+
Default: 0
|
48
|
+
|
49
|
+
=item dump_path:$FILENAME
|
50
|
+
|
51
|
+
Dumps the output at exit to a given filename:
|
52
|
+
|
53
|
+
total_bytes call_count location
|
54
|
+
|
55
|
+
In the future, dumping to a self-describing CSV will be supported.
|
56
|
+
|
57
|
+
=item dump_fd:$DESCRIPTOR
|
58
|
+
|
59
|
+
As with dump_path, but dumps the output to a given file descriptor.
|
60
|
+
|
61
|
+
=back
|
62
|
+
|
63
|
+
=head1 HTTP POST API
|
64
|
+
|
65
|
+
In addition to the various GET endpoints linked via C<http://0/$PID/>,
|
66
|
+
there are some POST endpoints which are typically accessed via
|
67
|
+
C<curl --unix-socket $DIR/$PID.sock>
|
68
|
+
|
69
|
+
=over 4
|
70
|
+
|
71
|
+
=item POST http://0/$PID/reset
|
72
|
+
|
73
|
+
C<curl --unix-socket $DIR/$PID.sock -XPOST http://0/$PID/reset>
|
74
|
+
|
75
|
+
Reset all internal counters. This is not done atomically and does
|
76
|
+
not release any memory.
|
77
|
+
|
78
|
+
=item POST http://0/$PID/trim
|
79
|
+
|
80
|
+
C<curl --unix-socket $DIR/$PID.sock -XPOST http://0/$PID/trim>
|
81
|
+
|
82
|
+
Runs L<malloc_trim(3)> with a 0 pad value to release unused memory
|
83
|
+
back to the kernel. In our malloc implementation, this is done
|
84
|
+
lazily to avoid contention and does not happen unless sleeping threads.
|
85
|
+
|
86
|
+
=item POST http://0/$PID/ctl
|
87
|
+
|
88
|
+
Set various internal knobs. Currently, C<X-Mwrap-BT> is the
|
89
|
+
only knob supported:
|
90
|
+
|
91
|
+
C<curl --unix-socket $DIR/$PID.sock -XPOST -HX-Mwrap-BT:1 http://0/$PID/ctl>
|
92
|
+
|
93
|
+
Using the C<X-Mwrap-BT> header allows changing the aforementioned
|
94
|
+
C<bt:> value to a specified depth level. As with C<bt:>, only make small
|
95
|
+
adjustments as the memory cost can increase exponentially with each step.
|
96
|
+
|
97
|
+
It is typically a good idea to reset (C<http://0/$PID/reset>) after changing
|
98
|
+
the depth on a running process.
|
99
|
+
|
100
|
+
Headers other than C<X-Mwrap-BT> may be accepted in the future to
|
101
|
+
tweak other settings.
|
102
|
+
|
103
|
+
=back
|
104
|
+
|
105
|
+
=head1 CONTACT
|
106
|
+
|
107
|
+
Feedback welcome via plain-text mail to L<mailto:mwrap-public@80x24.org>
|
108
|
+
|
109
|
+
Mail archives are hosted at L<https://80x24.org/mwrap-public/>
|
110
|
+
|
111
|
+
=head1 COPYRIGHT
|
112
|
+
|
113
|
+
Copyright all contributors L<mailto:mwrap-public@80x24.org>
|
114
|
+
|
115
|
+
License: GPL-3.0+ L<https://www.gnu.org/licenses/gpl-3.0.txt>
|
116
|
+
|
117
|
+
Source code is at L<https://80x24.org/mwrap.git/>
|
118
|
+
|
119
|
+
=head1 SEE ALSO
|
120
|
+
|
121
|
+
L<mwrap-rproxy(1)>, L<Devel::Mwrap(3pm)>, L<https://80x24.org/mwrap-perl.git>
|
122
|
+
|
123
|
+
=cut
|
data/MANIFEST
CHANGED
@@ -2,13 +2,28 @@
|
|
2
2
|
.gitignore
|
3
3
|
.olddoc.yml
|
4
4
|
COPYING
|
5
|
+
Documentation/.gitignore
|
6
|
+
Documentation/GNUmakefile
|
7
|
+
Documentation/mwrap.pod
|
5
8
|
MANIFEST
|
6
9
|
README
|
7
10
|
Rakefile
|
11
|
+
VERSION-GEN
|
8
12
|
bin/mwrap
|
13
|
+
ext/mwrap/check.h
|
14
|
+
ext/mwrap/dlmalloc_c.h
|
9
15
|
ext/mwrap/extconf.rb
|
16
|
+
ext/mwrap/gcc.h
|
17
|
+
ext/mwrap/httpd.h
|
10
18
|
ext/mwrap/jhash.h
|
11
19
|
ext/mwrap/mwrap.c
|
20
|
+
ext/mwrap/mwrap_core.h
|
21
|
+
ext/mwrap/mymalloc.h
|
22
|
+
ext/mwrap/picohttpparser.h
|
23
|
+
ext/mwrap/picohttpparser_c.h
|
24
|
+
lib/mwrap/.gitignore
|
12
25
|
lib/mwrap_rack.rb
|
13
26
|
mwrap.gemspec
|
27
|
+
t/httpd.t
|
28
|
+
t/test_common.perl
|
14
29
|
test/test_mwrap.rb
|
data/README
CHANGED
@@ -8,8 +8,8 @@ mwrap wraps all malloc-family calls to trace the Ruby source
|
|
8
8
|
location of such calls and bytes allocated at each callsite.
|
9
9
|
As of mwrap 2.0.0, it can also function as a leak detector
|
10
10
|
and show live allocations at every call site. Depending on
|
11
|
-
your application and workload, the overhead is roughly a 50%
|
12
|
-
increase memory and runtime.
|
11
|
+
your application and workload, the overhead is roughly a 50-100%
|
12
|
+
increase memory and runtime with default settings.
|
13
13
|
|
14
14
|
It works best for allocations under GVL, but tries to track
|
15
15
|
numeric caller addresses for allocations made without GVL so you
|
@@ -20,17 +20,15 @@ It requires the concurrent lock-free hash table from the
|
|
20
20
|
Userspace RCU project: https://liburcu.org/
|
21
21
|
|
22
22
|
It does not require recompiling or rebuilding Ruby, but only
|
23
|
-
supports Ruby
|
23
|
+
supports Ruby 2.7.0 or later on a few platforms:
|
24
24
|
|
25
|
-
* GNU/Linux
|
26
|
-
* FreeBSD (tested 11.1)
|
25
|
+
* GNU/Linux (only tested --without-jemalloc, mwrap 3.x provides its own)
|
27
26
|
|
28
|
-
It may work on NetBSD, OpenBSD and DragonFly BSD
|
27
|
+
It may work on FreeBSD, NetBSD, OpenBSD and DragonFly BSD if given
|
28
|
+
appropriate build options.
|
29
29
|
|
30
30
|
== Install
|
31
31
|
|
32
|
-
# FreeBSD: pkg install liburcu
|
33
|
-
|
34
32
|
# Debian-based systems: apt-get liburcu-dev
|
35
33
|
|
36
34
|
# Install mwrap via RubyGems.org
|
@@ -64,24 +62,33 @@ or an address retrieved by backtrace_symbols(3). It is
|
|
64
62
|
recommended to use the sort(1) command on either of the
|
65
63
|
first two columns to find the hottest malloc locations.
|
66
64
|
|
67
|
-
mwrap
|
65
|
+
mwrap 3.0.0+ also supports an embedded HTTP server
|
68
66
|
it is documented at:
|
69
67
|
|
70
|
-
https://80x24.org/mwrap/
|
68
|
+
https://80x24.org/mwrap.git/tree/Documentation/mwrap.pod
|
71
69
|
|
72
70
|
== Known problems
|
73
71
|
|
74
72
|
* 32-bit machines are prone to overflow (WONTFIX)
|
75
73
|
|
76
|
-
|
74
|
+
* signalfd(2)-reliant code will need latest URCU with commit
|
75
|
+
ea3a28a3f71dd02f (Disable signals in URCU background threads, 2022-09-23)
|
76
|
+
This doesn't affect C Ruby itself, and signalfd(2) use is rare
|
77
|
+
3rd-party processes.
|
78
|
+
|
79
|
+
* Ruby source files over 16.7 million lines long are not supported :P
|
80
|
+
|
81
|
+
== Public mail archives (HTTP, Atom feeds, IMAP mailbox, NNTP group, POP3):
|
77
82
|
|
78
83
|
* https://80x24.org/mwrap-public/
|
79
84
|
* nntps://80x24.org/inbox.comp.lang.ruby.mwrap
|
80
85
|
* imaps://;AUTH=ANONYMOUS@80x24.org/inbox.comp.lang.ruby.mwrap.0
|
81
86
|
* https://80x24.org/mwrap-public/_/text/help/#pop3
|
82
87
|
|
83
|
-
No subscription will ever be required to
|
84
|
-
|
88
|
+
No subscription nor real identities will ever be required to obtain support,
|
89
|
+
but HTML mail is rejected. Memory usage reductions start with you;
|
90
|
+
only send plain-text mail to us and do not top-post. HTML mail and
|
91
|
+
top-posting costs everybody memory and bandwidth.
|
85
92
|
|
86
93
|
mwrap-public@80x24.org
|
87
94
|
|
@@ -89,10 +96,11 @@ will be rejected:
|
|
89
96
|
|
90
97
|
git clone https://80x24.org/mwrap.git
|
91
98
|
|
92
|
-
Send all patches
|
93
|
-
|
94
|
-
|
99
|
+
Send all patches ("git format-patch" + "git send-email") and
|
100
|
+
pull requests (use "git request-pull" to format) via email
|
101
|
+
to mwrap-perl@80x24.org. We do not and will not use
|
102
|
+
proprietary messaging systems.
|
95
103
|
|
96
104
|
== License
|
97
105
|
|
98
|
-
GPL-
|
106
|
+
GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
|
data/Rakefile
CHANGED
@@ -8,10 +8,18 @@ rescue LoadError
|
|
8
8
|
warn 'rake-compiler not available, cross compiling disabled'
|
9
9
|
end
|
10
10
|
|
11
|
-
Rake::TestTask.new(
|
12
|
-
task
|
11
|
+
Rake::TestTask.new('test-ruby')
|
12
|
+
task 'test-ruby' => :compile
|
13
13
|
task :default => :compile
|
14
14
|
|
15
|
+
task 'test-httpd': 'lib/mwrap.so' do
|
16
|
+
require 'rbconfig'
|
17
|
+
ENV['RUBY'] = RbConfig.ruby
|
18
|
+
sh "#{ENV['PROVE'] || 'prove'} -v"
|
19
|
+
end
|
20
|
+
|
21
|
+
task test: %w(test-ruby test-httpd)
|
22
|
+
|
15
23
|
c_files = File.readlines('MANIFEST').grep(%r{ext/.*\.[ch]$}).map!(&:chomp!)
|
16
24
|
task 'compile:mwrap' => c_files
|
17
25
|
|
data/VERSION-GEN
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
VF=lib/mwrap/version.rb
|
3
|
+
DEF_VER=v3.0.0-pre1
|
4
|
+
VN=$(git describe HEAD 2>/dev/null)
|
5
|
+
if test $? -eq 0
|
6
|
+
then
|
7
|
+
case "$VN" in
|
8
|
+
v[0-9]*)
|
9
|
+
set -e
|
10
|
+
git update-index -q --refresh
|
11
|
+
set +e
|
12
|
+
git diff-index --quiet HEAD -- || VN="$VN-dirty"
|
13
|
+
set -e
|
14
|
+
VN=$(echo $VN | tr '-' '.')
|
15
|
+
;;
|
16
|
+
esac
|
17
|
+
fi
|
18
|
+
set -e
|
19
|
+
|
20
|
+
case $VN in
|
21
|
+
'') VN="$DEF_VER" ;;
|
22
|
+
esac
|
23
|
+
|
24
|
+
VN=$(expr "$VN" : v*'\(.*\)')
|
25
|
+
VC=unset
|
26
|
+
if test -r $VF
|
27
|
+
then
|
28
|
+
VC="$(cat $VF)"
|
29
|
+
fi
|
30
|
+
|
31
|
+
new="module Mwrap; VERSION = '$VN'.freeze; end"
|
32
|
+
if test x"$new" != x"$VC"
|
33
|
+
then
|
34
|
+
echo "$new" >$VF
|
35
|
+
fi
|
36
|
+
echo $VN
|
data/bin/mwrap
CHANGED
@@ -2,6 +2,25 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
# Copyright (C) mwrap hackers <mwrap-public@80x24.org>
|
4
4
|
# License: GPL-2.0+ <https://www.gnu.org/licenses/gpl-2.0.txt>
|
5
|
+
help = <<EOM
|
6
|
+
usage: mwrap COMMAND [ARGS]
|
7
|
+
see https://80x24.org/mwrap/README.html for more info
|
8
|
+
EOM
|
9
|
+
ARGV.empty? and abort help
|
10
|
+
ARGV.each do |x|
|
11
|
+
case x
|
12
|
+
when '--version', '-v'
|
13
|
+
require 'mwrap/version'
|
14
|
+
puts "mwrap #{Mwrap::VERSION} - #{RUBY_DESCRIPTION}"
|
15
|
+
exit 0
|
16
|
+
when '--help', '-h'
|
17
|
+
puts help
|
18
|
+
exit 0
|
19
|
+
else # don't intercept --version/--help intended for commands we wrap
|
20
|
+
break
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
5
24
|
require 'mwrap'
|
6
25
|
mwrap_so = $".grep(%r{/mwrap\.so\z})[0] or abort "mwrap.so not loaded"
|
7
26
|
cur = ENV['LD_PRELOAD']
|
data/ext/mwrap/check.h
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#ifndef CHECK_H
|
2
|
+
#define CHECK_H
|
3
|
+
#include "gcc.h"
|
4
|
+
#include <stdlib.h>
|
5
|
+
#include <assert.h>
|
6
|
+
/*
|
7
|
+
* standard assert may malloc, but NDEBUG behavior is standardized,
|
8
|
+
* however Perl headers add some weirdness if we undef NDEBUG, so
|
9
|
+
* keep NDEBUG defined and use MWRAP_NO_DEBUG
|
10
|
+
*/
|
11
|
+
#if defined(NDEBUG) && defined(MWRAP_NO_DEBUG)
|
12
|
+
# define mwrap_assert(expr)
|
13
|
+
# define CHECK(type, expect, expr) (void)(expr)
|
14
|
+
#else
|
15
|
+
# define mwrap_assert(x) do { if (caa_unlikely(!(x))) abort(); } while (0)
|
16
|
+
# define CHECK(type, expect, expr) do { \
|
17
|
+
type checkvar = (expr); \
|
18
|
+
mwrap_assert(checkvar==(expect)&& "BUG" && __FILE__ && __LINE__); \
|
19
|
+
(void)checkvar; \
|
20
|
+
} while (0)
|
21
|
+
#endif
|
22
|
+
|
23
|
+
#endif /* CHECK_H */
|