0

We're investigating erratic behavior of a C++Builder application on Windows XP.

We have a process dump file for analysis, however as the application is built using C++Builder, we don't have the usual .pdb files. Instead we have .tds/.map files, that should contain debug information. However, I'm not aware of any tool that is able to use these files for offline analysis. I did find some SourceForge converter tools, but they crash on the .tds/.map files we have.

I'm confident that there must be some way in a C++Builder toolchain to do process dump analysis. But as of yet, I didn't find any.

I already found this: Using Windows dump file for Borland C++ application. However, this skips over the symbol loading part. Other StackOverflow/Google searches didn't give any results, either.

Version info: Developing on Codegear C++ Builder 2009 with Update 4 (from Embarcadero).

Answer seems to be that there is no supported tool chain. (From C++ Builder perspective) you have to rely on 3rd party tools to convert the format to - for example - a windbg supported format (dbg). map2dbg, tds2pdb, or if manual conversion is needed, the map file layout can be found on this link on the Embarcadero website.

Freek Nossin
  • 101
  • 9
  • 1
    looks relevant https://community.osr.com/discussion/129819/tds-and-or-map-files-in-windbg Search was "windbg tds" – Richard Critten Jul 05 '21 at 12:43
  • https://github.com/andremussche/map2dbg this also contains tdstopdb i havent used it but i have used the map2dbg in the osr link above – blabb Jul 05 '21 at 12:53
  • 1
    btw a map file is a simple rva to name pair if you open in notepad like base 0x1000 rva 20 this is myfoo so if base is 2000 then 2020 is symbol this is myfoo if you can text parse it and label using [this windbg extension](https://github.com/blabberer/windbg_labeller) – blabb Jul 05 '21 at 12:57
  • @blabb thanks for the response. The first link (map2dbg) was unfortunately the same project as the sourceforge one I found. The application throws an exception on our tds or map files. I will have a look at the windbg extension. Interesting approach, didn't know the files were human readable. – Freek Nossin Jul 05 '21 at 13:51
  • @RichardCritten will look into that, it's a large thread full of back-and-forth discussion. I'll post a conclusion about my findings. – Freek Nossin Jul 05 '21 at 13:53
  • @FreekNossin which version of C++Builder are you using? **Borland** C++Builder is very old, and quite a different product than the newer **Embarcadero** C++Builder. – Remy Lebeau Jul 05 '21 at 15:23
  • @RemyLebeau Codegear C++ Builder 2009 with Update 4 (from Embarcadero). I see you are an expert on their platform. Do you know if there is any toolchain that Embarcadero supports (from that era), to analyze process dumps? – Freek Nossin Jul 05 '21 at 16:29
  • 1
    @FreekNossin No, there is no tool provided by CodeGear/Embarcadero (then or now) for analyzing crash dumps using tds/map files. So you have to rely on 3rd party tools. If map2dbg is crashing, I would suggest trying to fix that so it works correctly (nice thing about open source projects) – Remy Lebeau Jul 05 '21 at 16:35
  • @RemyLebeau thanks for the answer (though quite concerning...). For future reference. I found the documentation on the map file layout. Luckily it seems well documented. [Detailed Segments Map File](http://docwiki.embarcadero.com/RADStudio/Sydney/en/Detailed-Segments_Map_File) – Freek Nossin Jul 05 '21 at 16:47
  • 1
    also iirc there is a tds2map which can make a human readable map from the binary tds – blabb Jul 05 '21 at 16:48
  • @blabb and Remy Lebeau thanks for the information. Updated the OT with the summary. – Freek Nossin Jul 05 '21 at 16:51
  • here is a result for [tds2map](http://www.scalabium.com/smlog/index.htm) iirc comes with builder it contains the bordbg.dll discussed in the osr link – blabb Jul 05 '21 at 17:01

1 Answers1

0

You mention a crash when processing your TDS symbols. This is caused by a bug in the BorDebug.dll library that is used to read TDS symbol information. The function BorDebugNameIndexToUnmangledName() is used to turn a TDS index into a human readable symbol. Unfortunately some symbols are just too long when unmangled and cause a crash. Even if you put an exception handler around this call, any enumeration of the TDS file will cease (future calls will fail to work). This happens regardless of buffer length you pass to the function (we tried some very large buffer values).

The workaround is to use BorDebugNameIndexToName() to get the mangled name, and continue iterating all the symbols you need to examine. Once you've finished that and called BorDebugUnregisterFile() to close the TDS file, then you can unmangle the symbols with a call to BorDebugUnmangle() which you can call to unmangle functions even if you haven't opened a TDS file. You'll still need to handle the few functions that fail to unmangle without throwing an exception, but at least your symbol iteration worked and most symbols unmangle correctly.

If you can use a debugger to view the callstack of the minidump then you can convert the addresses to symbols, filenames and line numbers using TDS Browser (Delphi and C++ Builder 32 bit), DWARF Browser (C++ Builder 64 bit) and MAP File Browser.

These are tools I wrote for in house use. We've made them available for free.

Stephen Kellett
  • 3,078
  • 1
  • 22
  • 25