Jun 202017
 

What’s a Heap?

Before understanding HeapCorruption here’s a quick review of the Heap. The HeapCreate function creates a private heap object from which the calling process can allocate memory blocks by using the HeapAlloc function. HeapCreate specifies both an initial size and a maximum size for the heap. The initial size determines the number of committed, read/write pages initially allocated for the heap. The maximum size determines the total number of reserved pages. These pages create a contiguous block in the virtual address space of a process into which the heap can grow. Additional pages are automatically committed from this reserved space if requests by HeapAlloc exceed the current size of committed pages, assuming that the physical storage for it is available. Once the pages are committed, they are not decommitted until the process is terminated or until the heap is destroyed by calling the HeapDestroy function.

We don’t directly interact with this function but internally the boiler plate application code does this, for e.g. CRT heap. When we use ‘new’, ‘malloc’, internally somewhere there’s a call happening to HeapAlloc. When we call ‘delete’ or ‘free’ internally somewhere there’s a call happening to HeapFree.

So what’s HeapCorruption?

Any inconsistency that’s caused to a process heap because of application code can be called a HeapCorruption. For e.g. Since most of the time the heap memory blocks are in the form of a linked list, linked to each other, so if we end up overwriting these links then we call that a heap corruption because the heap cannot be traversed anymore from one linked list node to the other.

We could see an application crashing with following error…

0:143> .lastevent
Last event: 616c.a550: Unknown exception – code c0000374 (first/second chance not available)
debugger time: Tue Jun 13 12:41:19.531 2017 (UTC – 5:00)

0:143> !error c0000374
Error code: (NTSTATUS) 0xc0000374 (3221226356) – A heap has been corrupted.

But in my case even though application crashed due to c0000374 and when I check the reason for HeapCorruption, I got the following…

Error type: HEAP_FAILURE_INVALID_ARGUMENT

So essentially the heap is not corrupted but we passed an invalid argument for heap free function hence this failure. So how do I verify that this is indeed the reason? So, we pick up the address that was passed on to HeapFree function and then analyze it using the !address command…

0:143> !address 0x0000003c`5cec97a8

Usage: Stack
Base Address: 0000003c`5ceae000
End Address: 0000003c`5ced0000
Region Size: 00000000`00022000 ( 136.000 kB)
State: 00001000 MEM_COMMIT
Protect: 00000004 PAGE_READWRITE
Type: 00020000 MEM_PRIVATE
Allocation Base: 0000003c`5ce50000
Allocation Protect: 00000004 PAGE_READWRITE
More info: ~143k
Content source: 1 (target), length: 6858

If we look at above output, usage shows as stack memory, which should never be freed via Heap functions but instead they’re automatically released at the end of usage scope. Lets now look at another address which is located on the Heap…

0:143> !address 0x0000003c`6acbfc00

Usage: Heap
Base Address: 0000003c`6a930000
End Address: 0000003c`6af17000
Region Size: 00000000`005e7000 ( 5.902 MB)
State: 00001000 MEM_COMMIT
Protect: 00000004 PAGE_READWRITE
Type: 00020000 MEM_PRIVATE
Allocation Base: 0000003c`6a220000
Allocation Protect: 00000004 PAGE_READWRITE
More info: heap owning the address: !heap 0x3c74e70000
More info: heap segment
More info: heap entry containing the address: !heap -x 0x3c6acbfc00

Content source: 1 (target), length: 257400

The above memory block is owned by a heap hence this can be freed via HeapFree Windows API and we should not get the HEAP_FAILURE_INVALID_ARGUMENT error. The error  ‘HEAP_FAILURE_INVALID_ARGUMENT’ can be further proved by following output from an internal extension command output…

**************************************************************
*                                                            *
*                    HEAP ERROR DETECTED                     *
*                                                            *
**************************************************************

Details:

Heap address: 0000003c74e70000
Error address: 0000003c5cec97a8
Error type: HEAP_FAILURE_INVALID_ARGUMENT

Details: The caller tried to a free a block at an invalid (unaligned) address.

Oct 292014
 

What’s Z7 and Zi?

These are compiler switches which tells the compiler where to dump debugging information collected from a C/C++ source file during compilation. Z7 tells the compiler to dump debugging information into a .obj file. Zi tells the compiler to dumps debugging information into an intermediate .pdb file.

