1

I have a C++ application with debug symbols, and created a dump file of such application with all relevant gflags enabled:

gflags /i xxx.exe +hpa
gflags /i xxx.exe +ust

Now, I have found from other questions (see here), that by first looking for a type's vftable address:

x module!SomeClass*table*

And then searching the heap for that address:

!heap -srch 'address_of_vtable'

I can find all instances of that type. That is true, if the vftable exists for such type.

From what I have read, the vftable is only created for types that use inheritance, but if a type does not use inhertance at all, then it does not get created.

If the vftable is not created then the approach above does not seem to work. I can find an address for the type using (no vftable):

 x module!SomeClass::SomeClass

But if I search the heap for the returned address, there are no matches, eventhough I know I have several instances of such type.

What other people have done is to force the creation of the vftable, but modifying the code base in such a way for the sake of debugging does not seem like a good or practical approach for existing large code bases.

Is there a way, combination of windbg commands, to look for instances of a (non-inheritance) type in a dump file without having to modify the source code?

NOTE : I know there are other tools for heap analysis, like umdh and heap snapshots with WPR, but I assume I only have a regular, full, good old-fashined dump. All the heap information is in that dump, have the symbols and sources, so there must be a way, right?

  • Have you seen https://randomascii.wordpress.com/2019/10/27/heap-snapshots-tracing-all-heap-allocations/ which shows that Windows Performance Analyzer (not windbg) is able to group allocations by call site? – Ben Voigt Apr 20 '21 at 16:23
  • Didn't know about that, thanks for the link. Regardless, I am looking for a deployment-friendly solution. End users are not tech-savy and asking them to go to the task manager and create dump, is already the limit. Of course being able to create heap snapshots is very useful for development, but if I am already in a dev environment, then I just install Visual Studio and get done with it. – Juan Gonzalez Burgos Apr 21 '21 at 08:17

1 Answers1

1

Given that an object can be created out of random bytes (so long as alignment requirements are met) it is impossible to say whether some random collection of bytes is of any particular type. Even in the case where there is a value that matches a vtable pointer that is only a very strong hint rather than conclusive proof. After all it would be possible to have an integral member that just happens to have a value that matches the address of a vtable for whatever reason.

Given that reality, I would say it is impossible to even guess at the type of a collction of bytes that do not have a vtable-matching value.

SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23
  • Makes sense, but if so, how does umdh gets that information from a couple of snapshots of the heap? – Juan Gonzalez Burgos Apr 20 '21 at 15:45
  • @JuanGonzalezBurgos: Capturing the call stack when the allocation takes place? I'm not saying that will get you perfect type information, but it certainly will divide things up into buckets that depend on type. If your snapshots don't contain this information like UMDH snapshots do, you won't be able to analyze it the same way. – Ben Voigt Apr 20 '21 at 16:05
  • But my dump file also has call stack information for allocations (enabled by gflags), so the information used by umdh also exists in the dump file. This leads me to believe that windbg must be able to access it as well. – Juan Gonzalez Burgos Apr 20 '21 at 16:07
  • have you searched for windbg and the name of the gflag you are using? You didn't bother listing it in your question, all you said was "all relevant". StackOverflow is not supposed to be a guessing game where experts try to figure out what you mean. Be specific. Be exact. – Ben Voigt Apr 20 '21 at 16:08
  • Yes, and actually I let's say I have two types; Type1 which has vftable, and Type2 that doesn't. Type1 contains a reference (pointer) to an instance (allocated in heap) of Type2. I use the described method to find all instances of Type1, I display the members of one of those instances using the dx command and see the ref to a Type2, then I can see the Type2 instance contents. Furthermore, using !heap -p -a, I can even see the call stack that lead to the allocation of the Type2 instance. Yet I have found no way to find instances of Type2. – Juan Gonzalez Burgos Apr 20 '21 at 16:13
  • Edit: just added the gflags – Juan Gonzalez Burgos Apr 20 '21 at 16:16
  • So it seems like you are looking for a way to search all allocations based on the `DPH_BLOCK_INFORMATION` StackTrace, probably with some additional ability to match only a certain number of frames. Sounds like a good idea for a debugger extension. – Ben Voigt Apr 20 '21 at 16:20
  • Mark this as answer, I have been looking around and there is indeed no way to find instances if they do not have some kind of identifier (in the case of polymorphic classes, that identifier being the vftable). For [reference](https://www.itprotoday.com/microsoft-visual-studio/heap-magic-c-object-internals) – Juan Gonzalez Burgos Apr 21 '21 at 12:21