Skip to content

Commit 57987e1

Browse files
committed
chore(memtrack): add tcmalloc test
1 parent 85a82d3 commit 57987e1

6 files changed

Lines changed: 228 additions & 0 deletions

File tree

crates/memtrack/testdata/alloc_cpp/CMakeLists.txt

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,53 @@ if(NOT JEMALLOC_STATIC_LIB)
5050
message(STATUS "Static jemalloc not found, will fall back to dynamic linking")
5151
endif()
5252

53+
# TCMalloc support via system gperftools package
54+
# gperftools provides libtcmalloc on most Linux distributions
55+
# (Ubuntu: libtcmalloc-minimal4, Fedora: gperftools-libs, NixOS: gperftools)
56+
find_package(Threads REQUIRED)
57+
58+
# Search in common paths including NixOS store
59+
file(GLOB TCMALLOC_NIX_PATHS "/nix/store/*gperftools*/lib")
60+
61+
# Find static library
62+
set(_old_suffixes ${CMAKE_FIND_LIBRARY_SUFFIXES})
63+
set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
64+
find_library(TCMALLOC_STATIC_LIB
65+
NAMES libtcmalloc_minimal.a libtcmalloc.a tcmalloc_minimal tcmalloc
66+
HINTS ${TCMALLOC_NIX_PATHS}
67+
DOC "Static TCMalloc library (from gperftools)"
68+
)
69+
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_old_suffixes})
70+
71+
if(NOT TCMALLOC_STATIC_LIB)
72+
message(STATUS "Static TCMalloc not found, will fall back to dynamic linking")
73+
endif()
74+
75+
# Find dynamic library
76+
find_package(PkgConfig)
77+
if(PKG_CONFIG_FOUND)
78+
pkg_check_modules(TCMALLOC QUIET libtcmalloc_minimal libtcmalloc)
79+
endif()
80+
81+
if(NOT TCMALLOC_FOUND)
82+
find_library(TCMALLOC_LIBRARY
83+
NAMES tcmalloc_minimal tcmalloc
84+
HINTS ${TCMALLOC_NIX_PATHS}
85+
DOC "TCMalloc library (from gperftools)"
86+
)
87+
if(TCMALLOC_LIBRARY)
88+
set(TCMALLOC_FOUND TRUE)
89+
set(TCMALLOC_LIBRARIES ${TCMALLOC_LIBRARY})
90+
endif()
91+
endif()
92+
93+
if(TCMALLOC_FOUND OR TCMALLOC_STATIC_LIB)
94+
message(STATUS "Found TCMalloc: static=${TCMALLOC_STATIC_LIB}, dynamic=${TCMALLOC_LIBRARIES}")
95+
set(TCMALLOC_AVAILABLE ON)
96+
else()
97+
message(STATUS "TCMalloc not found, tcmalloc test targets will not link correctly")
98+
endif()
99+
53100
# Target: alloc_cpp_system
54101
set(alloc_cpp_system_SOURCES
55102
cmake.toml
@@ -169,3 +216,67 @@ get_directory_property(CMKR_VS_STARTUP_PROJECT DIRECTORY ${PROJECT_SOURCE_DIR} D
169216
if(NOT CMKR_VS_STARTUP_PROJECT)
170217
set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT alloc_cpp_mimalloc_dynamic)
171218
endif()
219+
220+
# Target: alloc_cpp_tcmalloc_static
221+
set(alloc_cpp_tcmalloc_static_SOURCES
222+
cmake.toml
223+
"src/main.cpp"
224+
)
225+
226+
add_executable(alloc_cpp_tcmalloc_static)
227+
228+
target_sources(alloc_cpp_tcmalloc_static PRIVATE ${alloc_cpp_tcmalloc_static_SOURCES})
229+
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${alloc_cpp_tcmalloc_static_SOURCES})
230+
231+
target_compile_definitions(alloc_cpp_tcmalloc_static PRIVATE
232+
USE_TCMALLOC=1
233+
)
234+
235+
get_directory_property(CMKR_VS_STARTUP_PROJECT DIRECTORY ${PROJECT_SOURCE_DIR} DEFINITION VS_STARTUP_PROJECT)
236+
if(NOT CMKR_VS_STARTUP_PROJECT)
237+
set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT alloc_cpp_tcmalloc_static)
238+
endif()
239+
240+
set(CMKR_TARGET alloc_cpp_tcmalloc_static)
241+
if(TCMALLOC_STATIC_LIB)
242+
# Use --whole-archive to ensure malloc override symbols are included
243+
target_link_options(alloc_cpp_tcmalloc_static PRIVATE "LINKER:--whole-archive")
244+
target_link_libraries(alloc_cpp_tcmalloc_static PRIVATE ${TCMALLOC_STATIC_LIB})
245+
target_link_options(alloc_cpp_tcmalloc_static PRIVATE "LINKER:--no-whole-archive")
246+
target_link_libraries(alloc_cpp_tcmalloc_static PRIVATE Threads::Threads)
247+
elseif(TCMALLOC_LIBRARIES)
248+
# Fallback to dynamic linking
249+
target_link_libraries(alloc_cpp_tcmalloc_static PRIVATE ${TCMALLOC_LIBRARIES})
250+
else()
251+
message(WARNING "TCMalloc not found, alloc_cpp_tcmalloc_static will not link correctly")
252+
endif()
253+
254+
# Target: alloc_cpp_tcmalloc_dynamic
255+
set(alloc_cpp_tcmalloc_dynamic_SOURCES
256+
cmake.toml
257+
"src/main.cpp"
258+
)
259+
260+
add_executable(alloc_cpp_tcmalloc_dynamic)
261+
262+
target_sources(alloc_cpp_tcmalloc_dynamic PRIVATE ${alloc_cpp_tcmalloc_dynamic_SOURCES})
263+
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${alloc_cpp_tcmalloc_dynamic_SOURCES})
264+
265+
target_compile_definitions(alloc_cpp_tcmalloc_dynamic PRIVATE
266+
USE_TCMALLOC=1
267+
)
268+
269+
get_directory_property(CMKR_VS_STARTUP_PROJECT DIRECTORY ${PROJECT_SOURCE_DIR} DEFINITION VS_STARTUP_PROJECT)
270+
if(NOT CMKR_VS_STARTUP_PROJECT)
271+
set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT alloc_cpp_tcmalloc_dynamic)
272+
endif()
273+
274+
set(CMKR_TARGET alloc_cpp_tcmalloc_dynamic)
275+
if(TCMALLOC_AVAILABLE)
276+
target_link_libraries(alloc_cpp_tcmalloc_dynamic PRIVATE ${TCMALLOC_LIBRARIES})
277+
if(TCMALLOC_INCLUDE_DIRS)
278+
target_include_directories(alloc_cpp_tcmalloc_dynamic PRIVATE ${TCMALLOC_INCLUDE_DIRS})
279+
endif()
280+
else()
281+
message(WARNING "TCMalloc not found, alloc_cpp_tcmalloc_dynamic will not link correctly")
282+
endif()

