Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libbpf-tools: Add new feature ALSan #4120

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

Bojun-Seo
Copy link
Contributor

@Bojun-Seo Bojun-Seo commented Jul 19, 2022

Add ALSan(Attachable Leak Sanitizer) feature on libbpf-tools
ALSan feature originally comes from the llvm-project lsan
https://github.com/llvm/llvm-project
cvector.h comes from c-vector project, commit d3f3156373b0587336ac7ee1568755d6cf93dd39
https://github.com/eteran/c-vector
uthash.h comes from uthash project, commit bf15263081be6229be31addd48566df93921cb46
https://github.com/troydhanson/uthash
This tool detect and report unreachable memory periodically

Usage:

$ ./alsan -h
Usage: alsan [OPTION...]
Detect memory leak resulting from unreachable pointers.

Either -c or -p is a mandatory option
EXAMPLES:
    alsan -p 1234             # Detect leaks on process id 1234
    alsan -c a.out            # Detect leaks on a.out
    alsan -c 'a.out arg'      # Detect leaks on a.out with argument

  -c, --command=COMMAND      Execute and detect memory leak on the specified
                             command
  -i, --interval=INTERVAL    Set interval in second to detect leak
  -p, --pid=PID              Detect memory leak on the specified process
  -s, --suppressions=SUPPRESSIONS
                             Suppressions file name
  -T, --top=TOP              Report only specified amount of backtraces
  -v, --verbose              Verbose debug output
  -w, --stop-the-world       Stop the target process during tracing
  -?, --help                 Give this help list
      --usage                Give a short usage message
  -V, --version              Print program version

Mandatory or optional arguments to long options are also mandatory or optional
for any corresponding short options.

Report bugs to https://github.com/iovisor/bcc/tree/master/libbpf-tools.

Report example:

$ sudo ./alsan -p 28346

[2024-05-22 14:44:58] Print leaks:
44 bytes direct leak found in 1 allocations from stack id(57214)
        #1 0x00583bca1b2250 baz+0x1c (/home/bojun/alsan/libbpf-tools/a.out+0x1250)
        #2 0x00583bca1b22d7 main+0x73 (/home/bojun/alsan/libbpf-tools/a.out+0x12d7)
        #3 0x007470c7c2a1ca [unknown] (/usr/lib/x86_64-linux-gnu/libc.so.6+0x2a1ca)
        #4 0x007470c7c2a28b __libc_start_main+0x8b (/usr/lib/x86_64-linux-gnu/libc.so.6+0x2a28b)
        #5 0x00583bca1b2105 _start+0x25 (/home/bojun/alsan/libbpf-tools/a.out+0x1105)


[2024-05-22 14:45:08] Print leaks:
132 bytes direct leak found in 3 allocations from stack id(57214)
        #1 0x00583bca1b2250 baz+0x1c (/home/bojun/alsan/libbpf-tools/a.out+0x1250)
        #2 0x00583bca1b22d7 main+0x73 (/home/bojun/alsan/libbpf-tools/a.out+0x12d7)
        #3 0x007470c7c2a1ca [unknown] (/usr/lib/x86_64-linux-gnu/libc.so.6+0x2a1ca)
        #4 0x007470c7c2a28b __libc_start_main+0x8b (/usr/lib/x86_64-linux-gnu/libc.so.6+0x2a28b)
        #5 0x00583bca1b2105 _start+0x25 (/home/bojun/alsan/libbpf-tools/a.out+0x1105)

^C
$

Source code of test program:

$ cat leak_test.c
#include <stdlib.h>
#include <unistd.h>

int *arr[10000];

int *foo(size_t size) {
        int *tmp = malloc(size);
        *tmp = 99;
        return tmp;
}

int *bar(size_t nmemb, size_t size) {
        int *tmp = calloc(nmemb, size);
        *tmp = 22;
        return tmp;
}

int *baz(size_t size) {
        int *tmp = valloc(size);
        *tmp = 11;
        return tmp;
}

int main(int argc, char* argv[]) {
        int *a;
        int i = 0;
        while (1) {
                a = foo(4);
                arr[i++] = a;
                a = bar(4, 4);
                free(a);
                a = baz(44);
                sleep(5);
        }
        return 0;
}

