Skip to content

Commit 7c87321

Browse files
committed
fix(module) Fix memory leak inside get_global_metadata.
The code was acting like this before: 1. Allocate a new `Vec<LLVMValueRef>`, 2. Get a mutable pointer to it, 3. Forget the vector, 4. Fill the vector with `LLVMGetNamedMetadataOperands`, 5. Read back the vector as a slice, 6. Map slice values, and collect them in a newly allocated vector. Here, the first vector is lost. That's a memory leak. This patch changes the step 5: Instead of reading the results as a slice, results are read as a vector, the same vector, with the same pointer. That way, the new `vec` vector will be dropped by Rust nicely. Compiling and running the documentation of the `get_global_metadata` method, valgrind gives us the following results: (before) ``` ==35629== LEAK SUMMARY: ==35629== definitely lost: 40 bytes in 3 blocks ==35629== indirectly lost: 0 bytes in 0 blocks ==35629== possibly lost: 0 bytes in 0 blocks ==35629== still reachable: 145 bytes in 1 blocks ==35629== suppressed: 137,663 bytes in 1,484 blocks ``` (after) ``` ==35805== LEAK SUMMARY: ==35805== definitely lost: 24 bytes in 2 blocks ==35805== indirectly lost: 0 bytes in 0 blocks ==35805== possibly lost: 0 bytes in 0 blocks ==35805== still reachable: 145 bytes in 1 blocks ==35805== suppressed: 137,663 bytes in 1,484 blocks ```
1 parent 5e64c01 commit 7c87321

File tree

1 file changed

+5
-5
lines changed

1 file changed

+5
-5
lines changed

src/module.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -930,20 +930,20 @@ impl<'ctx> Module<'ctx> {
930930
/// ```
931931
pub fn get_global_metadata(&self, key: &str) -> Vec<MetadataValue<'ctx>> {
932932
let c_string = to_c_str(key);
933-
let count = self.get_global_metadata_size(key);
933+
let count = self.get_global_metadata_size(key) as usize;
934934

935-
let mut raw_vec: Vec<LLVMValueRef> = Vec::with_capacity(count as usize);
935+
let mut raw_vec: Vec<LLVMValueRef> = Vec::with_capacity(count);
936936
let ptr = raw_vec.as_mut_ptr();
937937

938938
forget(raw_vec);
939939

940-
let slice = unsafe {
940+
let vec = unsafe {
941941
LLVMGetNamedMetadataOperands(self.module.get(), c_string.as_ptr(), ptr);
942942

943-
from_raw_parts(ptr, count as usize)
943+
Vec::from_raw_parts(ptr, count, count)
944944
};
945945

946-
slice.iter().map(|val| MetadataValue::new(*val)).collect()
946+
vec.iter().map(|val| MetadataValue::new(*val)).collect()
947947
}
948948

949949
/// Gets the first `GlobalValue` in a module.

0 commit comments

Comments
 (0)