C++ memory leak detection

Post on 22-Jan-2017

276 views 0 download

transcript

C++ Memory leak detection

@Hero

2

Question? What does “memory leak” mean ?

How is memory structure ? What does its consequences ? Why does “memory leak” happen ? How to detect and solve?

3

What does “memory leak” mean ?

First, How is memory structure ?

4

How is memory structure ?

STACK vs HEAP

5

Run-time storage

Code segment:• where the compiled program sits in memory

Global area:• Initialized data segment: store e global,

static and constant data• Uninitialized data segment

Stack segment:• where parameters and local variables are

allocated Heap segment:

• where dynamically allocated variables are allocated

Text segment(Code

segment)

Stack segment

Heap Segment

Data segment

MIPS

6

Stack

Where parameters and local variables are allocated

Limited size Stack overflow

Memory use in stack is temporary and auto release

Fast processing/low size

ParametersReturn Address

where to begin execution

when function exitsDynamic link

pointer to caller's stack frame

Static linkpointer to lexical parent(for nested functions)

Return valueLocal variables

“Concept” Stack frame

Text segment(Code

segment)

Stack frame

Heap Segment

Data segment

Stack frame

7

Heap Large pool of memory Dynamic allocation Stays allocated until

specifically deallocated leak !

Must be accessed through a pointer

Large arrays, structures, or classes should be stored Heap why?

Large & dynamic

ParametersReturn Address

where to begin execution

when function exitsDynamic link

pointer to caller's stack frame

Static linkpointer to lexical parent(for nested functions)

Return valueLocal variables

“Concept” Stack frame

Text segment(Code

segment)

Stack frame

Heap Segment

Data segment

Stack frame

8

Heap vs Stack

int _array[10]; stored in stackStack

_arrayint *_array = new int[n]

• Pointer _array is stored in Stack• Data of array is stored in Heap

_array0x00FF

Stack 10

Heap

0x00FF

0x0005

Value of:● _array : address where int “point” into in heap (0x00FF)● (*_array): value at it's address on heap (10)● (&_array): address of the memory which used for stored pointer _array in stack (0x0005)

Always stored

in stack ?

Any chance to store _array in

heap?

9

FAQ Why we use

Classname *Obj = new Classname();

instead ofClassname Obj;

?

10

Memory leak overview

11

What does memory leaking mean? Definition:

Particular type of unused memory, unable to release Common:

Refer to any unwanted increase in memory usage Different from memory fragmentation

* for heap memory

