We have a program, that using IPC waits until it receives a message. When the program receives a message, it process it, calls some stored procedures in a database and then returns an answer.
One of our clients noticed that every time we receive a message, the memory usage is increased in 20kb. This program is supposed to process more than a million messages a day, so I was tasked with fixing this leak.
The problem is that the program isn't a basic executable, but runs in a proprietary application server, and uses proprietary libraries for almost anything. Because of this, I can't run the program by itself, which makes it impossible to run programs like valgrind.
I created a simple function to read the current memory usage, and spammed it everywhere, but when I went to the code, it was just a function call.
Code to check memory usage.
void PrintMemory(char *msg) {
PREPARELOG(PrintMemory);
FILE *fp = fopen("/proc/self/statm", "r");
if(fp == NULL) {
LOG(FAI, "[PrintMemory] Cant open /proc/self/statm");
return;
}
long rss;
fscanf(fp, "%*lu %ld", &rss);
fclose(fp);
LOG(NOT, "[PrintMemory] [%-30s] [%ld]", msg, rss);
}
Where PREPARELOG
is a macro that sets some variables for the LOG
macro.
After checking the log I see this:
[...]
[PrintMemory] [Function 1 end ] [32633].
[PrintMemory] [Function 2 init ] [32637].
[...]
Looking at the code, I see this:
ret = Function1(param);
PrintMemory("Function 1 end");
if (ret == 0) {
Function2(¶m1, ¶m2, param3, param4);
}
int Function2(int *param1, int *param2, char *param3, struct name* param4) {
PREPARELOG(Function2);
PrintMemory("Function 2 init");
[...]
}
Checked the assembly of it just in case and saw this:
call PrintMemory #Function 1 end
.loc 1 282 0
movl -28(%rbp),