Friday, April 25, 2014

PerfView tool for memory analysis


Steps to perform memory analysis:

PerfView is very usefull tool to from Microsoft to analyze, memory and performance issues. In this section we will see how to use PerfView tool to perform memory leak analysis.

1. Collect the full memory dump file for the exe to be investigated.
Use Task manager->Select the process -> Right click Create Dump File. to save the dump. Else use ProcDump.exe with "-ma" option (Available in SysInternals website) to create full memory dump.

2. Open the dump file using PerfView.exe




3. "Dump GC Heap" button shall walk through the heap and start dumping them into .GCHeap File. 

4. If we are debugging Live process then ForceGC, Freeze would options make sense. Anyway now we are checking already collected dump file.

5. Double click on "GCHeap" dump file to view the stack table.



6. Stack table contains various Filter options.

7. Options like Inc, IncCount shall help you to find which object occupies the heap. most of the Array or String used to be on Top of all the  memory allocated. 

8. We could use options like Fold, Drill Into, F10 to see who is really referring this objects.

9. As soon as we know the major reference holding live objects, we should be able to find the root cause.

10. Apart from great table view, PerfView also provide Diff option if we collected the heap snap shots on difference time interval of the same process to find the leaking objects and the root holding the objects.


Sunday, April 6, 2014

Debugging using WinDBG, Root cause finding using WER.

Finding the root cause from WER:

From wer file info, I got 34a5.
               
                                6.1
                                7601 Service Pack 1
                                (0x7): Windows Server 2008 R2 Standard
                                ServerStandard
                                7601.17944.amd64fre.win7sp1_gdr.120830-0333
                                1130
                                Multiprocessor Free
                                X64
                                1033
               
               
                                640
                                C:\Windows\System32\services.exe
                                C:\Windows\system32\services.exe
               
               
                                CLR20r3
                                loggersvc.exe
                                1.0.4668.23049
                                5077f573
                                mscorlib
                                2.0.0.0
                                4ef6c131
                                34a5
                                b2
                                System.IO.IOException
               
               
                                6.1.7601.2.1.0.272.7
                                1033
               
               
                                62F68A02-4CCC-4EFA-B6D6-446950477748
                                Dell Inc.
                                PowerEdge T610
                                2.2.10
               

1.       !token2ee mscorlib_ni 060034a5 – bcoz “06xxxxxx” is standard. – mscorlib is the guy who failed.


O/P:

!token2ee mscorlib 060034a5
0:012> !token2ee mscorlib_ni 060034a5
Module: 000007fef8e91000 (mscorlib.dll)
Token: 0x00000000060034a5
MethodDesc: 000007fef8f0fd00
Name: System.IO.__Error.WinIOError(Int32, System.String)
JITTED Code Address: 000007fef9163fa0


2.       !dumpil 000007fef8f0fd00 – Go to method and also go to b2 since this is the offset


O/P:

ilAddr = 000007fef96dba58
IL_0000: ldarg.0
IL_0001: ldc.i4.s 123
IL_0003: beq.s IL_000f
IL_0005: ldarg.0
IL_0006: ldc.i4 161
IL_000b: ceq
IL_000d: br.s IL_0010
IL_000f: ldc.i4.1
IL_0010: stloc.0
IL_0011: ldarg.1
IL_0012: ldloc.0
IL_0013: call System.IO.__Error::GetDisplayablePath
IL_0018: stloc.1
IL_0019: ldarg.0
IL_001a: stloc.2
IL_001b: ldloc.2
IL_001c: ldc.i4.s 80
IL_001e: bgt.s IL_005f
IL_0020: ldloc.2
IL_0021: ldc.i4.s 15
IL_0023: bgt.s IL_004a
IL_0025: ldloc.2
IL_0026: ldc.i4.2
IL_0027: sub
IL_0028: switch (IL_009a, IL_00d9, IL_025b, IL_011a)
IL_003d: ldloc.2
IL_003e: ldc.i4.s 15
IL_0040: beq IL_019c
IL_0045: br IL_025b
IL_004a: ldloc.2
IL_004b: ldc.i4.s 32
IL_004d: beq IL_01d8
IL_0052: ldloc.2
IL_0053: ldc.i4.s 80
IL_0055: beq IL_021d
IL_005a: br IL_025b
IL_005f: ldloc.2
IL_0060: ldc.i4 183
IL_0065: bgt.s IL_007f
IL_0067: ldloc.2
IL_0068: ldc.i4.s 87
IL_006a: beq IL_01c5
IL_006f: ldloc.2
IL_0070: ldc.i4 183
IL_0075: beq IL_015b
IL_007a: br IL_025b
IL_007f: ldloc.2
IL_0080: ldc.i4 206
IL_0085: beq IL_018c
IL_008a: ldloc.2
IL_008b: ldc.i4 995
IL_0090: beq IL_0255
IL_0095: br IL_025b
IL_009a: ldloc.1
IL_009b: callvirt System.String::get_Length
IL_00a0: brtrue.s IL_00b2
IL_00a2: ldstr "IO.FileNotFound"
IL_00a7: call System.Environment::GetResourceString
IL_00ac: newobj System.IO.FileNotFoundException::.ctor
IL_00b1: throw
IL_00b2: call System.Globalization.CultureInfo::get_CurrentCulture
IL_00b7: ldstr "IO.FileNotFound_FileName"
IL_00bc: call System.Environment::GetResourceString
IL_00c1: ldc.i4.1
IL_00c2: newarr System.Object
IL_00c7: stloc.3
IL_00c8: ldloc.3
IL_00c9: ldc.i4.0
IL_00ca: ldloc.1
IL_00cb: stelem.ref
IL_00cc: ldloc.3
IL_00cd: call System.String::Format
IL_00d2: ldloc.1
IL_00d3: newobj System.IO.FileNotFoundException::.ctor
IL_00d8: throw
IL_00d9: ldloc.1
IL_00da: callvirt System.String::get_Length
IL_00df: brtrue.s IL_00f1
IL_00e1: ldstr "IO.PathNotFound_NoPathName"
IL_00e6: call System.Environment::GetResourceString
IL_00eb: newobj System.IO.DirectoryNotFoundException::.ctor
IL_00f0: throw
IL_00f1: call System.Globalization.CultureInfo::get_CurrentCulture
IL_00f6: ldstr "IO.PathNotFound_Path"
IL_00fb: call System.Environment::GetResourceString
IL_0100: ldc.i4.1
IL_0101: newarr System.Object
IL_0106: stloc.s VAR OR ARG 4
IL_0108: ldloc.s VAR OR ARG 4
IL_010a: ldc.i4.0
IL_010b: ldloc.1
IL_010c: stelem.ref
IL_010d: ldloc.s VAR OR ARG 4
IL_010f: call System.String::Format
IL_0114: newobj System.IO.DirectoryNotFoundException::.ctor
IL_0119: throw
IL_011a: ldloc.1
IL_011b: callvirt System.String::get_Length
IL_0120: brtrue.s IL_0132
IL_0122: ldstr "UnauthorizedAccess_IODenied_NoPathName"
IL_0127: call System.Environment::GetResourceString
IL_012c: newobj System.UnauthorizedAccessException::.ctor
IL_0131: throw
IL_0132: call System.Globalization.CultureInfo::get_CurrentCulture
IL_0137: ldstr "UnauthorizedAccess_IODenied_Path"
IL_013c: call System.Environment::GetResourceString
IL_0141: ldc.i4.1
IL_0142: newarr System.Object
IL_0147: stloc.s VAR OR ARG 5
IL_0149: ldloc.s VAR OR ARG 5
IL_014b: ldc.i4.0
IL_014c: ldloc.1
IL_014d: stelem.ref
IL_014e: ldloc.s VAR OR ARG 5
IL_0150: call System.String::Format
IL_0155: newobj System.UnauthorizedAccessException::.ctor
IL_015a: throw
IL_015b: ldloc.1
IL_015c: callvirt System.String::get_Length
IL_0161: brfalse IL_025b
IL_0166: ldstr "IO.IO_AlreadyExists_Name"
IL_016b: ldc.i4.1
IL_016c: newarr System.Object
IL_0171: stloc.s VAR OR ARG 6
IL_0173: ldloc.s VAR OR ARG 6
IL_0175: ldc.i4.0
IL_0176: ldloc.1
IL_0177: stelem.ref
IL_0178: ldloc.s VAR OR ARG 6
IL_017a: call System.Environment::GetResourceString
IL_017f: ldarg.0
IL_0180: call Microsoft.Win32.Win32Native::MakeHRFromErrorCode
IL_0185: ldarg.1
IL_0186: newobj System.IO.IOException::.ctor
IL_018b: throw
IL_018c: ldstr "IO.PathTooLong"
IL_0191: call System.Environment::GetResourceString
IL_0196: newobj System.IO.PathTooLongException::.ctor
IL_019b: throw
IL_019c: call System.Globalization.CultureInfo::get_CurrentCulture
IL_01a1: ldstr "IO.DriveNotFound_Drive"
IL_01a6: call System.Environment::GetResourceString
IL_01ab: ldc.i4.1
IL_01ac: newarr System.Object
IL_01b1: stloc.s VAR OR ARG 7
IL_01b3: ldloc.s VAR OR ARG 7
IL_01b5: ldc.i4.0
IL_01b6: ldloc.1
IL_01b7: stelem.ref
IL_01b8: ldloc.s VAR OR ARG 7
IL_01ba: call System.String::Format
IL_01bf: newobj System.IO.DriveNotFoundException::.ctor
IL_01c4: throw
IL_01c5: ldarg.0
IL_01c6: call Microsoft.Win32.Win32Native::GetMessage
IL_01cb: ldarg.0
IL_01cc: call Microsoft.Win32.Win32Native::MakeHRFromErrorCode
IL_01d1: ldarg.1
IL_01d2: newobj System.IO.IOException::.ctor
IL_01d7: throw
IL_01d8: ldloc.1
IL_01d9: callvirt System.String::get_Length
IL_01de: brtrue.s IL_01f7
IL_01e0: ldstr "IO.IO_SharingViolation_NoFileName"
IL_01e5: call System.Environment::GetResourceString
IL_01ea: ldarg.0
IL_01eb: call Microsoft.Win32.Win32Native::MakeHRFromErrorCode
IL_01f0: ldarg.1
IL_01f1: newobj System.IO.IOException::.ctor
IL_01f6: throw
IL_01f7: ldstr "IO.IO_SharingViolation_File"
IL_01fc: ldc.i4.1
IL_01fd: newarr System.Object
IL_0202: stloc.s VAR OR ARG 8
IL_0204: ldloc.s VAR OR ARG 8
IL_0206: ldc.i4.0
IL_0207: ldloc.1
IL_0208: stelem.ref
IL_0209: ldloc.s VAR OR ARG 8
IL_020b: call System.Environment::GetResourceString
IL_0210: ldarg.0
IL_0211: call Microsoft.Win32.Win32Native::MakeHRFromErrorCode
IL_0216: ldarg.1
IL_0217: newobj System.IO.IOException::.ctor
IL_021c: throw
IL_021d: ldloc.1
IL_021e: callvirt System.String::get_Length
IL_0223: brfalse.s IL_025b
IL_0225: call System.Globalization.CultureInfo::get_CurrentCulture
IL_022a: ldstr "IO.IO_FileExists_Name"
IL_022f: call System.Environment::GetResourceString
IL_0234: ldc.i4.1
IL_0235: newarr System.Object
IL_023a: stloc.s VAR OR ARG 9
IL_023c: ldloc.s VAR OR ARG 9
IL_023e: ldc.i4.0
IL_023f: ldloc.1
IL_0240: stelem.ref
IL_0241: ldloc.s VAR OR ARG 9
IL_0243: call System.String::Format
IL_0248: ldarg.0
IL_0249: call Microsoft.Win32.Win32Native::MakeHRFromErrorCode
IL_024e: ldarg.1
IL_024f: newobj System.IO.IOException::.ctor
IL_0254: throw
IL_0255: newobj System.OperationCanceledException::.ctor
IL_025a: throw
IL_025b: ldarg.0
IL_025c: call Microsoft.Win32.Win32Native::GetMessage
IL_0261: ldarg.0
IL_0262: call Microsoft.Win32.Win32Native::MakeHRFromErrorCode
IL_0267: ldarg.1
IL_0268: newobj System.IO.IOException::.ctor
IL_026d: throw