void Leak(){ int *A = new int[1000]; // some code here // ... // without delete A // return;}

4000 bytes

Return without free A → Leak

12

What does its consequences ? Application gets slow fps Application is crashed Device has been freeze, restarted

13

Why does “memory leak” happen?

First, Let's see some examples

14

Example 0 Forget to release resources No GC mechanic supported

Button is pressed

Save current floor

On target floor ?

Wait until lift is idle

Go to required floor

Release memory used to

save current floor

True

Finished Memory

Leaking here

15

void Fa(){}

void Fb(){}

void Leak(){ int *a = new int[10]; Fa(); Fb(); return;}

void main(){ Leak();}

C/C++ Example 1 Leak memory caused

by lacking of release dynamic memory

…delete a[];return;

Solution

Leak !

16

C/C++ Example 2

Allocation a series, delete only one unit

Leak !for (int i = 0; i < 10; i++){ delete list[i];}delete list;

Solution

void leak(){ int **list = new int*[10]; for (int i = 0; i < 10; i++) { list[i] = new int; }

delete list; return;}

17

C/C++ Example 3

Leak memory when using pointer-return-type

delete []str;

Avoid to call directly GenString()

Solution

char* GenString(){ char *a = new char[10]; a[9] = '\0'; return a;}

void Leak(){ char *str = GenString(); printf("%s\n", str); printf("%s\n", GenString());}

18

#include <cstdio>

void Foo(){ int* a = new int[100]; a = new int[1000];}

void Foo1(){ int* a = new int[100]; int* b = new int[1000]; a = b;}

C/C++ Example 4

Leak memory because of misunderstanding “=” operator in C++

Stack

Heap

ALEAK!

Leak!

C/C++ Example 5

19

void main()

{

Classname *A = new A();

...

...

//free A

A = NULL;

}

Misunderstand how to free memory method in C/C++

Stack

Heap

A

NULL

LEAK!

Keep in mind we are using C/C++ Use MACRO for safe deallocating

#define SAFE_DEL(a) {if(a){delele a;a = 0;}}

Solution

20

C/C++ Example 6 - STLclass Element{ int ID;public: Element(int id) { printf("Created %d at 0x%x\n", id, this); ID = id; } ~Element() { printf("Destroy %d at 0x%x\n", ID, this); }};int main() { list<Element*> m_List; Element *e0 = new Element(0); Element *e1 = new Element(1); //add to list m_List.push_back(e0); m_List.push_back(e1); //clear list printf("-----Before clear-----\n"); m_List.clear(); printf("-----After clear-----\n"); return 0; }

Created 0 addr 0xa719c0Created 1 addr 0xa81a18-----Before clear----------After clear-----

Command prompt

Memory leak here

list

Item 0Item 1

e0

e1

21

C/C++ Example 6 – STL (cont.)

int main() { list<Element*> m_List; Element *e0 = new Element(0); Element *e1 = new Element(1); //add to list m_List.push_back(e0); m_List.push_back(e1); //clear list printf("-----Before clear-----\n"); list <Element*>::iterator i; for (i = m_List.begin(); i != m_List.end(); i++) { delete *i; } m_List.clear(); printf("-----After clear-----\n"); return 0; }

Free data of each element pointer

Created 0 addr 0xb61a28Created 1 addr 0xb71a70-----Before clear-----Destroy 0 addr 0xb61a28Destroy 1 addr 0xb71a70-----After clear-----

Command prompt

Example 7

22

class CB {public: CB(){ m_iVal = 0; } ~CB(){} int m_iVal;};

class CA {public: CA(){ m_pB = 0; } ~CA(){ delete m_pB; m_pB = 0; } CB *m_pB;};

int main(){ CB *B = new CB; CA *A = new CA(); A->m_pB = B; delete(A); printf("%d", B->m_iVal);

}

B

Am_pB

Access violation reading

location ….

Try to remove delete m_pB

23

Example 7 (cont.)

class CB {public: CB(){ m_iVal = 0; } ~CB(){} int m_iVal;};

class CA {public: CA(){ m_pB = 0; } ~CA(){ delete m_pB; m_pB = 0; } CB *m_pB;};

int main(){ CA *A = new CA(); A->m_pB = new CB() delete(A);

}

Am_pB

Leak

Delete or not?

Use manual dealocate m_pB

Solution

24

C/C++ Example 8class cA(){public : cA() {m_pdata = new int[100];} virtual ~cA() {delete[]

m_pdata;} int *m_pdata;};

class cB: public cA(){public cB():cA() {m_pdata2 = new

int[100];} ~cB() {delete []m_pdata2;} int *m_pdata2;}

void main(){ cA *A = new cB(); delete A;}

Memory leak caused by misunderstanding finalization method

Without “virtual”, in this case,m_pdata is not deleted → leak

ALWAYS use virtual for finalization methods

Solution

C/C++ Example 9

25

Using new vs free. Destructor will be NOT invoked after free

class MyClass{public MyClass() { m_pdata2 = new int[100]; } ~ MyClass() { delete []m_pdata2; } int *m_pdata2;}

void main(){ MyClass* p = new MyClass(); free(p);}

Leak here

26

What are reasons of memory leak? Forget/ misunderstand C/C++ mechanism Out-of-Control (logic)

27

Current Solutions For “Forget/ misunderstand C/C++

mechanism” Semi-automatic memory management

Reference Counting Automatic memory management

Tracing Garbage Collection (GC): Java , C # No GC mechanic for C/C++

28

Reference Counter: Good or bad ?

Reference counter: Simple method for memory conflict resolution

Algorithms:• Increase counter when

use as reference• Decrease when release• Delete memory of

counter is zero

class IShareMem{public: IShareMem():m_iRefCounter(1){} virtual ~IShareMem(){} static IShareMem* SetReference(IShareMem* src) { src->m_iRefCounter++; return src; } void Release() { m_iRefCounter--; if (m_iRefCounter <= 0) { delete this; }}private: int m_iRefCounter;};

29

Reference Counter: Good or bad ? Good:

Avoid conflict in memory usage. (See example no.7)

Bad: Cause memory leak if user forget “release” Hard to detect memory leak. Sometimes CAN NOT DETECT LEAK by tool (leak

but not really leak)

30

Current Solutions - Disadvantage Garbage collectors generally can do nothing

about logical memory leaks

0

1

2

n

..

.

Alloc

Alloc

Alloc

Alloc

Which is really needed?A

B

D

E

Z

Do I alloc some-where without

release?

Somethings else is pointed

to an object

31

C/C++How to avoid, detect? Rule:

Remember to release dynamic data (pointer) HARD

Keep our resource in well controlled TOO HARD Detect

By phenomenon on device ? not exactly By review source ? TOO HARD By tool

VC++ memory leak debugging External tool

Cannot detect some cases.

32

C/C++How to solve? Easy to detect, but hard to solve Experience

Organize source and keep it in control Such as a document about resource ?!?

Application Leak log

dataDetect Memory leak Leak

InformationAnalysis

Experience

Knowledge

Fix and test

33

Detect Memory Leak

34

Memory leak – quick detection Windows: use task manager / process tab

Android: adb shell top -m <number_of_record>See VSS, RSS

35

Use Visual studio supported function Use __CrtDumpMemoryLeaks

Advantage Easy to use Fully report about leak when application completed Free

Disadvantage Cannot detect run-time Fail if application Crashed

Presentation: Manually coding by user Use some lib such as VLD

36

Debug in Visual studio

37

VLD Tool http://www.codeproject.com/KB/applications/visualleakdetector.asp

x http://vld.codeplex.com/

Include vld.h in source Add vld.lib

#include "vld.h"#pragma comment(lib, "vld.lib")

38

VLD Tool After finish application normally, memory leak

information will be displayed in output

WARNING: Visual Leak Detector detected memory leaks!---------- Block 3 at 0x006F4F98: 12 bytes ---------- Call Stack: c:\users\ricky.ngk\desktop\testleak\testleak\main.cpp (81): TestLeak.exe!Init + 0x7 bytes c:\users\ricky.ngk\desktop\testleak\testleak\main.cpp (108): TestLeak.exe!main f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (586): TestLeak.exe!__tmainCRTStartup + 0x19 bytes f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c (403): TestLeak.exe!mainCRTStartup 0x76BBED6C (File and line number not available): kernel32.dll!BaseThreadInitThunk + 0x12 bytes 0x772237F5 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0xEF bytes 0x772237C8 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0xC2 bytes Data: 74 A7 DF 00 01 00 00 00 20 60 6F 00 t....... .`o.....Double click the stack to navigate to source

VLD Tool Like any leak detect tools, shows where memory was

allocated without free User have to analyst to find real reason

40

Debug memory leak run-time Use some tool, such as:

Glow code: http://www.glowcode.com/ Memory validator:

http://www.softwareverify.com/cpp-memory.php

Advantage Runtime checking Nice Interface

Disadvantage Not free Not easy to use. Need tutorial

Note: Those tool cannot working well with VLD

The end!

Thanks for your attention

Appendix – Top ten excuses for memory leak A little memory leak is no big thing Nobody will ever find out Complex programs always have memory leak My application Framework is too entangled The memory leak is in the operation system The memory leak is in my third party tools Product development cycles are too fast It’s hard to get good programmer today Leaks and bugs are the price you pay for GUI Everything else leaks, why shouldn’t mine?

http://www.troubleshooters.com/codecorn/memoryleak.htm