What’s the Difference between Z7 and Zi?

Regarding Z7…

This option produces a .obj file containing full symbolic debugging information for every C/C++ source compiled for use with the linker. The symbolic debugging information includes the names and types of variables, as well as functions and line numbers. .Obj files get bigger in size because of the debugging information dumped in by the compiler into this file and then bloats your disk. /Z7 is based on the old code view format. This option introduces additional burden on the linker to parse every .obj file for debugging information. These .obj files will then be collated into a one .pdb file which will normally be named after the executable file name during linking phase.

Advantages of using Z7 switch
  • Good thing here is that there is no contention to write to one file (as you’ll see below).
  • Every .cpp file will have its own debugging information which will eventually be collated by the linker.
Disadvantages of using Z7 switch
  • Downside being the time taken to link, size of files on disk and old format.
  • Minimal rebuild feature (/Gm) will not work if /Z7 is enabled. You’ll get following warning…
    Command line warning D9007: ‘/Gm’ requires ‘/Zi or /ZI’; option ignored
  • The biggest disadvantage of Z7 is that this format doesn’t allow Edit and Continue, well this matters if you use this feature at all?
During Debugging what’s the effect of Z7 switch?

When debugging the debugger will tell us from where it has loaded a pdb file for a binary that its debugging. It loads the pdb file generated by the Linker which is unaffected by either /Zi or /Z7. Please see highlighted path of .pdb file from the debugger. So yes linker generates .pdb file which is the final .pdb file.

ConsoleApplication4.exe .\ConsoleApplication4.exe Symbols loaded. .\ConsoleApplication4.pdb 00E50000-00E70000 [5476] ConsoleApplication4.exe: Native

Demo

With /Z7 enabled you’ll see following list of files in your intermediate folder, note the size of .obj files…

10/23/2014  06:07 PM               136 ConsoleApplication4.res
10/23/2014  06:07 PM               348 ConsoleApplication4.log
10/23/2014  06:07 PM             2,473 ConsoleApplication4.Build.CppClean.log
10/23/2014  06:07 PM           117,615 ConsoleApplication4.obj
10/23/2014  06:07 PM         4,920,987 stdafx.obj
10/23/2014  06:07 PM        36,175,872 ConsoleApplication4.pch

Please compare above size of .obj files with below output files generated when /Zi is enabled.

Regarding Zi…

The compiler writes debugging information to one centralized file. The compiler names the program database named VCx0.pdb (or what you’ve configured it to be named), where x is the major version of Visual C++ in use.

Advantages of using Zi
    • When you use this option, your .obj files will be smaller, because debugging information is stored in the .pdb file rather than in .obj files.
    • Easy on the linker. It just has one file to parse to figure out debugging information for a binary that’s linking up.
    • Duplicate debugging information doesn’t make into the .pdb file generated by the compiler since its now working on one .pdb file instead of multiple .obj files where it doesn’t maintain a list of symbols generated to figure out duplicate ones.
    • Minimal Rebuild (/Gm) will work only work with /Zi or /ZI.
    • Advanced debugging features like Edit and Continue (/ZI) will work (making code changes when debugging, the changes are then built and we continue debugging again without stopping the debugging session). Sample effect on the debugger when a code change is done when debugging with Edit and Continue enabled…

clip_image002

——– Edit and Continue build started ——–

——————— Done ———————-

Disadvantages of using Zi
  • High contention to write to the one .pdb file as we’ve parallel builds running. Some machines will have several parallel builds configured.
Demo

With Zi enabled you’ll see following list of files generated. Take a note of sizes for the .obj files. Note that now we’ve got a

10/23/2014  06:00 PM               136 ConsoleApplication4.res
10/23/2014  06:00 PM               192 ConsoleApplication4.log
10/23/2014  06:00 PM             2,473 ConsoleApplication4.Build.CppClean.log
10/23/2014  06:00 PM           103,106 ConsoleApplication4.obj
10/23/2014  06:00 PM           933,490 stdafx.obj
10/23/2014  06:00 PM         1,551,360 vc120.idb
10/23/2014  06:00 PM         4,239,360 vc120.pdb <<<-- This is the pdb that the compiler generates, which contains debugging information from all the cpp files (path is generated using following pattern: $(IntDir)vc$(PlatformToolsetVersion).pdb). Now .obj files will not have debugging information. Compare their sizes with earlier output.
10/23/2014  06:00 PM        36,896,768 ConsoleApplication4.pch