I used the below links to find this out.


Debugging .Net applications crash using WinDbg

Commands:

1. .loadby sos clr

This command needed to load the SOS.dll and show you the CLR types and .net call stacks during debugging.

2. !threads
Displays all the threads information.

3. ~ s
Sets the particular thread.

4. !clrstack
Displays the .net callstack.

5.!dumpstack
Displays both native and .net call stack together.

6. ~* e !clrstack
Displays all threads call stack.

7. !pe
prints the exception if any present in the current threads
!pe -nested shall display nested exceptions if present.

8. !dumpheap -stat
Displays the heap status.

9. !dso 
Dumps the stack objects for current threads.

10. !dumpheap -type [Data Type you want to investigate]
Dumps the specified data type from the heap.




Setup for Programming cloud using Google App Engine


How to setup the machine for Cloud programming using Google app engine.

In this section we will see how to setup the machine programming Google app engine for windows using Python 2.7.

1. You need down load and install Python 2.7 version.
Google app engine works with Python2.7 version not Python2.5 version.
You can down the Python from Python.org. Direct download for Win7/8 from python-2.7.6.amd64.msi

2. You need log-in to google devwlopers site and  https://developers.google.com/appengine/downloads.
Down load the MSI and install.

Now you are ready to create the application locally in your machine.



