From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-3.6 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,NORMAL_HTTP_TO_IP, NUMERIC_HTTP_ADDR shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 096EE1F51A for ; Fri, 5 Apr 2024 21:05:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=80x24.org; s=selector1; t=1712351105; bh=4iF5m+RgGUcMP8JJPe5rxpJAcXx4S44fDIrS4vHxrGM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=vToFw6CZaKkMot3f0HyXjGqXlFK0zNetZ+V8s4RWHYoaOwFcCUEl5/88MhvoRAXyK b3HphIQRaTXF1qeHvSj/1G7ySALjH3Q3GA/69nUtmicXzANwVdhLtrU6r3FEGkr2QX 74HpKoGxIpE5Fm4QtMGmNd+oEXG7JbjzX2vK4XUQ= From: Eric Wong To: spew@80x24.org Subject: [PATCH 3/4] gzip Date: Fri, 5 Apr 2024 21:05:03 +0000 Message-ID: <20240405210504.3110367-3-e@80x24.org> In-Reply-To: <20240405210504.3110367-1-e@80x24.org> References: <20240405210504.3110367-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: --- httpd.h | 8 ++++++- lib/Devel/Mwrap/TraceReplay.pm | 2 +- lib/Devel/Mwrap/dlmalloc_c.h | 4 +++- lib/Devel/Mwrap/trace-replay.h | 7 ++++-- mwrap_core.h | 40 +++++++++++++++++++++++++++++++--- mymalloc.h | 4 ++-- script/mwrap-trace-replay | 15 ++++++++++++- t/httpd.t | 2 +- 8 files changed, 70 insertions(+), 12 deletions(-) diff --git a/httpd.h b/httpd.h index 3594eb4..a097e0e 100644 --- a/httpd.h +++ b/httpd.h @@ -1423,6 +1423,8 @@ join_thread: static void h1d_atfork_prepare(void) { + if (pthread_equal(g_h1d.tid, pthread_self())) + return; if (uatomic_cmpxchg(&g_h1d.alive, 1, 0)) h1d_stop_join(&g_h1d); } @@ -1443,7 +1445,11 @@ static void h1d_start(void) /* may be called as pthread_atfork child cb */ /* must be called with global_mtx held */ static void h1d_atfork_parent(void) { - if (g_h1d.lfd < 0) + if (!pthread_equal(g_h1d.tid, pthread_self()) && g_h1d.lfd < 0) h1d_start(); } +static void h1d_atfork_child(void) +{ + if (!pthread_equal(g_h1d.tid, pthread_self())) h1d_start(); +} diff --git a/lib/Devel/Mwrap/TraceReplay.pm b/lib/Devel/Mwrap/TraceReplay.pm index bb2551b..fa3af7c 100644 --- a/lib/Devel/Mwrap/TraceReplay.pm +++ b/lib/Devel/Mwrap/TraceReplay.pm @@ -74,7 +74,7 @@ sub check_build () { sub run (@) { check_build(); - exec $bin, @_; + system $bin, @_; } 1; diff --git a/lib/Devel/Mwrap/dlmalloc_c.h b/lib/Devel/Mwrap/dlmalloc_c.h index cd2f7f5..398f376 100644 --- a/lib/Devel/Mwrap/dlmalloc_c.h +++ b/lib/Devel/Mwrap/dlmalloc_c.h @@ -590,6 +590,8 @@ MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP #include /* For size_t */ #endif /* LACKS_SYS_TYPES_H */ +#include + /* The maximum possible size_t value has all bits set */ #define MAX_SIZE_T (~(size_t)0) @@ -2608,7 +2610,7 @@ struct malloc_state { #endif /* USE_LOCKS */ msegment seg; size_t trace_wfill; - char trace_wbuf[BUFSIZ]; + char trace_wbuf[PIPE_BUF]; struct cds_list_head arena_node; /* cold */ struct cds_wfcq_tail remote_free_tail; }; diff --git a/lib/Devel/Mwrap/trace-replay.h b/lib/Devel/Mwrap/trace-replay.h index a2b0e50..c43cc0f 100644 --- a/lib/Devel/Mwrap/trace-replay.h +++ b/lib/Devel/Mwrap/trace-replay.h @@ -8,7 +8,7 @@ #define _GNU_SOURCE /* knobs for dlmalloc */ #define HAVE_MORECORE 0 -#define DEFAULT_GRANULARITY (8U * 1024U * 1024U) +#define DEFAULT_GRANULARITY (2U * 1024U * 1024U) #define FOOTERS 1 /* required for remote_free_* stuff */ #define USE_DL_PREFIX #define ONLY_MSPACES 1 /* aka per-thread "arenas" */ @@ -198,9 +198,12 @@ int main(int argc, char *argv[]) } if (free_miss || realloc_miss || bad_entry) - fprintf(stderr, "miss free=%zu realloc=%zu bad=%zu\n", + fprintf(stderr, "W: miss free=%zu realloc=%zu bad=%zu\n", free_miss, realloc_miss, bad_entry); + fprintf(stderr, "# ptrmap .size=%zu capa=%zu\n", + (size_t)kh_size(old2cur), (size_t)kh_capacity(old2cur)); + if (malloc_stats_print) // jemalloc loaded malloc_stats_print(NULL, NULL, NULL); else diff --git a/mwrap_core.h b/mwrap_core.h index af73057..2910a5a 100644 --- a/mwrap_core.h +++ b/mwrap_core.h @@ -36,6 +36,7 @@ #include #include #include +#include #if MWRAP_PERL # include "EXTERN.h" @@ -1076,6 +1077,7 @@ static struct src_loc *mwrap_get_bin(const char *buf, size_t len) static const char *mwrap_env; +// n.b. signals are always blocked by the caller(s) when calling this static int trace_on(const char *env) { char trace_path[PATH_MAX]; @@ -1107,14 +1109,46 @@ static int trace_on(const char *env) if (trace_path[len - 1] != '/') trace_path[len++] = '/'; int rc = snprintf(trace_path + len, 32, - "mwrap.%d.trace", (int)getpid()); + "mwrap.%d.trace.gz", (int)getpid()); if (rc < 0 || rc >= 32) return ENAMETOOLONG; int fd = open(trace_path, O_CLOEXEC|O_CREAT|O_APPEND|O_WRONLY, 0666); if (fd < 0) return errno; - if (uatomic_cmpxchg(&mwrap_trace_fd, -1, fd) != -1) { - close(fd); + int pfds[2]; + if (pipe2(pfds, O_CLOEXEC) < 0) + return errno; + pid_t pid_a = fork(); + if (pid_a < 0) { + err(1, "fork"); + } else if (pid_a == 0) { // child + if (setsid() < 0) err(1, "setsid"); + pid_t pid_b = fork(); + if (pid_b < 0) { + err(1, "fork"); + } else if (pid_b == 0) { // grandchild + unsetenv("LD_PRELOAD"); + + close(pfds[1]); + if (dup2(pfds[0], 0) < 0) err(1, "dup2"); + close(pfds[0]); + if (dup2(fd, 1) < 1) err(1, "dup2"); + close(fd); + + execlp("gzip", "gzip", "-c", NULL); + err(1, "execlp"); + } else { + _exit(0); + } + } + close(pfds[0]); + close(fd); + int st; + pid_t wpid = waitpid(pid_a, &st, 0); + if (wpid != pid_a) err(1, "waitpid(a)"); + if (st) errx(1, "gzip parent failed %d", st); + if (uatomic_cmpxchg(&mwrap_trace_fd, -1, pfds[1]) != -1) { + close(pfds[1]); return EBUSY; } return 0; diff --git a/mymalloc.h b/mymalloc.h index 8acf573..37771d4 100644 --- a/mymalloc.h +++ b/mymalloc.h @@ -94,7 +94,7 @@ ATTR_COLD static void mstate_tsd_dtor(void *p) /* see httpd.h */ static void h1d_atfork_prepare(void); static void h1d_atfork_parent(void); -static void h1d_start(void); +static void h1d_atfork_child(void); ATTR_COLD static void atfork_prepare(void) { @@ -132,7 +132,7 @@ ATTR_COLD static void atfork_child(void) } reset_mutexes(); call_rcu_after_fork_child(); - h1d_start(); + h1d_atfork_child(); } #if defined(__GLIBC__) diff --git a/script/mwrap-trace-replay b/script/mwrap-trace-replay index 433480b..22cbc82 100644 --- a/script/mwrap-trace-replay +++ b/script/mwrap-trace-replay @@ -2,6 +2,19 @@ # Copyright (C) mwrap hackers # License: GPL-3.0+ use v5.12; +use autodie; use Devel::Mwrap::TraceReplay; -(-f STDIN || -p STDIN) or die "Usage: $0 &', $w; + close $_ for ($r, $w); + exec $gzip, '-dc'; + die "exec: $!"; +} +open STDIN, '<&', $r; +close $_ for ($r, $w); Devel::Mwrap::TraceReplay::run @ARGV; +waitpid $pid, 0; diff --git a/t/httpd.t b/t/httpd.t index 244f8da..d7006d5 100644 --- a/t/httpd.t +++ b/t/httpd.t @@ -82,7 +82,7 @@ SKIP: { $rc = system(@curl, '-v', '-XPOST', "http://0/$pid/trace"); is $rc, 0, 'trace ok'; like(slurp($cout), qr/tracing/, 'tracing enabled'); - $trace_file = "$mwrap_tmp/tr/mwrap.$pid.trace"; + $trace_file = "$mwrap_tmp/tr/mwrap.$pid.trace.gz"; ok -f $trace_file, 'trace enabled'; };