When hooks_active = 1, the control flow will be: Malloc() ->malloc_() ->my_malloc_hook() -> __lib_malloc() (->pmm_ioctl() to kernel module).

When hooks_active variable is zero, it will be: Malloc() ->malloc_() -> __libc_malloc().

Kernel module. The pmm is used as a kernel module. The module init() registers the character device, say, pmmdev, and its fops (device open, ioctl, close) structure. The pmm_ioctl() is the main contact point for the module, which has following ioctls:

PMM_RECORD_LOG ioctl for recording the memory request from hook functions. On receipt of malloc or realloc logs, these will be added to the log list. And, on receipt of free log, it will be compared with already logged malloc logs and, when a match is found, both malloc and free logs will be removed from the log list. (Because, the matching pair of malloc and free will not increase the memory footprint of a process.)

PMM_SET_CONFIG ioctl for starting or stopping logging for a particular user process.

PMM_GET_CONFIG ioctl for getting current configuration (kernel thread-execution cycle, etc).

PMM_MONITORED_PIDS for getting the list of monitored user processes.

Initialise proc entry (say, /proc/pmm) for user interaction. Our proc has two entries.

Cfg. Displays the module’s configuration. This is used to start or stop scanning the kernel task structure by our kernel thread and modifying its frequency.

Pid. Used to display logs (memory-allocation logs sent from the user space daemon) to the user.

Fig. 1: Screenshot of the program output
Fig. 1: Screenshot of the program output

Start pmthread, a kernel thread. The thread runs over the kernel task structure to find out whether current monitoring user space daemons are in active or killed state.

Note. The kernel thread can be enhanced to process memory footprint at any point by accessing vm and rss sizes for understanding its overall increase in usage against the time quantum.

For further development
Check for other data members of kernel task_struct structure of user space processes for getting the complete picture of vm and rss sizes, shared library size, CS and DS segment sizes and much more. Using simple math, we can find out the overall memory consumption of processes that can be used for memory-leak alerting.

Hook functions can be separated as shared library so that these become a ready-made solution for developers seeking a programmable memory-leak logger infrastructure.

Download Source Code: click here

Testing procedure
Steps to test involve compilation and verification as a root user from the terminal. Follow the sequence as given below.

1. For compiling our user daemon, issue the following command:

 [stextbox id=”grey”]# gcc pmd.c –o pmd –g –I .[/stextbox]

2. For compiling the kernel module (kernel makefile is included):

 [stextbox id=”grey”]# make[/stextbox]

3. For installing the module, issue the following command:

 [stextbox id=”grey”]# insmod pmm.ko[/stextbox]

4. For starting the daemon, issue the following command:

 [stextbox id=”grey”]# ./pmd[/stextbox]

A typical output of this command run in Ubuntu system is shown in the screenshot above (Fig. 1).

5. For viewing memory request logs, issue the following command:

 [stextbox id=”grey”]# cat /proc/pmm/pid[/stextbox]

Sample output
Some sample outputs are given below. Issue following commands on the terminal:

 [stextbox id=”grey”]# cat /proc/pmm/pid[/stextbox]

The output will be something like this:

 [stextbox id=”grey”][1] PID: 21113, Comp: pmd, PPID: 1,
State: 1, Log count: 2[/stextbox]

This means, the pmm proc is registered by the kernel module. It displays the format of pid file memory logs. (Here, PID of ‘pmd’ process is 21113.)

Issue following commands on the terminal:

 [stextbox id=”grey”]# ./pmd[/stextbox]

The output will be something like this:

 [stextbox id=”grey”]{MALLOC @06:57:11} Sz: 100B Pointer:
0x10012008 Caller: 0x10000e60 main()
207 pmd.c
{REALLOC @06:57:21} Sz: 200B
Prev Pointer: 0x10012008 Pointer:
0x10012008 Caller: 0x10000e84 main()
209 pmd.c[/stextbox]

The meanings of these outputs are given below.

type of log. {@}

Sz.

Pointer.

Caller.

Location. function-name, line-number and file-name.

The above details will give user the system status and health conditions.

To stop the process, issue following commands:

 [stextbox id=”grey”]#ps -ef | grep pmd
root 20604 2 0 06:27 ? 00:00:00
[pmthread]
root 21113 1 0 06:30 ? 00:00:00 ./pmd[/stextbox]

Issue the following commands on the terminal:

 [stextbox id=”grey”]# cat /proc/pmm/cfg[/stextbox]

The output will be something like this:

 [stextbox id=”grey”]Configs:
[“INTERVAL” (Scan Interval) :=10000]
[“SCAN” (Scan on:1/off:0) := 1]
[“START_PID” (Start a monitor):=21113]
[“STOP_PID” (Stop a monitor) := 0][/stextbox]

This output displays configuration objects including interval, scanning and start-and-stop status.

For exanokem INTERVAL configuration is currently set to 10000ms and this can be changed using the following command:

 [stextbox id=”grey”]

#Printf “INTERVAL 5000” >> /proc/pmm/cfg

[/stextbox]

To start monitoring on a PID, use the following command:

 [stextbox id=”grey”]#Printf “START_PID >> /proc/
pmm/cfg[/stextbox]


L. Karthikeyan is B.E. (computer science) from AC Tech, Karaikudi. He is working as a technical lead, HCL Technologies, Chennai. He likes to read and write articles related to computer science and finance

SHARE YOUR THOUGHTS & COMMENTS

Please enter your comment!
Please enter your name here