@Bojun-Seo Bojun-Seo changed the title bbpf-tools: Add new feature(leaksanitizer) on BPF CO-RE bpf-tools: Add new feature(leaksanitizer) on BPF CO-RE Jul 19, 2022
@Bojun-Seo Bojun-Seo force-pushed the lsan branch 5 times, most recently from 3473249 to 5b90929 Compare July 19, 2022 08:31
@chenhengqi
Copy link
Collaborator

There is a similar PR in #3828 .

@Bojun-Seo
Copy link
Contributor Author

@chenhengqi, well, lsan is pretty different from memleak.
memleak is to keep tracking currently allocated heap memory,
where lsan is to report dangling pointers within "currently allocated heap memory" like llvm-project leak sanitizer

@chenhengqi
Copy link
Collaborator

Fine, could you describe how does it work ?

@Bojun-Seo
Copy link
Contributor Author

Followings are the way it work.(Refer to this document https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizerDesignDocument)
lsan hooks memory allocating functions(malloc, calloc, free.. etc).
It considers memory space as direct graph.(Consider every value as a pointer)
Set hooked node as "unreachable", before it starts following steps.(and repeat periodically)
One, it traverses from the root set and mark reachable node as "reachable"
Two, it traverses again from the hooked set and marks reachable node as "indirect" if it is "unreachable" node.
Three, sort and report "unreachable" node as direct leak and "indirect" node as indirect leak.

About root set:
Root set denotes these things.
global variables, stacks of running threads, general-purpose registers of running threads, ELF thread-local storage and POSIX thread-specific data.
Original lsan is a library, so it can use API to get this information.
BPF lsan is an independent process, so it use ptrace api to get general-purpose registers, and read /proc/pid/maps to get others.

Indirect leak means not reachable allocation node from the root but can be reachable from some unreachable block.
Direct leak means not reachable allocation node from the root and not indirect leak.

@Bojun-Seo
Copy link
Contributor Author

The memory leak problem is an old problem and has not yet been conquered but very important. To solve memory leak problem, various methods have been tried and the best way is using a tool so far. There are two types of tools: static tools and dynamic tools.
In case of static tools, operation time and detection capability are trade off. Theoretically, almost infinite amount of time is required to detect all memory leaks using a static analysis tool. So static tool usually used to detect quite easy memory leaks because of time limitations.
In case of dynamic tools, there are two famous dynamic memory leak detecting tools: Valgrind and llvm-project LeakSanitizer.
These tools are good but have limitations. Valgrind performance degradation is about 10-50 times. It is difficult to use even in a desktop environment, and it is virtually impossible to use in an embedded system. llvm-project LeakSanitizer has little performance degradation, but not easy to use. And both tool require to restart the target program and can get report at termination of the target process.
I suggest bcc lsan(this PR) to solve these problems. It has little performance degradation, is easy to use, can be applied immediately to a running process, and can get report without target process termination.
For example, imagine if you developed a new service(daemon), which has no scenario to be quit. Somehow you found some weird memory increasement on the service. How can you debug it? To use llvm-project LeakSanitizer or Valgrind, you need to make exit routine on your program, regenerate the issue and rerun the program. Making good exit routine is quite hard but let's consider you did it well. But what if it takes 3 days to regenerate this issue? Maybe you need to stop the factory 3 days.
bcc lsan will reduce and remove these kind of problems. Because it can be applied immediately and generate report in the middle of the target process execution.

Copy link
Contributor

@eiffel-fl eiffel-fl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi.

First of all, I would like to thank you for your contribution, it seems really cool.
I have some comments regarding the eBPF code.
I will take a look later at the C userland code (even though I am not 100% I will be able to understand the logic).

Best regards.

libbpf-tools/lsan.bpf.c Outdated Show resolved Hide resolved
libbpf-tools/lsan.bpf.c Outdated Show resolved Hide resolved
libbpf-tools/lsan.bpf.c Outdated Show resolved Hide resolved
Copy link
Contributor

@eiffel-fl eiffel-fl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi.

This time, I took a look at the userspace code.
I am not 100% sure I understand the whole code particularly all the hash maps you need but it worked!
I also share your opinion about being able to quickly spot memory leak at runtime while not slowing the application (contrary to valgrind even though I really like this tool).

I tried to run it and I had to modify the following:

