HOWTO: Enhancing AUTOEXP.DAT - Creating Custom Type Evaluator Routines 
Author Message
 HOWTO: Enhancing AUTOEXP.DAT - Creating Custom Type Evaluator Routines

Hello,

Several weeks ago, one my good friend has played with eecxx.dll and he discovered technique, how to write Custom Type Evaluator Routines. Due to number of people posting questions about using autoexp.dat I asked him to publish these [totally undocumented] informations.

The type evaluator is bound with custom type evaluating routine through autoexp.dat pseudomacro $ADDIN in the following form:

<type>=$ADDIN(<dll_name>,<exported_function>)
where

dll_name is the name of custom evaluator dll that exports exported_function. One library can export multiple functions for different evaluated types.

We have tested only relative names (dll was placed in the same directory as autoexp.dat - %MSDevDir%\bin). Maybe, double-quoted absolute path would work too.

Example:

MyRecord=$ADDIN(my.dll,Evaluate_MyRecord)
MyPointer=$ADDIN(my.dll,Eval_MyPointer)
MyNS::MyType=$ADDIN(my2.dll,Evaluate_MyType)
Note: The expression $ADDIN(<dll_name>,<exported_function>) [probably] should not contain spaces.

When Visual C++ de{*filter*} is asked to evaluate custom type (e.g. QuickWatch or displaying tool tip in source editor), is calls extension dll and runs exported function

int _cdecl EvaluateXXX(
    LPVOID   lpEvalObject       // pointer to evaluated object
    DWORD           dwSignature // signature
    DWORD           dwRadix     // radix to use
    DWORD           dwReserver  // reserved, always 0
    LPSTR    pszText    // displayed text
    DWORD    cchMax     // text size
);

Parameters

lpEvalObject

    [in] Pointer to object being evaluated in debugged process memory space (see Remarks)

dwSignature
    [in] 0x52526c00 = "RRI" - used to get evaluated object (see Remarks)

dwRadix
    [in] Radix to use (to format numbers in the returned string) - usually decimal (10) or hexadecimal (16), set by checking Hexadecimal display option in Tools/Options/Debug/General or Watch/Variables window context menu

dwReserved
    [in] Reserved - always 0 (for future use ?)

pszText
    [out] Address of the buffer to receive the null-terminated string of object being evaluated

cchMax
    [in] Size of the buffer to receive the null-terminated string

Return Values

Returns NOERROR (0) if successful, other value is considered as an error and displayed text is "???".

Remarks

When the size of evaluated object is <= sizeof(DWORD), lpEvalObject is not pointer, but it does contain the object immediately (char, int, DWORD). For larger objects (structures.) the lpEvalObject points to memory in debugged process memory space and the object has to be obtained by calling function GetDebuggedProcessMemory - the address of this function follows dwSignature:
typedef int (_stdcall *GETMEM_FUNC)(DWORD dwSignature, void *pProcessMemory, DWORD dwBufferSize, void *pBuffer, DWORD *pdwBytesReceived);
inline int GetDebuggedProcessMemory(DWORD dwSignature, void *pProcessMemory, DWORD dwBufferSize, void *pBuffer)
{
  DWORD dwBytesReceived;
  GETMEMFUNC _GetMem = (GETMEM_FUNC)*(((int *)dwSignature) + 1);
  int nRetVal = _GetMem(dwSignature, pProcessMemory, dwBufferSize, pBuffer, &dwBytesReceived);
  if(nRetVal != 0)
    return nRetVal;
  if(dwBytesReceived != dwBufferSize)
    return 0x80004005;
    return 0;

Quote:
}

Example, how to write custom type evaluator function:

MyType=$ADDIN(my.dll,EvaluateMyType)

int _cdecl EvaluateMyType(LPVOID lpEvalObject, DWORD dwSignature, DWORD dwRadix, DWORD dwReserver, LPSTR pszText, DWORD cchMax)
{
  int nRetVal;
  BYTE buffer[1024];
  MyType *pMyVar = (MyType *)buffer;   // Important note: if(sizeof(MyType) <= sizeof(DWORD))  //                   pMyVar = lpEvalObject   if((nRetVal = GetDebuggedProcessMemory(dwSignature, pEvalObject, sizeof(MyType), buffer)) != 0)
    return nRetVal;    // Here you can examine variable and fill string
  // lstrcpyn(pszText, pMyVar->ToString(), cchMax);  // pszText[cchMax] = '\0';
   return 0;}
Note: IMHO (maybe) dwSignature is a part of more complex structure that contains dwSignature followed with pointer to GetDebuggedProcessMemory function. By the way, in this time it is not so important...Viktor "Viki" VolmutStanislav "ChainsaW" Simicek---DGroup Team



Fri, 04 Apr 2003 03:00:00 GMT  
 
 [ 1 post ] 

 Relevant Pages 

1. AutoExp.dat and member variables of (STL) string type

2. BUG: autoexp.dat is wrong for std:basic_string

3. autoexp.dat and function calls

4. autoexp.dat and VC7

5. AutoExp.dat with Interfaces

6. BUG: autoexp.dat is wrong for std:basic_string

7. BUG with: AutoExp.dat in VC.NET

8. Inheritance in autoexp.dat

9. autoexp.dat there but ignore?

10. Problem with AutoExp.Dat

11. AutoExp.dat and NoStepInto

12. Info on autoexp.dat

 

 
Powered by phpBB® Forum Software