From a20990fc4982678c2353afeca6567e5c051eee61 Mon Sep 17 00:00:00 2001 From: Marco Neumann Date: Thu, 19 Aug 2021 14:55:13 +0200 Subject: [PATCH 1/2] feat: Make jemalloc optional Add a way to use the system memory allocator which is required for some analysis tools like valgrind. --- src/influxdb_ioxd.rs | 33 ++++++++++++++++++++++++++++----- src/main.rs | 3 --- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/influxdb_ioxd.rs b/src/influxdb_ioxd.rs index 9c3b1e31e1..ac21021139 100644 --- a/src/influxdb_ioxd.rs +++ b/src/influxdb_ioxd.rs @@ -130,18 +130,41 @@ fn make_server( app_server } +#[cfg(all(not(feature = "heappy"), not(feature = "jemalloc_replacing_malloc")))] +fn build_malloc_conf() -> String { + "system".to_string() +} + +#[cfg(all(feature = "heappy", not(feature = "jemalloc_replacing_malloc")))] +fn build_malloc_conf() -> String { + "heappy".to_string() +} + +#[cfg(all(not(feature = "heappy"), feature = "jemalloc_replacing_malloc"))] +fn build_malloc_conf() -> String { + tikv_jemalloc_ctl::config::malloc_conf::mib() + .unwrap() + .read() + .unwrap() + .to_string() +} + +#[cfg(all(feature = "heappy", feature = "jemalloc_replacing_malloc"))] +fn build_malloc_conf() -> String { + compile_error!("must use exactly one memory allocator") +} + /// This is the entry point for the IOx server. `config` represents /// command line arguments, if any. pub async fn main(config: Config) -> Result<()> { let git_hash = option_env!("GIT_HASH").unwrap_or("UNKNOWN"); let num_cpus = num_cpus::get(); - let build_malloc_conf = tikv_jemalloc_ctl::config::malloc_conf::mib() - .unwrap() - .read() - .unwrap(); + let build_malloc_conf = build_malloc_conf(); info!( git_hash, - num_cpus, build_malloc_conf, "InfluxDB IOx server starting" + num_cpus, + %build_malloc_conf, + "InfluxDB IOx server starting", ); // Install custom panic handler and forget about it. diff --git a/src/main.rs b/src/main.rs index ff6355d108..056c41bdd1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -46,9 +46,6 @@ static VERSION_STRING: Lazy = Lazy::new(|| { ) }); -#[cfg(not(any(feature = "heappy", feature = "jemalloc_replacing_malloc")))] -compile_error!("you need to pick either heappy or jemalloc_replacing_malloc feature, cargo can't pick a default out of a mutually exclusive set"); - #[cfg(all(feature = "heappy", feature = "jemalloc_replacing_malloc"))] compile_error!("heappy and jemalloc_replacing_malloc features are mutually exclusive"); From 803d49648adbf5e257deb34215262c52e91041eb Mon Sep 17 00:00:00 2001 From: Marco Neumann Date: Thu, 19 Aug 2021 14:59:05 +0200 Subject: [PATCH 2/2] feat: valgrind support --- .gitignore | 4 +++- docs/valgrind.md | 42 ++++++++++++++++++++++++++++++++++++++++++ scripts/valgrind.supp | 31 +++++++++++++++++++++++++++++++ scripts/valigrind_leak | 14 ++++++++++++++ 4 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 docs/valgrind.md create mode 100644 scripts/valgrind.supp create mode 100755 scripts/valigrind_leak diff --git a/.gitignore b/.gitignore index 91b703d57a..fdf8a75188 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,9 @@ **/*.rs.bk .idea/ .env +.gdb_history *.tsm **/.DS_Store **/.vscode -query_tests/cases/**/*.out \ No newline at end of file +query_tests/cases/**/*.out +valgrind-out.txt diff --git a/docs/valgrind.md b/docs/valgrind.md new file mode 100644 index 0000000000..c45ae56b26 --- /dev/null +++ b/docs/valgrind.md @@ -0,0 +1,42 @@ +# Valgrind +This document explains how to use [Valgrind] to perform certain debug tasks. + +## Build +Create a debug build that uses the system memory allocator (i.e. neither [heappy] nor [jemalloc]): + +```console +$ cargo build --no-default-features +``` + +## Memory Leaks +There is a script that does most of the config setting. Just start the server with: + +```console +$ ./scripts/valgrind_leak ./target/debug/influxdb_iox run ... +``` + +You can kill the server w/ `CTRL-C` when you're ready. The [Valgrind] output will be written to `valgrind-out.txt`. + +## Suppression Rules +[Valgrind] allows you to suppress certain outputs. This can be used to ignore known "issues" like that [lazycell] leaks. +For IOx we provide a file that is used by the scripts (under `scripts/valgrind.supp`). If you plan to write your own +rules, here are some useful links: + +- +- +- + +You may also use the `--gen-suppressions=all` to auto-generate supppression rules: + +```console +$ ./scripts/valgrind_leak --gen-suppressions=all ./target/debug/influxdb_iox run ... +``` + +Note that Rust symbols like `influxdb_iox::main` are mangled in a way that [Valgrind] cannot parse them (e.g. to +`_ZN12influxdb_iox4main17h940b8bf02831a9d8E`). The easiest way is to replace `::` w/ `*` and prepand and append an +additional wildcard `*`, so `influxdb_iox::main` gets `*influxdb_iox*main*`. + +[heappy]: https://github.com/mkmik/heappy +[jemalloc]: ttps://github.com/jemalloc/jemalloc +[lazycell]: https://crates.io/crates/lazycell +[Valgrind]: https://valgrind.org/ diff --git a/scripts/valgrind.supp b/scripts/valgrind.supp new file mode 100644 index 0000000000..ae6f2f8d80 --- /dev/null +++ b/scripts/valgrind.supp @@ -0,0 +1,31 @@ +{ + dlopen + Memcheck:Leak + ... + fun:do_dlopen + ... +} + +{ + lazystatic + Memcheck:Leak + ... + fun:__static_ref_initialize + ... +} + +{ + oncecell + Memcheck:Leak + ... + fun:*once_cell*imp*initialize_inner* + ... +} + +{ + init_logs_and_tracing + Memcheck:Leak + ... + fun:*init_logs_and_tracing* + ... +} diff --git a/scripts/valigrind_leak b/scripts/valigrind_leak new file mode 100755 index 0000000000..92f23c93c7 --- /dev/null +++ b/scripts/valigrind_leak @@ -0,0 +1,14 @@ +#!/bin/bash +set -eu -o pipefail + +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +exec valgrind \ + --leak-check=full \ + --log-file=valgrind-out.txt \ + --num-callers=50 \ + --show-leak-kinds=all \ + --suppressions="$SCRIPT_DIR/valgrind.supp" \ + --track-origins=yes \ + --verbose \ + $@