{"action":"closed","issue":{"url":"https://api.github.com/repos/SimonKagstrom/kcov/issues/122","labels_url":"https://api.github.com/repos/SimonKagstrom/kcov/issues/122/labels{/name}","comments_url":"https://api.github.com/repos/SimonKagstrom/kcov/issues/122/comments","events_url":"https://api.github.com/repos/SimonKagstrom/kcov/issues/122/events","html_url":"https://github.com/SimonKagstrom/kcov/issues/122","id":117146405,"number":122,"title":"Big memory leak with shared memory","user":{"login":"jbatmall","id":12907635,"avatar_url":"https://avatars.githubusercontent.com/u/12907635?v=3","gravatar_id":"","url":"https://api.github.com/users/jbatmall","html_url":"https://github.com/jbatmall","followers_url":"https://api.github.com/users/jbatmall/followers","following_url":"https://api.github.com/users/jbatmall/following{/other_user}","gists_url":"https://api.github.com/users/jbatmall/gists{/gist_id}","starred_url":"https://api.github.com/users/jbatmall/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jbatmall/subscriptions","organizations_url":"https://api.github.com/users/jbatmall/orgs","repos_url":"https://api.github.com/users/jbatmall/repos","events_url":"https://api.github.com/users/jbatmall/events{/privacy}","received_events_url":"https://api.github.com/users/jbatmall/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/SimonKagstrom/kcov/labels/dwarf/ptrace","name":"dwarf/ptrace","color":"5319e7"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":7,"created_at":"2015-11-16T15:17:11Z","updated_at":"2015-11-19T09:26:49Z","closed_at":"2015-11-19T09:26:49Z","body":"Hi,\r\n\r\nI have a big memory leak when I used a shared memory\r\n\r\n#### Environnement\r\nOperating system : centos 6.6 (kernel 2.6.32-504) x86_64\r\n\r\n#### Reproduction\r\nReproduced with version 29 of kcov but the problem also occurs with the latest snapshot\r\n\r\n### Report\r\nI'm developing a dynamic shared library (.so) and snmpd (net-snmp daemon) use it.\r\nThis library created a many pthread and fork (about 20 pthread and 20 fork every 4 seconds) to collect data\r\n\r\nBut when I launched snmpd with kcov\r\n```\r\nkcov --include-path=/src_path /tmp/output /usr/sbin/snmpd -f -A -LS 0-5 0 -p /var/run/snmpd.pid -a\r\n```\r\nI have seen an increase in the memory used by kcov to saturation of memory (RAM and swap)\r\n```\r\nTasks: 301 total,   2 running, 297 sleeping,   1 stopped,   1 zombie\r\nCpu(s):  0.3%us,  8.3%sy,  0.0%ni, 91.4%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st\r\nMem:  16221228k total, 16052524k used,   168704k free,   460020k buffers\r\nSwap: 16777212k total,        0k used, 16777212k free,  4495416k cached\r\n\r\n   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                          \r\n110313 root      20   0 10.3g  10g 3860 R 99.5 65.8   1:20.93 kcov                                                                                                                                            \r\n110081 root      20   0  172m  66m  40m S  0.0  0.4   0:07.05 Xorg                                                                                                                                             \r\n111374 root      20   0  251m  28m  15m T  1.0  0.2   0:00.01 nvidia-settings                                                                                                                                  \r\n110315 root      20   0  921m 9892 5804 S  0.0  0.1   0:00.16 snmpd                                                                                                                                            \r\n 58305 root      20   0 98.1m 6412 3388 S  0.0  0.0   0:00.50 sshd                                                                                                                                             \r\n  1806 haldaemo  20   0 39180 5692 4176 S  0.0  0.0   0:03.23 hald                                                                                                                                             \r\n  6615 root      20   0 98368 4384 3388 S  0.0  0.0   0:00.43 sshd                                                                                                                                             \r\n 48296 root      20   0 98368 4384 3388 S  0.0  0.0   0:00.18 sshd                                                                                                                                             \r\n136879 root      20   0 98368 4384 3388 S  0.0  0.0   0:01.02 sshd                                                                                                                                             \r\n132486 root      20   0 98368 4380 3388 S  0.0  0.0   0:00.83 sshd                                                                                                                                             \r\n 80262 root      20   0 98368 4364 3388 S  0.0  0.0   0:12.86 sshd         \r\n```\r\n\r\n### Additional information\r\nkcov reload one library many time (libnividia-glcore.so.346.47 - size 40Mo - used when I run nvidia-settings command for collect data)\r\nbut I think that this issues is not related to this lib\r\n\r\nWhen running kcov with --debug=30, the following message appears:\r\n```\r\nPT stopped PID 118669 0x0000137f\r\nPT BP at 0x7ffff70ceb1c:-1 for 118669\r\nCan't find breakpoint at 0x7ffff70ceb1c\r\nPT continuing 118669 with signal 0\r\nPT stopped PID 118670 0x0000137f\r\nPT BP at 0x7ffff70ceb1c:-1 for 118670\r\nCan't find breakpoint at 0x7ffff70ceb1c\r\nPT continuing 118670 with signal 0\r\nPT stopped PID 118669 0x0000057f\r\nPT BP at 0x7ffff7dddaff:-1 for 118669\r\nCan't find breakpoint at 0x7ffff7dddaff\r\nPT continuing 118669 with signal 0\r\nPT stopped PID 118670 0x0000057f\r\nPT BP at 0x7ffff7dddaff:-1 for 118670\r\nCan't find breakpoint at 0x7ffff7dddaff\r\nNo debug symbols in /usr/lib64/libnvidia-glcore.so.346.47.\r\nPT continuing 118670 with signal 0\r\nPT stopped PID 118669 0x0000057f\r\nPT BP at 0x7ffff77dbce9:-1 for 118669\r\nCan't find breakpoint at 0x7ffff77dbce9\r\nNo debug symbols in /usr/lib64/libnvidia-glcore.so.346.47.\r\nPT continuing 118669 with signal 0\r\nPT stopped PID 118670 0x0000057f\r\nPT BP at 0x7ffff77dbce9:-1 for 118670\r\nCan't find breakpoint at 0x7ffff77db\r\n```\r\n\r\n#### Fix found\r\nAfter looking the source code and conducting tests I found a fix that solves my problem but I'd like to have your opinion\r\n\r\nIn file \"src/parsers/elf-parser.cc\"\r\n\r\nFunction parseOneElf\r\n```\r\n\t\t\tSegment seg(fileData + sh_offset, sh_addr, sh_addr, sh_size);\r\n\t\t\t// If we have segments already, we can safely skip this\r\n\t\t\tif (setupSegments)\r\n\t\t\t\tm_curSegments.push_back(seg);\r\n\t\t\tm_executableSegments.push_back(seg);\r\n\t\t}\r\n\t\tret = true;\r\n        free(fileData);  // MY FIX\r\nout_elf_begin:\r\n\t\telf_end(m_elf);\r\n\t\treturn ret;\r\n\t}\r\n```\r\n##### Analysis\r\n\r\nIn file \"src/parsers/elf-parser.cc\"\r\nm_executableSegments is an attribute of the class ElfInstance\r\n```\r\n817 : SegmentList_t m_executableSegments\r\n```\r\nwhere SegmentList_t is a std::vector<Segment> and Segment is a class (file src/include/file-parser.hh)\r\n\r\nm_executableSegments is used in functions addressIsValid,parseOneElf and addFile\r\n\r\nIt's filled in function parseOneElf (src/parsers/elf-parser.cc)\r\n```\r\n\t\t\tSegment seg(fileData + sh_offset, sh_addr, sh_addr, sh_size); \r\n\t\t\t// If we have segments already, we can safely skip this\r\n\t\t\tif (setupSegments)\r\n\t\t\t\tm_curSegments.push_back(seg);\r\n\t\t\tm_executableSegments.push_back(seg);\r\n```\r\n\r\nFor remember (file src/include/file-parser.hh)\r\n```\r\n\t\t\tSegment(const void *data, uint64_t paddr, uint64_t vaddr, uint64_t size) :\r\n\t\t\t\tm_data(data), m_paddr(paddr), m_vaddr(vaddr), m_size(size)\r\n\t\t\t{\r\n\t\t\t}\r\n```\r\n\r\nIn addFile (src/parsers/elf-parser.cc)\r\n```\r\n118 : m_executableSegments.clear();\r\n```\r\n\r\nClear function calls the destructor of Segment Class\r\nIt destroys all Segments objects but can't destroy fileData (cf elf-parser.cc:475) because Segment class store only char* pointer (m_data)\r\nfileData is an pointer created by \"read_int\" function (cf src/utils.cc)\r\n\r\n### Conclusion\r\n\r\nI'm not sure to my fix because the addressIsValid function (which use m_executableSegments) is called in parseOneDwarf\r\n\r\nWhat are you thinking about ?"}}