When debugging the debugger tells exactly from where a pdb file is loaded. It loads the pdb file generated by the Linker which is unaffected by either /Zi or /Z7. Please see highlighted path of .pdb file from the debugger. So yes linker generates .pdb file which is the final .pdb file.

ConsoleApplication4.exe .\ConsoleApplication4.exe  Symbols loaded. .\ConsoleApplication4.pdb [4660] ConsoleApplication4.exe: Native

What’s the effect of these options when debugging in Visual Studio or a crash dump?

As far as debugging is concerned there is zero effect as the linker will eventually generate one final pdb file which is controlled by the linker switch: /DEBUG.

clip_image003

The compiler only generates an ‘intermediate’ .pdb file which contains debugging information collected during compilation which the linker will then eventually dump to a ‘final’ .pdb file. So all that you should be worried is the final .pdb file generated by the linker. This .pdb file is placed alongside the executable. This is the .pdb file that will be used when debugging the application or crash dumps.

So you might ask what if we disable .pdb generation in the compiler settings? Well then your code breakpoints will not hit. The breakpoints will be disabled since the linker couldn’t figure symbols for your code as the compiler didn’t generate any!

Please let me know if you have further questions?

Oct 142014
 

Introduction to MiniDumpWriteDump

In this post, let me show you some sample code to create a full memory dump of any given process using the Windows API MiniDumpWriteDump.

Creating Full Memory Dumps using MiniDumpWriteDump

Here’s some sample code to create a full memory dump of any given process. Just call WriteFullDump(hProcessHandle). This process handle must have PROCESS_QUERY_INFORMATION and PROCESS_VM_READ access to the process. If handle information is to be collected then PROCESS_DUP_HANDLE access is also required.

Please test out before production use. Just some quick code that I was writing up for a customer.

#include <tchar.h>
#include <windows.h>
#include <DbgHelp.h>

using namespace std;

#pragma comment (lib, "dbghelp.lib")