diff --git a/libbpf-tools/lsan.c b/libbpf-tools/lsan.c
index dcb3862e..1cd9538b 100644
--- a/libbpf-tools/lsan.c
+++ b/libbpf-tools/lsan.c
@@ -358,11 +358,11 @@ static int get_libc_path(char *path)
                        continue;
 
                file_name = strrchr(buf, '/') + 1;
-#ifdef __aarch64__
+// #ifdef __aarch64__
                if (sscanf(file_name, "libc-%f.so", &version) == 1) {
-#else
-               if (sscanf(file_name, "libc.so.%f", &version) == 1) {
-#endif
+// #else
+//             if (sscanf(file_name, "libc.so.%f", &version) == 1) {
+// #endif
                        memcpy(path, buf, strlen(buf));
                        fclose(f);
                        return 0;

Indeed, on my system, I have:

francis@pwmachine:~/Codes/kinvolk/bcc/libbpf-tools$ lsb_release -a                                                                                  
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.5 LTS
Release:        20.04
Codename:       focal
francis@pwmachine:~/Codes/kinvolk/bcc/libbpf-tools$ uname -a                                                                                        
Linux pwmachine 5.15.0-48-generic #54~20.04.1-Ubuntu SMP Thu Sep 1 16:17:26 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
francis@pwmachine:~/Codes/kinvolk/bcc/libbpf-tools$ ls -l /usr/lib/x86_64-linux-gnu/libc.so.6                                                       
lrwxrwxrwx 1 root root 12 avril  7 03:24 /usr/lib/x86_64-linux-gnu/libc.so.6 -> libc-2.31.so

After this modification, I was able to get the same output as you (plus the value 99 printed by a.out).

Best regards.

libbpf-tools/cvector.h Outdated Show resolved Hide resolved
libbpf-tools/lsan.bpf.c Outdated Show resolved Hide resolved
libbpf-tools/lsan.c Outdated Show resolved Hide resolved
libbpf-tools/lsan.c Outdated Show resolved Hide resolved
libbpf-tools/lsan.c Outdated Show resolved Hide resolved
libbpf-tools/lsan.c Outdated Show resolved Hide resolved
libbpf-tools/lsan.c Outdated Show resolved Hide resolved
libbpf-tools/lsan.c Outdated Show resolved Hide resolved
libbpf-tools/cvector.h Outdated Show resolved Hide resolved
libbpf-tools/Makefile Outdated Show resolved Hide resolved
libbpf-tools/lsan.h Outdated Show resolved Hide resolved
libbpf-tools/lsan.bpf.c Outdated Show resolved Hide resolved
libbpf-tools/lsan.bpf.c Outdated Show resolved Hide resolved
libbpf-tools/lsan.bpf.c Outdated Show resolved Hide resolved
@chenhengqi
Copy link
Collaborator

Sorry for the long delay, I will try finishing this review this week.

@chenhengqi
Copy link
Collaborator

Ping me if this PR is ready for review.

@Bojun-Seo
Copy link
Contributor Author

@chenhengqi
This PR is ready to be reviewed

Copy link
Contributor

@eiffel-fl eiffel-fl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi!

Thank you for the latest modifications!
I only found nits.
I will test it again but from code inspection it looks OK.

Best regards.

libbpf-tools/lsan.c Outdated Show resolved Hide resolved
libbpf-tools/lsan.c Outdated Show resolved Hide resolved
Copy link
Contributor

@eiffel-fl eiffel-fl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested it again and it works fine:

$ sudo ./lsan -c /tmp/test -s /tmp/suppr.txt                   (remotes/bojun/lsan) *%
[sudo] Mot de passe de francis : 
Info: Execute child process: /tmp/test
Info: execute command: /tmp/test(pid 94525)
99
99

[2023-11-08 16:15:57] Print leaks:
4 bytes direct leak found in 1 allocations from stack id(41605)
        #1 0x00557fb2fee1bf foo+0x16 (/tmp/test+0x11bf)
        #2 0x00557fb2fee21b main+0x1e (/tmp/test+0x121b)
        #3 0x007f4794629d90 __libc_init_first+0x90 (/usr/lib/x86_64-linux-gnu/libc.so.6+0x29d90)

99

[2023-11-08 16:16:07] Print leaks:
8 bytes direct leak found in 2 allocations from stack id(41605)
        #1 0x00557fb2fee1bf foo+0x16 (/tmp/test+0x11bf)
        #2 0x00557fb2fee21b main+0x1e (/tmp/test+0x121b)
        #3 0x007f4794629d90 __libc_init_first+0x90 (/usr/lib/x86_64-linux-gnu/libc.so.6+0x29d90)

99

[2023-11-08 16:16:17] Print leaks:
12 bytes direct leak found in 3 allocations from stack id(41605)
        #1 0x00557fb2fee1bf foo+0x16 (/tmp/test+0x11bf)
        #2 0x00557fb2fee21b main+0x1e (/tmp/test+0x121b)
        #3 0x007f4794629d90 __libc_init_first+0x90 (/usr/lib/x86_64-linux-gnu/libc.so.6+0x29d90)

Apart from the two nits I found earlier, it is, for me, ready to go!
Thank you for this cool tool!

libbpf-tools/lsan.c Outdated Show resolved Hide resolved
libbpf-tools/lsan.c Outdated Show resolved Hide resolved
libbpf-tools/lsan.c Outdated Show resolved Hide resolved
@Bojun-Seo Bojun-Seo marked this pull request as draft March 2, 2024 00:33
@Bojun-Seo Bojun-Seo marked this pull request as ready for review March 14, 2024 03:54
@Bojun-Seo
Copy link
Contributor Author

Difference between memleak and lsan
memleak shows the status of memory allocation. In other words, it shows memory allocated but not released.
lsan shows the unreachable memory among allocated memory.

Followings are the test code

#include <stdlib.h>
#include <unistd.h>

int *arr[10000];

int *foo(size_t size) {
        int *tmp = malloc(size);
        *tmp = 99;
        return tmp;
}

int *bar(size_t nmemb, size_t size) {
        int *tmp = calloc(nmemb, size);
        *tmp = 22;
        return tmp;
}

int *baz(size_t size) {
        int *tmp = valloc(size);
        *tmp = 11;
        return tmp;
}

int main(int argc, char* argv[]) {
        int *a;
        int i = 0;
        while (1) {
                a = foo(4);
                arr[i++] = a;
                a = bar(4, 4);
                free(a);
                a = baz(44);
                sleep(5);
        }
        return 0;
}

memory allocated by foo is saved on arr array. So it is reachable and not deallocated.
memory allocated by bar is deallocated.
memory allocated by baz will become unreachable(as well as not deallocated).

So, memleak reports deallocated allocations. foo and baz

$ sudo ./memleak -c a.out
[sudo] password for bojun:
using default object: libc.so.6
using page size: 4096
tracing kernel: false
child created with pid: 257140
Tracing outstanding memory allocs...  Hit Ctrl-C to end
received go event. executing child command
[14:18:6] Top 2 stacks with outstanding allocations:
88 bytes in 2 allocations from stack
        0 [<000055f3810e1250>] baz+0x1c
        1 [<000055f3810e12d7>] main+0x73
        2 [<00007fbd77829d90>] __libc_init_first+0x90
8 bytes in 2 allocations from stack
        0 [<000055f3810e11e5>] foo+0x1c
        1 [<000055f3810e1288>] main+0x24
        2 [<00007fbd77829d90>] __libc_init_first+0x90
[14:18:11] Top 2 stacks with outstanding allocations:
132 bytes in 3 allocations from stack
        0 [<000055f3810e1250>] baz+0x1c
        1 [<000055f3810e12d7>] main+0x73
        2 [<00007fbd77829d90>] __libc_init_first+0x90
12 bytes in 3 allocations from stack
        0 [<000055f3810e11e5>] foo+0x1c
        1 [<000055f3810e1288>] main+0x24
        2 [<00007fbd77829d90>] __libc_init_first+0x90

^C[14:18:12] Top 2 stacks with outstanding allocations:
132 bytes in 3 allocations from stack
        0 [<000055f3810e1250>] <null sym>
        1 [<000055f3810e12d7>] <null sym>
        2 [<00007fbd77829d90>] <null sym>
12 bytes in 3 allocations from stack
        0 [<000055f3810e11e5>] <null sym>
        1 [<000055f3810e1288>] <null sym>
        2 [<00007fbd77829d90>] <null sym>
reaped child process
done

lsan reports only unreachable allocations. baz.

$ sudo ./lsan -c a.out
2024-Mar-14 11:47:18 INFO execute command: a.out(pid 257157)

[2024-03-14 14:26:51] Print leaks:
44 bytes direct leak found in 1 allocations from stack id(65376)
        #1 0x00559d087a2250 baz+0x1c
        #2 0x00559d087a22d7 main+0x73
        #3 0x007f0b3a629d90 [unknown]


[2024-03-14 14:27:01] Print leaks:
132 bytes direct leak found in 3 allocations from stack id(65376)
        #1 0x00559d087a2250 baz+0x1c
        #2 0x00559d087a22d7 main+0x73
        #3 0x007f0b3a629d90 [unknown]

^C

Copy link
Contributor

@eiffel-fl eiffel-fl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi!

I already approved it, so it should be OK.
Reading the code again, I just have one question with regard to avoid having several loops, but I am doubtful this is possible.

Best regards.

Comment on lines 1016 to 1021
for_each_tid_ptrace(PTRACE_SEIZE);
for_each_tid_ptrace(PTRACE_INTERRUPT);
for_each_tid_waitpid();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to have the code inside one loop and doing all these operations inside this loop?
Something like this:

	save_roots();
	for (i = 0; i < cvector_size(tids); ++i) {
		ret = ptrace(PTRACE_SEIZE, tids[i], NULL, NULL);
		if // ...
		ret = ptrace(PTRACE_INTERRUPT, tids[i], NULL, NULL);
		if // ...
		ret = waitpid(tids[i], NULL, __WALL);
		if // ...
	}
	
	ret = read_table();
	if (ret < 0) {
		p_warn("Failed to read_table, retry after %d seconds",
		       env.interval);
		for_each_tid_ptrace(PTRACE_DETACH);
		return 0;
	}
	HASH_ITER(hh, allocs, curr, next) {
		mark_indirectly_leaked_cb(curr->id);
		collect_leaks_cb(curr->id);
	}
	for_each_tid_ptrace(PTRACE_DETACH);
	report_leaks(syms_cache);

	return 0;

What do you think?

Copy link
Contributor Author

@Bojun-Seo Bojun-Seo Mar 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it could be possible to have the code inside one loop and doing all ptrace attach, interrupt and waitpid inside the loop, which will mitigate loop overhead.

I think it would be better to factorize it for readability.
However, despite the intention to factorize it for readability, it currently doesn't seem to be very readable.
I think that's why you think it would be better to make one loop.
I'll revise this function to enhance its readability.

Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to change the code as you suggested, but because of the env.stop_the_world flag, the code became more complicated. This means the current code has better readability in my opinion. So I decided to stick with it. However, your suggestion is very good, and I'll change the code if I find a more readable way.

Thanks!

@Bojun-Seo
Copy link
Contributor Author

I split my whole patch into three parts.

  1. Adding open source cvector.h file
  2. Adding open source uthash.h file
  3. Lsan implementation

@Bojun-Seo
Copy link
Contributor Author

Bojun-Seo commented Aug 1, 2024

I changed alignment value(loop stride factor) in function scan_range_for_pointers from 1 to WORD_SIZE for performance.

In case of tracing chrome during it is playing Youtube, the overhead was about 179 seconds and now it becomes 22 seconds with this change.(about 8 times faster)

Copy link
Contributor

@eiffel-fl eiffel-fl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi!

I have one comment with regard to cvector.h and uthash.h.

Best regards.

libbpf-tools/cvector.h Outdated Show resolved Hide resolved
libbpf-tools/lsan.c Outdated Show resolved Hide resolved
Add submodule c-vector
https://github.com/eteran/c-vector

This project is header only library project that contains interfaces
and implementations of vector container which can be used in C
The license of this project is MIT
Add submodule uthash
https://github.com/troydhanson/uthash

This project is header only library project that contains interfaces
and implementations of hash map container which can be used in C
The license is written on the top of the file uthash.h
@Bojun-Seo Bojun-Seo changed the title libbpf-tools: Add new feature lsan libbpf-tools: Add new feature ALSan Aug 27, 2024
Add ALSan(Attachable Leak Sanitizer) feature on libbpf-tools
ALSan feature originally comes from the llvm-project lsan
https://github.com/llvm/llvm-project
This tool detect and report unreachable memory periodically

USAGE:

  $ ./alsan -h
  Usage: alsan [OPTION...]
  Detect memory leak resulting from unreachable pointers.

  Either -c or -p is a mandatory option
  EXAMPLES:
      alsan -p 1234             # Detect leaks on process id 1234
      alsan -c a.out            # Detect leaks on a.out
      alsan -c 'a.out arg'      # Detect leaks on a.out with argument

    -c, --command=COMMAND      Execute and detect memory leak on the specified
                               command
    -i, --interval=INTERVAL    Set interval in second to detect leak
    -p, --pid=PID              Detect memory leak on the specified process
    -s, --suppressions=SUPPRESSIONS
                               Suppressions file name
    -T, --top=TOP              Report only specified amount of backtraces
    -v, --verbose              Verbose debug output
    -w, --stop-the-world       Stop the target process during tracing
    -?, --help                 Give this help list
        --usage                Give a short usage message
    -V, --version              Print program version

  Mandatory or optional arguments to long options are also mandatory or optional
  for any corresponding short options.

  Report bugs to https://github.com/iovisor/bcc/tree/master/libbpf-tools.

Report example:

  $ sudo ./alsan -p 28346

  [2024-05-22 14:44:58] Print leaks:
  44 bytes direct leak found in 1 allocations from stack id(57214)
          iovisor#1 0x00583bca1b2250 baz+0x1c (/home/bojun/alsan/libbpf-tools/a.out+0x1250)
          iovisor#2 0x00583bca1b22d7 main+0x73 (/home/bojun/alsan/libbpf-tools/a.out+0x12d7)
          iovisor#3 0x007470c7c2a1ca [unknown] (/usr/lib/x86_64-linux-gnu/libc.so.6+0x2a1ca)
          iovisor#4 0x007470c7c2a28b __libc_start_main+0x8b (/usr/lib/x86_64-linux-gnu/libc.so.6+0x2a28b)
          iovisor#5 0x00583bca1b2105 _start+0x25 (/home/bojun/alsan/libbpf-tools/a.out+0x1105)

  [2024-05-22 14:45:08] Print leaks:
  132 bytes direct leak found in 3 allocations from stack id(57214)
          iovisor#1 0x00583bca1b2250 baz+0x1c (/home/bojun/alsan/libbpf-tools/a.out+0x1250)
          iovisor#2 0x00583bca1b22d7 main+0x73 (/home/bojun/alsan/libbpf-tools/a.out+0x12d7)
          iovisor#3 0x007470c7c2a1ca [unknown] (/usr/lib/x86_64-linux-gnu/libc.so.6+0x2a1ca)
          iovisor#4 0x007470c7c2a28b __libc_start_main+0x8b (/usr/lib/x86_64-linux-gnu/libc.so.6+0x2a28b)
          iovisor#5 0x00583bca1b2105 _start+0x25 (/home/bojun/alsan/libbpf-tools/a.out+0x1105)

Source code of test program:

  $ cat leak_test.c
  #include <stdlib.h>
  #include <unistd.h>

  int *arr[10000];

  int *foo(size_t size) {
          int *tmp = malloc(size);
          *tmp = 99;
          return tmp;
  }

  int *bar(size_t nmemb, size_t size) {
          int *tmp = calloc(nmemb, size);
          *tmp = 22;
          return tmp;
  }

  int *baz(size_t size) {
          int *tmp = valloc(size);
          *tmp = 11;
          return tmp;
  }

  int main(int argc, char* argv[]) {
          int *a;
          int i = 0;
          while (1) {
                  a = foo(4);
                  arr[i++] = a;
                  a = bar(4, 4);
                  free(a);
                  a = baz(44);
                  sleep(5);
          }
          return 0;
  }
@Bojun-Seo
Copy link
Contributor Author

Rebase and change the tool name from lsan to alsan because lsan is a name that is already in use.
This tool is not lsan, so I changed the name to alsan to make it clear.

@Bojun-Seo
Copy link
Contributor Author

There was a talk about this feature in C++ Now conference.

https://youtu.be/9f5hd-8suVE?si=lOli99myFpExgzac

I hope this video helps people understand this patch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants