dumping ground for random patches and texts
 help / color / mirror / Atom feed
From: Eric Wong <e@80x24.org>
To: spew@80x24.org
Subject: [PATCH 3/4] gzip
Date: Fri,  5 Apr 2024 21:05:03 +0000	[thread overview]
Message-ID: <20240405210504.3110367-3-e@80x24.org> (raw)
In-Reply-To: <20240405210504.3110367-1-e@80x24.org>

---
 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 <sys/types.h>  /* For size_t */
 #endif  /* LACKS_SYS_TYPES_H */
 
+#include <limits.h>
+
 /* 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 <urcu/rculfhash.h>
 #include <urcu/rculist.h>
 #include <limits.h>
+#include <err.h>
 
 #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 <mwrap-perl@80x24.org>
 # License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
 use v5.12;
+use autodie;
 use Devel::Mwrap::TraceReplay;
-(-f STDIN || -p STDIN) or die "Usage: $0 </path/to/mwrap.\$PID.trace\n";
+(-f STDIN || -p STDIN) or die "Usage: $0 </path/to/mwrap.\$PID.trace.gz\n";
+pipe(my $r, my $w);
+my $gzip = $ENV{GZIP} // 'gzip';
+my $pid = fork;
+if ($pid == 0) {
+	open STDOUT, '>&', $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';
 };
 

  parent reply	other threads:[~2024-04-05 21:05 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-05 21:05 [PATCH 1/4] support malloc tracing Eric Wong
2024-04-05 21:05 ` [PATCH 2/4] realloc Eric Wong
2024-04-05 21:05 ` Eric Wong [this message]
2024-04-05 21:05 ` [PATCH 4/4] tracecompress Eric Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240405210504.3110367-3-e@80x24.org \
    --to=e@80x24.org \
    --cc=spew@80x24.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).