void WriteFullDump(HANDLE hProc)
{
   const DWORD Flags = MiniDumpWithFullMemory |
   MiniDumpWithFullMemoryInfo |
   MiniDumpWithHandleData |
   MiniDumpWithUnloadedModules |
   MiniDumpWithThreadInfo;

   HANDLE hFile = CreateFile(_T("F:\\main.dmp"), GENERIC_ALL, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
   if (!hFile)
   {
     std::cerr << _T("Failed to write dump: Invalid dump file");
   }
   else
   {
     BOOL Result = MiniDumpWriteDump( hProc,
                                      GetProcessId(hProc),
                                      hFile,
                                      (MINIDUMP_TYPE)Flags,
                                      nullptr,
                                      nullptr,
                                      nullptr );

     CloseHandle(hFile);

     if (!Result)
     {
        std::cerr << _T("Looks like an error: MiniDumpWriteDump failed") ;
     }
   }// End if

   return;
}

Significance of MiniDumpWriteDump flags

What gets into a process’ memory dump is determined by the flags we pass in to MiniDumpWriteDump API. The code that I’ve given produces the biggest dumps possible for a process. The output dump file in this case will have the entire process’ memory, modules, registers, thread information, unloaded module information, and process handle related information.

For our case we’ve given these five flags, this will just basically copy everything from a process’ virtual address space into a dump. Comment out any flags if you’re not interested in that information, for e.g. if you don’t need information on the handles in a process just comment out: MiniDumpWithHandleData.

MiniDumpWithFullMemory |
MiniDumpWithFullMemoryInfo |
MiniDumpWithHandleData |
MiniDumpWithUnloadedModules |
MiniDumpWithThreadInfo;

References

http://msdn.microsoft.com/en-us/library/windows/desktop/ms680360(v=vs.85).aspx

Sep 102014
 

Issue

Recently a colleague asked this question. They had a customer who was experiencing a heap corruption so as expected we enabled PageHeap but there was a catch. The application had to run for a long time (around 30 days) in order to reproduce the crash and we had no idea what’s causing the crash.

How do we enable PageHeap?

We can enable standard PageHeap using following command run from an admin command prompt: gflags /p /enable ImageFileName
To enable full PageHeap use the following: gflags /p /enable ImageFileName /full 

(MSDN) Use care in interpreting the Enable page heap check box for an image file in the GFlags dialog box. It indicates that page heap verification is enabled for an image file, but it does not indicate whether it is full or standard page heap verification. If the check results from selecting the check box, then full page heap verification is enabled for the image file. However, if the check results from use of the command-line interface, then the check can represent the enabling of either full or standard page heap verification for the image file.

Why application hung?

So customer enabled PageHeap and went home. Came back next day to see that the application has stopped responding and is hung. The application hung apparently after enabling PageHeap and as we know of PageHeap: every allocation is paged to the page file. So guess why would the hang take place? PageFile size!

Resolution

The customer had set PageFile to its default size which apparently was not enough in this case. We suggested to increase the PageFile size and the hang went away. This resolved the issue. Note that if you enable PageHeap and then go home no matter what’s the PageFile size eventually the result will be unpredictable as the PageFile size is finite. You might need to tweak your PageHeap settings and make it per module or non-full standard page heap.

Conclusion

Please note there are different variants of PageHeap. In this case we needed a full PageHeap so please note this will be pretty heavy on the PageFile.

Aug 272014
 
What is a Symbol?

When you compile your executable the compiler generates debugging symbol information for every file it compiles and then linker assembles all of these symbol information into one file called PDB file or the Program DataBase file. Every variable, function in your application code can be called as a symbol which implies there will be private and public symbols.

This generated .pdb file’s full local path is embedded into the executable file. This comes in handy while you are debugging this application on your development machine. The PDB file will be picked up by the debugger since full path to the PDB is embedded into the executable by the linker. This will help the debugger figure, line numbers, file names, callstacks, local and global vars.

Why do we need Symbols?

Symbol file or .pdb file contains information which are actually not needed when you run your application but these come in handy when debugging application for bugs. Without pdb files or symbol files figuring out bugs or exact callstacks will be a pain on Windows. If that’s the case you might ask then why is this information not embedded into the executable? The answer is symbols are not always needed hence they are dumped into a separate file called .pdb so that you can debug when needed and also you can choose who see’s what symbols in turn making it hard for people to reverse engineer your code.

What does a PDB file contain?

They can contain a variety of information. For e.g.

  • Source code information: Line numbers, file names
  • Variables: Global and Local variables mapped to their addresses
  • Function names mapped to their addresses
  • FPO information to get correct call stack.
  • etc

Windows Debugger installation contains utilities to check out a PDB file namely: symchk, agestore, symstore, pdbcopy etc.

Public and Private Symbols

When linker generates a PDB file it contain both private and public debugging symbol information. Of course you can configure what it generates in the linker property pages.

Private symbol data contains following (mostly)

  • Global and Local Variables.
  • Functions
  • All user defined types.
  • Line number and source file information.

Public symbol table contains following…

  • Functions (just the address)
  • Global variables that are visible across obj files.

As you might have inferred private symbol files will be bigger in size compared to public symbols files. Also since private symbol file contains public symbols information as well, we can generate a separate public symbol file from this private symbols file. We use a tool called pdbcopy.exe for this purpose, comes with the windows debugger installation.

Symbol Path

So how do we tell the debugger where to look for symbols. One of my favorites is to use the environment variable_NT_SYMBOL_PATH. This variable provides us the flexibility to specify cache directories for downloaded symbols, we can even specify per symbol server cache directory.

Following value for _NT_SYMBOL_PATH downloads symbols from the server and puts into C:\Symbols folder.

cache*c:\Symbols;SRV*http://symbolserver;srv*http://anotherserver;srv*http://onemoreserver

Following value for _NT_SYMBOL_PATH downloads symbols from the server and puts into C:\Symbols folder and downloads symbols from http://anotherserver to c:\anotherserver_cache_folder.

cache*c:\Symbols;SRV*http://symbolserver;srv*c:\anotherserver_cache_folder*http://anotherserver

Windows debugger provides commands to controls symbol path, .sympath, .symfix. I use .symfix to quickly setup a default symbol path and symbols will be downloaded to a sym folder under the debugger folder. While .sympath is a cool command. If you would quickly add a symbol path to the debugger, just do the following…

.sympath+ C:\AnotherSymbolFolder
.reload

Controlling Symbol Loading in Windows Debugger

The debugger provides a command called .symopt. If we run the command without any arguments its shows our current symbol loading settings, for e.g.

Output from .symopt

So we see in this case we’ve configured to load line number information, and since we haven’t said SYMOPT_PUBLICS_ONLY, then private symbols are loaded. SYMOPT_AUTO_PUBLICS tells debugger to look for public symbols only as a last resort.

More information on symbols loading options can be found here: http://msdn.microsoft.com/en-us/library/windows/hardware/ff558827(v=vs.85).aspx

Along with this to see a list of modules for which symbol loading failed use command ‘lme’. To get a verbose output of the symbol loading process in the debugger use “!sym noisy” to turn it off use “!sym quiet”.

Conclusion

Always keep your symbols handy. Never know when you might need them.

Aug 052014
 

What are DateTime Custom Formatters?

A date and time format string defines the text representation of a DateTime or DateTimeOffset value that results from a formatting operation . It can also define the representation of a date and time value that is required in a parsing operation in order to successfully convert the string to a date and time. A custom format string consists of one or more custom date and time format specifiers. Any string that is not a standard date and time format string is interpreted as a custom date and time format string.

Custom date and time format strings can be used with both DateTime and DateTimeOffset values.

Issue with DateTime Custom Formatters?

Recently a customer opened a ticket thinking that there is an issue with the DateTime Custom Formatters. They had following piece of code.

namespace DateTimeDefect
{
 class Test
 {
   static void Main(string[] args)
   {
     DateTime dt = DateTime.Now;

     Console.WriteLine(dt.ToString("f"));
     Console.WriteLine(dt.ToString("ff"));
     Console.WriteLine(dt.ToString("fff"));

     Console.ReadLine();
   }
 }
}

Except for dt.ToString(“f”) the other two ToString calls were returning correct results. Here’s the output…

Friday, May 30, 2014 12:53 AM (Here’s the issue, customer expects a numeric value as shown below)
53
534

Here’s what MSDN says about custom formatter ‘f’, ‘ff’, ‘fff’.

“f”: The tenths of a second in a date and time value. More information: The “f” Custom Format Specifier.

Sample:
6/15/2009 13:45:30.617 -> 6
6/15/2009 13:45:30.050 -> 0

“ff”: The hundredths of a second in a date and time value. More information: The “ff” Custom Format Specifier.

Sample:
6/15/2009 13:45:30.617 -> 61
6/15/2009 13:45:30.005 -> 00

“fff”: The milliseconds in a date and time value. More information: The “fff” Custom Format Specifier.

Sample:
6/15/2009 13:45:30.617 -> 617
6/15/2009 13:45:30.0005 –> 000

 So what’s going wrong here with DateTime Custom Formatters

The issue here is that dt.ToString(“f”) is not recognized as a custom format specifier. Please read below documentation from MSDN…

A custom date and time format string consists of two or more characters. Date and time formatting methods interpret any single-character string as a standard date and time format string. If they do not recognize the character as a valid format specifier, they throw a FormatException. For example, a format string that consists only of the specifier “h” is interpreted as a standard date and time format string. However, in this particular case, an exception is thrown because there is no “h” standard date and time format specifier.

To use any of the custom date and time format specifiers as the only specifier in a format string (that is, to use the “d”, “f”, “F”, “g”, “h”, “H”, “K”, “m”, “M”, “s”, “t”, “y”, “z”, “:”, or “/” custom format specifier by itself), include a space before or after the specifier, or include a percent (“%”) format specifier before the single custom date and time specifier.

For example, “%h” is interpreted as a custom date and time format string that displays the hour represented by the current date and time value. You can also use the ” h” or “h ” format string, although this includes a space in the result string along with the hour. The following example illustrates these three format strings.

Resolution

So in this case the date time formatting method is interpreting this single character string as a standard date and time format string. To work around this, following are the options that you have…

1. Use dt.ToString(“%f”)
2. Use dt.ToString(“ f”);// add a space before ‘f’
3. Use dt.ToString(“f ”);// add a space after ‘f’

So if we change above code to…

static void Main(string[] args)
{
  DateTime dt = DateTime.Now;
  Console.WriteLine(dt.ToString("%f"));
  Console.WriteLine(dt.ToString("ff"));
  Console.WriteLine(dt.ToString("fff"));
  Console.ReadLine();
}

Now program output looks as follows…

8
87
873

Based on last value output you can verify the first two. Issue resolved.

Aug 052014
 

Just saw this (.NET Reference Source)… (totally cool) J

http://referencesource.microsoft.com/

Channel nine video: http://channel9.msdn.com/Series/NET-Framework/How-to-browse-the-NET-Reference-Source

Further details on our blog: http://blogs.msdn.com/b/dotnet/archive/2014/02/24/a-new-look-for-net-reference-source.aspx

Feb 242014
 

Recently had a customer who faced this issue when his application is run from a network share. The exception information is as follows …

************** Exception Text **************

System.Configuration.ConfigurationErrorsException: An error occurred creating the configuration section handler for dataConfiguration: That assembly does not allow partially trusted callers. (G:\System\Backoffice\Citrix2008\MediaExplorer\Rev2008\Prod\Mfm.MediaExplorer.exe.Config line 28) ---> System.Security.SecurityException: That assembly does not allow partially trusted callers.

   at System.Security.CodeAccessSecurityEngine.ThrowSecurityException(RuntimeAssembly asm, PermissionSet granted, PermissionSet refused, RuntimeMethodHandleInternal rmh, SecurityAction action, Object demand, IPermission permThatFailed)
   at System.RuntimeMethodHandle.PerformSecurityCheck(Object obj, RuntimeMethodHandleInternal method, RuntimeType parent, UInt32 invocationFlags)
   at System.RuntimeMethodHandle.PerformSecurityCheck(Object obj, IRuntimeMethodInfo method, RuntimeType parent, UInt32 invocationFlags)
   at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture
   at System.Reflection.ConstructorInfo.Invoke(Object[] parameters)
   at System.Configuration.TypeUtil.InvokeCtorWithReflectionPermission(ConstructorInfo ctor)
   at System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.CreateSectionImpl(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
   at System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.CreateSectionWithRestrictedPermissions(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
   at System.Configuration.RuntimeConfigurationRecord.CreateSection(Boolean inputIsTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
   at System.Configuration.BaseConfigurationRecord.CallCreateSection(Boolean inputIsTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader, String filename, Int32 line)
   --- End of inner exception stack trace ---

   at System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult)
   at System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject)
   at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
   at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)

Collected dumps of the application at the point when the JIT dialog appeared…

Checked out the threads…

0:000> !threads
ThreadCount:      5
UnstartedThread:  0
BackgroundThread: 4
PendingThread:    0
DeadThread:       0
Hosted Runtime:   no
                                   PreEmptive   GC Alloc                Lock
       ID  OSID ThreadOBJ    State GC           Context       Domain   Count APT Exception
   0    1 11b08 007e2c38      6020 Enabled  03093658:03093fe8 007dc9f8     0 STA System.Configuration.ConfigurationErrorsException (02fcce20)
   2    2 11b10 007ee008      b220 Enabled  00000000:00000000 007dc9f8     0 MTA (Finalizer)
   5    3 11b24 0085a600   8009220 Enabled  00000000:00000000 007dc9f8     0 MTA (Threadpool Completion Port)
   6    4 10e78 00860b00   100a220 Enabled  00000000:00000000 007dc9f8     0 MTA (Threadpool Worker)
   8    5 11944 0087a1a8   200b220 Enabled  030911ac:03091fe8 007dc9f8     0 MTA

Yes there is a System.Configuration.ConfigurationErrorsException.

Callstack is as follows…

0:000> !pe 02fcce20
Exception object: 02fcce20
Exception type:   System.Configuration.ConfigurationErrorsException
Message:          An error occurred creating the configuration section handler for dataConfiguration: That assembly does not allow partially trusted callers.
InnerException:   System.Security.SecurityException, Use !PrintException 02fc55d0 to see more.
StackTrace (generated):
    SP       IP       Function
    0045E2EC 69D2E834 System_Configuration_ni!System.Configuration.BaseConfigurationRecord.EvaluateOne(System.String[], System.Configuration.SectionInput, Boolean, System.Configuration.FactoryRecord, System.Configuration.SectionRecord, System.Object)+0xc8
    0045E3C8 69D2E655 System_Configuration_ni!System.Configuration.BaseConfigurationRecord.Evaluate(System.Configuration.FactoryRecord, System.Configuration.SectionRecord, System.Object, Boolean, Boolean, System.Object ByRef, System.Object ByRef)+0x481
    0045E488 69D26F5D System_Configuration_ni!System.Configuration.BaseConfigurationRecord.GetSectionRecursive(System.String, Boolean, Boolean, Boolean, Boolean, System.Object ByRef, System.Object ByRef)+0x5bd
    0045E510 69D26F5D System_Configuration_ni!System.Configuration.BaseConfigurationRecord.GetSectionRecursive(System.String, Boolean, Boolean, Boolean, Boolean, System.Object ByRef, System.Object ByRef)+0x5bd
    0045E598 69D26F5D System_Configuration_ni!System.Configuration.BaseConfigurationRecord.GetSectionRecursive(System.String, Boolean, Boolean, Boolean, Boolean, System.Object ByRef, System.Object ByRef)+0x5bd
    0045E620 69D2698A System_Configuration_ni!System.Configuration.BaseConfigurationRecord.GetSection(System.String)+0x2a
    0045E630 69D2A5A9 System_Configuration_ni!System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(System.String)+0x55
    0045E644 69D210BF System_Configuration_ni!System.Configuration.ConfigurationManager.GetSection(System.String)+0x4f

There is an inner exception as well…

0:000> !PrintException 02fc55d0
Exception object: 02fc55d0
Exception type:   System.Security.SecurityException
Message:          That assembly does not allow partially trusted callers.
InnerException:   
StackTrace (generated):
    SP       IP       Function
    0045DC8C 6BD56349 mscorlib_ni!System.Security.CodeAccessSecurityEngine.ThrowSecurityException(System.Reflection.RuntimeAssembly, System.Security.PermissionSet, System.Security.PermissionSet, System.RuntimeMethodHandleInternal, System.Security.Permissions.SecurityAction, System.Object, System.Security.IPermission)+0xa9
    0045E1EC 6B7E9EF2 mscorlib_ni!System.RuntimeMethodHandle.PerformSecurityCheck(System.Object, System.IRuntimeMethodInfo, System.RuntimeType, UInt32)+0x22
    0045E208 6B772242 mscorlib_ni!System.Reflection.RuntimeConstructorInfo.Invoke(System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo)+0x82
    0045E298 6B7E9EBA mscorlib_ni!System.Reflection.ConstructorInfo.Invoke(System.Object[])+0x12
    0045E2A0 69D277C8 System_Configuration_ni!System.Configuration.TypeUtil.InvokeCtorWithReflectionPermission(System.Reflection.ConstructorInfo)+0x24
    0045E2B0 69D276AC System_Configuration_ni!System.Configuration.RuntimeConfigurationRecord+RuntimeConfigurationFactory.CreateSectionImpl(System.Configuration.RuntimeConfigurationRecord, System.Configuration.FactoryRecord, System.Configuration.SectionRecord, System.Object, System.Configuration.ConfigXmlReader)+0x2c
    0045E2D8 69D312DB System_Configuration_ni!System.Configuration.RuntimeConfigurationRecord+RuntimeConfigurationFactory.CreateSectionWithRestrictedPermissions(System.Configuration.RuntimeConfigurationRecord, System.Configuration.FactoryRecord, System.Configuration.SectionRecord, System.Object, System.Configuration.ConfigXmlReader)+0x57
    0045E31C 69D2762A System_Configuration_ni!System.Configuration.RuntimeConfigurationRecord.CreateSection(Boolean, System.Configuration.FactoryRecord, System.Configuration.SectionRecord, System.Object, System.Configuration.ConfigXmlReader)+0x5e
    0045E344 69D274E4 System_Configuration_ni!System.Configuration.BaseConfigurationRecord.CallCreateSection(Boolean, System.Configuration.FactoryRecord, System.Configuration.SectionRecord, System.Object, System.Configuration.ConfigXmlReader, System.String, Int32)+0x4c

StackTraceString: 
HResult: 8013150a
SecurityException Message: 
The action that failed was:
LinkDemand
The assembly or AppDomain that failed was:
System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
The Zone of the assembly that failed was:
MyComputer
The Url of the assembly that failed was:
file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll

Hmm weird that the assembly having this issue is System.Configuration! CLR version is 4.0. Caspol shouldn’t kick in if that’s the case. Eventually this turned out to be a bug.

This is fixed via a hotfix: http://support.microsoft.com/kb/2580188
FIX: System.Security.SecurityException occurs when a .NET Framework 4-based application that calls a static method in the System.Configuration.ConfigurationManager class runs on a network share.

The KB article says the following…
The application calls a static method in the System.Configuration.ConfigurationManager class. For example, the application calls the ConfigurationManager.GetSection method.

For this case this was true and the application was indeed calling ConfigurationManager.GetSection.

Disclaimer:
————–
Please read through the hotfix to be very sure that this hotfix applies to you. A classic symptom would be .net 4.0 + ConfigurationManager.GetSection call.

Jan 222014
 

[Edited post for Visual studio 2017, I had written this post for Visual Studio 2013]

Visual Studio 2017 comes with a new feature called “Debug Managed Memory” this feature also allows to compare managed memory usage across two dumps.  Read on…

This is how you would open a .net 4.5 memory dump in Visual Studio…

imageimage

So for the purpose of this blog I’ve created memory dumps of a managed application that consumes high memory: memtest.exe. I’ve collected three memory dumps…

  1. MemTest.dmp
  2. MemTest (2).dmp
  3. MemTest (3).dmp

For demo purpose I’m opening MemTest (3).dmp ‘first’ as shown in the above screenshot. So once you open the dump in Visual studio this is how Visual Studio will look like…

image

Check out mouse cursor location in the above screenshot. Click on this option. You’ll see following dialog pop up….

image

Following which you’ll see the following screen…

image

This report will show the most number of objects on heap. If you noticed; the largest objects in my case are ArrayLists and second one is MemTest.Form1. This report will also show you the roots to an object, similar to gcroot in WinDbg.

Further in the above screenshot, I’ve highlighted an item in red. That option allows us to compare multiple dumps.

The resultant report will show you the diff view between the two dumps. For demo I’m comparing MemTest (3).dmp with MemTest.dmp. MemTest (3).dmp was collected after  memtest.dmp was collected so you should ideally see a positive diff between the two dumps since memory usage increased in MemTest(3).dmp. Please see screenshot…

image

Now you’ll see that, new columns has been added to this report, for e.g. “Count Diff.”, ‘Size Diff (Bytes)” etc. The bottom table shows you the “Reference Count Diff.” as well.

Really cool feature! Comparing managed memory has been never easier. Please note this feature is only enabled for.net memory dumps that use .net 4.5.

Dec 202013
 

Had a customer whose application was crashing after migration from Visual Studio 2005 to Visual Studio 2008. He had the crash dumps as well. The crash call stack had some CRT string format functions like vsprintf. This gave to us a fair inkling that parameters passed in are wrong.

Customer had a format string, something like this: “My string format [%s]”.

At the point of crash the output buffer looked like this: “My string format[“. It became quite evident that the crash is happening when the %s in the format string was being replaced by the actual string. Quite evident that something’s wrong with the parameter passed in for replacing the %s format specifier.

Checking code saw something like this…

MyString mystr = “MS rocks”;
MyFormatters::Format(“My string format [%s]”, mystr);

You should never do this. %s is expecting a “raw string” and do not pass in anything else. This is wrong even if your class has a raw string as its first member, imagine if you have a virtual function in the class or if someone decides in the future this class should be derived further.

Always pass in a raw string pointer and nothing else to the string format functions for expanding the format specifier: %s. The string format family of functions doesn’t check the type passed in. Those functions work on varargs hence compiler doesn’t help as well.

In this case we fixed above code likewise:
MyFormatters::Format(“My string format [%s]”, mystr.c_str());

You might have an obvious question as to why it worked in Visual Studio 2005, the answer is pretty obvious as well. I’ll leave that for you to answer.