crates/memtrack/testdata/alloc_cpp/cmake.toml

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,53 @@ endif()
2121
if(NOT JEMALLOC_STATIC_LIB)
2222
message(STATUS "Static jemalloc not found, will fall back to dynamic linking")
2323
endif()
24+
25+
# TCMalloc support via system gperftools package
26+
# gperftools provides libtcmalloc on most Linux distributions
27+
# (Ubuntu: libtcmalloc-minimal4, Fedora: gperftools-libs, NixOS: gperftools)
28+
find_package(Threads REQUIRED)
29+
30+
# Search in common paths including NixOS store
31+
file(GLOB TCMALLOC_NIX_PATHS "/nix/store/*gperftools*/lib")
32+
33+
# Find static library
34+
set(_old_suffixes ${CMAKE_FIND_LIBRARY_SUFFIXES})
35+
set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
36+
find_library(TCMALLOC_STATIC_LIB
37+
NAMES libtcmalloc_minimal.a libtcmalloc.a tcmalloc_minimal tcmalloc
38+
HINTS ${TCMALLOC_NIX_PATHS}
39+
DOC "Static TCMalloc library (from gperftools)"
40+
)
41+
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_old_suffixes})
42+
43+
if(NOT TCMALLOC_STATIC_LIB)
44+
message(STATUS "Static TCMalloc not found, will fall back to dynamic linking")
45+
endif()
46+
47+
# Find dynamic library
48+
find_package(PkgConfig)
49+
if(PKG_CONFIG_FOUND)
50+
pkg_check_modules(TCMALLOC QUIET libtcmalloc_minimal libtcmalloc)
51+
endif()
52+
53+
if(NOT TCMALLOC_FOUND)
54+
find_library(TCMALLOC_LIBRARY
55+
NAMES tcmalloc_minimal tcmalloc
56+
HINTS ${TCMALLOC_NIX_PATHS}
57+
DOC "TCMalloc library (from gperftools)"
58+
)
59+
if(TCMALLOC_LIBRARY)
60+
set(TCMALLOC_FOUND TRUE)
61+
set(TCMALLOC_LIBRARIES ${TCMALLOC_LIBRARY})
62+
endif()
63+
endif()
64+
65+
if(TCMALLOC_FOUND OR TCMALLOC_STATIC_LIB)
66+
message(STATUS "Found TCMalloc: static=${TCMALLOC_STATIC_LIB}, dynamic=${TCMALLOC_LIBRARIES}")
67+
set(TCMALLOC_AVAILABLE ON)
68+
else()
69+
message(STATUS "TCMalloc not found, tcmalloc test targets will not link correctly")
70+
endif()
2471
"""
2572

2673
# System allocator (libc default malloc)
@@ -69,3 +116,42 @@ type = "executable"
69116
sources = ["src/main.cpp"]
70117
compile-definitions = ["USE_MIMALLOC=1"]
71118
link-libraries = ["mimalloc"]
119+
120+
# TCMalloc (gperftools) - static linking
121+
# Uses system-installed libtcmalloc.a from gperftools package
122+
[target.alloc_cpp_tcmalloc_static]
123+
type = "executable"
124+
sources = ["src/main.cpp"]
125+
compile-definitions = ["USE_TCMALLOC=1"]
126+
cmake-after = """
127+
if(TCMALLOC_STATIC_LIB)
128+
# Use --whole-archive to ensure malloc override symbols are included
129+
target_link_options(alloc_cpp_tcmalloc_static PRIVATE "LINKER:--whole-archive")
130+
target_link_libraries(alloc_cpp_tcmalloc_static PRIVATE ${TCMALLOC_STATIC_LIB})
131+
target_link_options(alloc_cpp_tcmalloc_static PRIVATE "LINKER:--no-whole-archive")
132+
target_link_libraries(alloc_cpp_tcmalloc_static PRIVATE Threads::Threads)
133+
elseif(TCMALLOC_LIBRARIES)
134+
# Fallback to dynamic linking
135+
target_link_libraries(alloc_cpp_tcmalloc_static PRIVATE ${TCMALLOC_LIBRARIES})
136+
else()
137+
message(WARNING "TCMalloc not found, alloc_cpp_tcmalloc_static will not link correctly")
138+
endif()
139+
"""
140+
141+
# TCMalloc (gperftools) - dynamic linking
142+
# Uses system-installed libtcmalloc from gperftools package
143+
# (Ubuntu: libtcmalloc-minimal4, Fedora: gperftools-libs)
144+
[target.alloc_cpp_tcmalloc_dynamic]
145+
type = "executable"
146+
sources = ["src/main.cpp"]
147+
compile-definitions = ["USE_TCMALLOC=1"]
148+
cmake-after = """
149+
if(TCMALLOC_AVAILABLE)
150+
target_link_libraries(alloc_cpp_tcmalloc_dynamic PRIVATE ${TCMALLOC_LIBRARIES})
151+
if(TCMALLOC_INCLUDE_DIRS)
152+
target_include_directories(alloc_cpp_tcmalloc_dynamic PRIVATE ${TCMALLOC_INCLUDE_DIRS})
153+
endif()
154+
else()
155+
message(WARNING "TCMalloc not found, alloc_cpp_tcmalloc_dynamic will not link correctly")
156+
endif()
157+
"""

crates/memtrack/testdata/alloc_cpp/src/main.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
#include <mimalloc.h>
1313
#endif
1414

15+
// USE_TCMALLOC: Uses gperftools libtcmalloc via dynamic linking
16+
// No header include needed - tcmalloc overrides malloc/free symbols
17+
1518
// Prevent compiler from optimizing away allocations
1619
// Similar to Rust's core::hint::black_box
1720
template<typename T>

crates/memtrack/tests/cpp_tests.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ fn compile_cpp_project(project_dir: &Path, target: &str) -> anyhow::Result<std::
5050
#[case("alloc_cpp_jemalloc_dynamic")]
5151
#[case("alloc_cpp_mimalloc_static")]
5252
#[case("alloc_cpp_mimalloc_dynamic")]
53+
#[case("alloc_cpp_tcmalloc_static")]
54+
#[case("alloc_cpp_tcmalloc_dynamic")]
5355
#[test_log::test]
5456
fn test_cpp_alloc_tracking(#[case] target: &str) -> Result<(), Box<dyn std::error::Error>> {
5557
let project_path = Path::new("testdata/alloc_cpp");
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
source: crates/memtrack/tests/cpp_tests.rs
3+
expression: formatted_events
4+
---
5+
[
6+
"Malloc { size: 44444 }",
7+
"Free",
8+
"Malloc { size: 8 }",
9+
"Free",
10+
"Malloc { size: 88888 }",
11+
"AlignedAlloc { size: 32768 }",
12+
"Free",
13+
]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
source: crates/memtrack/tests/cpp_tests.rs
3+
expression: formatted_events
4+
---
5+
[
6+
"Malloc { size: 44444 }",
7+
"Free",
8+
"Malloc { size: 8 }",
9+
"Free",
10+
"Malloc { size: 88888 }",
11+
"AlignedAlloc { size: 32768 }",
12+
"Free",
13+
]

0 commit comments

Comments
 (0)