Tuesday, January 5, 2010

Function Pointers

1. Function pointer
2. Function pointer for C++ class member function
3. Function returning function pointer
4. Function pointer passed as argument
5. Array of function pointers


Function pointer

Its a pointer holding the address of a function.

Declaration

Example function declaration - int myFunction(int, float);
Example function pointer - int (*myFuncPtr)(int, float);
Later in the program code assign the address of myFunction to myFuncPtr.
i.e., myFuncPtr = &myFunction;

Sample program

#include "stdafx.h"

//Declare a function
int myFuncAdd(int,int);
int myFuncMultiply(int,int);

//Declare function pointer1
int (*myAddPtr)(int,int);

int main(int argc, char* argv[])
{
myAddPtr = &myFuncAdd;
int result = myAddPtr(10,20);
printf("Added value %d\n",result);

//Using same function pointer for different function.
//You can do this as long as, function signatures are same.
myAddPtr = &myFuncMultiply;
result = myAddPtr(10,20);
printf("Multiplied value using add pointer %d\n",result);

//Declaration of function pointer2
int (*myMulPtr)(int,int) = &myFuncMultiply;
result = myMulPtr(10,20);

printf("Multiplied value %d\n",result);
return 0;
}

int myFuncAdd(int data1,int data2)
{
return data1 + data2;
}

int myFuncMultiply(int data1,int data2)
{
return data1 * data2;
}
-------------------------------------------------------------------------------------------------

Function pointer for C++ class member function
All the non static C++ class member function pointer declaration contains a hidden parameter, which is the "this" pointer of instance of the class. So the function pointer for static member and non-static member are incompatible.

Example declaration
int (MyClass::*myFuncAddPtr)(int,int) = NULL;
Here myFuncAddPtr is a pointer to a function in a class called MyClass, which takes two integers as arguments and returns an integer.

Sample program

#include "stdafx.h"

class myClass
{
public:
int myFuncAdd(int data1,int data2)
{
return data1 + data2;
}
};

//Declare function pointer for myClass::myFuncAdd
int (myClass::*myFuncAddptr)(int,int) = NULL;

int main(int argc, char* argv[])
{
myClass myClassobj;
myFuncAddptr = &myClass::myFuncAdd;
result = (myClassobj.*myFuncAddptr)(20,30);
printf("Added value using C++ function pointers %d\n",result);

return 0;
}
-------------------------------------------------------------------------------------------------
Passing function pointer:
Function pointer can be passed as a argument for a function. Below is the example for passing function pointer.

Returning function pointer:
Function can return pointer to a function. This is bit tricky and confusing....see below for the declaration of the function call which return function pointer.

//Passing function pointer
int PassFuncPtr(int (*myFuncPtr)(int ,int ))
{
return myFuncPtr(10,60);
}

typedef int (*myFuncptr)(int,int);
myFuncptr retPointer()
{
int(*myFuncPtr)(int,int) = &myFuncAdd;
return myFuncPtr;
}

//Function definition with out using type def
int (*retPointer2())(int,int)
{
return &myFuncAdd;
}

inside main()
//Passing function pointer
int (*myFuncPtr)(int,int) = &myFuncAdd;
result = PassFuncPtr(myFuncPtr);
printf("Added value using passing function pointers %d\n",result);

//Returning function pointer
int (*myFuncPtr2)(int,int) = NULL;
myFuncPtr2 = retPointer();
result = myFuncPtr2(20,10);
printf("Added value using returned function pointer %d\n",result);
-------------------------------------------------------------------------------------------------
Array of function pointers: This is also bit tricky and confusing. I feel, using typedef is the easy way to implement array of function pointers.

below code is inside the main()
//Array of function pointers
typedef int (*myArrayFuncPtr)(int,int);
myArrayFuncPtr funcPtrArray[10] = {NULL};

//Without using typedef
int (*myArrayFuncPtr2[10])(int,int) = {NULL};

funcPtrArray[0] = &myFuncAdd;
result = (*funcPtrArray[0])(10,10);
printf("Added value using Array of function pointer %d\n",result);

-------------------------------------------------------------------------------------------------

C Storage classes

Storage classes specifies where the variable need to be created, life time of the variable and scope of the variable.

There are four storage classes supported in C programming language.
1. Auto.
2. Register.
3. Static.
4. Extern.

When discussing about the storage classes, we mainly need to consider the life of the variable, scope of the variable(means is it possible to access this variable this at this point of time?) and storage location of the variable.

1. Auto specifier is the default storage class specifier for variables declared inside a function.
This variable life remains will be with in the scope of the function. i.e, when function scope } ended, this variable will go out of the memory and will not be accessible.

2. Register specifier also similar to auto variable but the storage location is CPU Registers instead of RAM. So the variables can be accessed by the processor quickly compared to the variables stored in RAM. Also it is not guaranteed that register keyword, will store the variable in CPU registers.

"What is the CPU register name which stores the variable when register keyword is used to declare the variable?"

3. Static storage specifier, will create the global variable(i.e life time is till end of the program) which can be accessed only with in the scope of the declaration.
So, when static variable is declared inside a function, then it can be accessed only with in the function, and its value initialized during the first call of the function. Value retained till end of the program. Example usage: 1. Static counters. 2. Avoid localization issues(Hide the variable to outside the scope)

4. Extern storage specifier, indicates that variable might be defined in some other source file and reference of that global variable is declared and used in some other source file.

What is the difference between static and global variables?
Answer1
Variables defined local to a function disappear at the end of the function scope. So when we call the function again, storage for variables is created and
values are reinitialized. So if we want the value to be extent throughout the life of a program, we can define the local variable as "static." Initialization is performed only at the first call and data is retained between func calls.

Had it been gloal variable, it would have been available outside the scope of the function, but static variable is not available outside the scope of a function (helpful in localizing errors - as it can't be changed outside the func
scope).

Answer2
Static and global variable differ a lot in their behaviour to life and scope. First, let me distinguish between life and scope. Life of an object determines whether the object is still in the memory (of the process) whereas scope of the object is whether can I know the variable by its name at this position. It is possible that object is live, but not visible (not in scope) but not that object is not alive but in scope (except for dynamically allocated objects where you refer object through pointers).

Static variables are local in scope to their module in which they are defined, but life is throughout the program. Say for a static variable inside a function cannot be called from outside the function (because it's not in scope) but is alive and exists in memory. The next time this function is entered (within the same program) the same chunk of memory would be accessed now retaining the variables old value and no new memory is allocated this time for this variable like other variables in the function (automatic variables). So basically the variable persists throughout the program. Similarly if a static variable is defined in a global space (say at beginning of file) then this variable will be
accessible only in this file (file scope).

Tuesday, December 22, 2009

.Net Table Layout control

In .Net framework, form controls can be placed and arranged in Table lay out control.
In form application, design time, we can drag and drop the table layout control from the tool box.











Inside the table layout control we can add or remove the rows/column during design time as well as during run time. The key advantage of table layout is, the controls inside the table layout will expand or shrink when user re sizes the form.

The places to which table layout control is applicable:
1. Controls need to be expanded/shrink in proportional manner.
2. Controls and layout that are modified during run time. Ex: Customer entry forms, user can remove some of the controls during run time.
3. Layouts that remain constant size. In that case keep all the controls inside the lay out. And let the layout size the controls appropriately.

The places to which table layout control is not applicable:
1. Places where control need to be anchored in some place with constant size.
2. Places where control need to be docked.