• Format Specifiers in C++ (zz)


    Format Specifiers in C++


    The following tables show the format specifiers recognized by the debugger.

    Specifier Format Expression Value Displayed

    d,i

    signed decimal integer

    0xF000F065, d

    -268373915

    u

    unsigned decimal integer

    0x0065, u

    101

    o

    unsigned octal integer

    0xF065, o

    0170145

    x,X

    Hexadecimal integer

    61541, x

    0x0000F065

    l,h

    long or short prefix for: d, i, u, o, x, X

    00406042,hx

    0x0c22

    f

    signed floating point

    (3./2.), f

    1.500000

    e

    signed scientific notation

    (3./2.), e

    1.500000e+000

    g

    signed floating point or signed scientific notation, whichever is shorter

    (3./2.), g

    1.5

    c

    Single character

    0x0065, c

    101 'e'

    s

    String

    0x0012fde8, s

    "Hello world"

    su

    Unicode string

    0x0012fde8, su

    "Hello world"

    hr

    HRESULT or Win32 error code. (The debugger now decodes HRESULTs automatically, so this specifier is not required in those cases.

    0x00000000L, hr

    S_OK

    wc

    Window class flag.

    0x00000040, wc

    WC_DEFAULTCHAR

    wm

    Windows message numbers

    0x0010, wm

    WM_CLOSE

    !

    raw format, ignoring any data type views customizations

    i !

    4


    The following table contains formatting symbols used for memory locations. You can use a memory location specifier with any value or expression that evaluates to a location.

    Symbol Format Expression Value Displayed

    ma

    64 ASCII characters

    ptr, ma

    0x0012ffac .4...0...".0W&.......1W&.0.:W..1...."..1.JO&.1.2.."..1...0y....1

    m

    16 bytes in hexadecimal, followed by 16 ASCII characters

    ptr, m

    0x0012ffac B3 34 CB 00 84 30 94 80 FF 22 8A 30 57 26 00 00 .4...0...".0W&..

    mb

    16 bytes in hexadecimal, followed by 16 ASCII characters

    ptr, mb

    0x0012ffac B3 34 CB 00 84 30 94 80 FF 22 8A 30 57 26 00 00 .4...0...".0W&..

    mw

    8 words

    ptr, mw

    0x0012ffac 34B3 00CB 3084 8094 22FF 308A 2657 0000

    md

    4 doublewords

    ptr, md

    0x0012ffac 00CB34B3 80943084 308A22FF 00002657

    mq

    2 quadwords

    ptr, mq

    0x0012ffac 7ffdf00000000000 5f441a790012fdd4

    mu

    2-byte characters (Unicode)

    ptr, mu

    0x0012fc60 8478 77f4 ffff ffff 0000 0000 0000 0000


    If you have a pointer to an object you want to view as an array, you can use an integer to specify the number of array elements:

    ptr,10
    


    Size Specifier for Pointers as 2D Arrays

    If your pointer is a pointer to a 2-dimensional array, you can also specify a size for both dimensions, by separating your sizes with spaces:


    ptr,10 10

    //z 2013-07-16 19:55:52 IS2120@BG57IV3.T2045059389.K[T3,L65,R1,V14]

    The following table shows the C# format specifiers recognized by the debugger.

    Specifier Format Value Displays

    d

    Decimal integer

    0x0065

    101

    h

    Hexadecimal integer

    61541

    0x0000F065

    nq

    String with No Quotes

    "My String"

    My String

    private

    Displays item as it appears in the private members node

       

    raw

    Displays item as it appears in the raw item node. Valid on proxy objects only.

       

    Ac

    Force evaluation of an expression. This can be useful when implicit evaluation of properties and implicit function calls is turned off. SeeSide Effects and Expressions.

     

    //z 2013-07-16 19:55:52 IS2120@BG57IV3.T2045059389.K[T3,L65,R1,V14]

    Pseudoregisters

    Pseudoregister

    Description

    @ERR

    Last error value; the same value returned by the GetLastError() API function

    @TIB

    Thread information block for the current thread; necessary because the debugger doesn't handle the "FS:0" format

    @CLK

    Undocumented clock register; usable only in the Watch window

    @EAX, @EBX, @ECX, @EDX, @ESI, @EDI, @EIP, @ESP, @EBP, @EFL

    Intel CPU registers

    @CS, @DS, @ES, @SS, @FS, @GS

    Intel CPU segment registers

    @ST0, @ST1, @ST2, @ST3, @ST4, @ST5, @ST6, @ST7

    Intel CPU floating-point registers


    @ERR
     最后错误值; 和GetLastError() API 函数一致
     
    @TIB
     当前线程信息; 在调试器无法处理”FS:0”格式的时候是必要的
     
    @CLK
     未列入文档的寄存器; 只是在Watch窗口适用
     
    @EAX, @EBX, @ECX, @EDX, @ESI, @EDI, @EIP, @ESP, @EBP, @EFL
     Intel CPU 寄存器
     
    @CS, @DS, @ES, @SS, @FS, @GS
     Intel CPU 段寄存器
     
    @ST0, @ST1, @ST2, @ST3, @ST4, @ST5, @ST6, @ST7
     Intel CPU 浮点寄存器
     
    其中@TIB很有用,可以用在多线程调试的时候作为断点的条件变量.这样就可以只观察一个线程的执行情况.
    另一个常用的@err,hr

    另一篇相关链接:(调试的伪注册器 pseudo-registers in watch window pseudo registers

    //z 2013-07-16 19:52:40 IS2120@BG57IV3.T3155280055.K[T2,L65,R1,V13]
    Customizing the Visual Studio Debugger Display of Your DataCalvin Hsia

    Microsoft Corporation

    June 2006

    Applies to:
       Visual Studio 2005
       Visual Studio .NET 2003
       Visual Studio 7.0

    Summary: Illustrates ways to customize the Visual Studio 2005 debugger to get the most out of your debugging time. (6 printed pages)

    As a software developer, I spend much of my time looking at code, learning how it works, and figuring out how to modify or fix it. A very good tool to help examine code is the Visual Studio debugger.

    (Even if you're not a hard core programmer, the following tutorial shows some of the power of the Visual Studio components—for example, the project system, build system, and debugger—working together.)

    At a breakpoint, I can examine local variables in the Watch, Auto, or Locals window to see their values and types. If it's a class or structure, the debugger will show a plus sign (+), indicating that it can be expanded, and the first couple members of that structure. Structures' submembers or inherited values can be examined. These structures can getvery deep. Sometimes I need to inspect a value that's dozens of levels down in a hierarchy. That's a lot of complicated tree navigation in the debugger. Other times, I need to take a local variable name (or a member of that variable if it's a structure/class), drag and drop it to a new line in the Watch window, and then typecast it to a value that's more meaningful. As I step through the code, the variable might go out of scope, or it might have a different name in a subroutine, so I'd have to repeat the typecasting steps in the Watch window with the different variable name.

    For example, suppose that one of the variables is called VBLine, and that it is an internal representation of a line of Visual Basic .NET code. It's much more meaningful to seeDim MyVar As String than a bunch of hex numbers in the debugger. I drag and drop it to the Watch window, typecast it to aDIM statement, and expand/navigate the results to findMyVar. Then, I step into the next called function, withVBLine passed as an argument. The receiving function names the parameterVBStatement, so my Watch window drilldown needs to be modified to use the different variable name.

    This gets very cumbersome. Let's improve it!

    Here's a simple demonstration of how you can control what the debugger displays.

    1. Start Visual Studio 2005 or 2003. (It also works in Visual Studio 7, although the steps might be slightly different.)
    2. Click File > New > Projects.
    3. Select Visual C++, and then Win32 Console Application, and name itTest.
    4. Click Finish in the wizard.
    5. Paste in some sample code to debug.
      #include "windows.h"
      int _tmain(int argc, _TCHAR* argv[])
      {
         OSVERSIONINFOEX osinfo;   // Declare a structure
         ZeroMemory(&osinfo, sizeof(osinfo));   // init it to 0
         osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);   // set the size
         GetVersionEx((LPOSVERSIONINFO) &osinfo);   // call WinAPI to fill it in
      
         WIN32_FIND_DATA   FAR ffd;   // Declare a structure
         FindFirstFile("c:\windows\system32\k*.exe",&ffd);   // Find the first file starting with "k"
      
         return 0;   //set bpt here
      }
      

      This sample code just calls the Windows API functions GetVersionEx and FindFirstFile, which fill structures that we can examine in the debugger.

    6. To make things simple, let's use ANSI rather than Unicode characters (Visual Studio 2005 defaults to Unicode):
      1. Click Project > Properties > Configuration Properties >General >Character Set.
      2. Change the character set from Use Unicode Character Set to Use Multi-Byte Character Set.
    7. Let's also remove the check for 64-bit portability issues:
      1. Click Project > Properties > Configuration Properties >C++ >General.
      2. Clear Detect 64 bit portability issues.
    8. Press F9 on the return line to set a breakpoint, and then press F5 to build and run the project.

    When the breakpoint hits, the Debug window shows the following.

    +      osinfo   {dwOSVersionInfoSize=284 dwMajorVersion=5 dwMinorVersion=1 ...}   _OSVERSIONINFOEXA
    +      ffd   {dwFileAttributes=32 ftCreationTime={...} ftLastAccessTime={...} ...}   _WIN32_FIND_DATAA
    

    Now, let's control the string displayed for a given type:

    1. Open the file called AutoExp.dat (which installs with Visual Studio) in the Visual Studio editor:
      1. Click File > Open > File.
      2. Locate the AutoExp.dat file. On my machine, it's at c:Program FilesMicrosoft Visual Studio 8Common7PackagesDebuggerAutoexp.dat.

      This file describes how to customize the output of the Debug Watch, Locals, and Auto windows. It's formatted like an INI file.

    2. Add the following line to the AutoExp.dat file, in the [AutoExpand] section.
      _OSVERSIONINFOEXA = Hi there <szCSDVersion> Build number = <dwBuildNumber>
      
    3. Press F5 to go to the breakpoint.

    Now the Watch window shows the following.

    +      osinfo   {Hi there 0x0013fe58 "Service Pack 2" Build number = 2600}   _OSVERSIONINFOEXA
    

    This is a big improvement: we've told the debugger which members of the structure to show, and how to format them! We can still click the+ to drill down the member hierarchy.

    When starting a debug session, the debugger reads the AutoExpand file, and if the left of the equal sign matches the type in the Type column of the Locals/Watch/Auto window, the right side will direct how to format the displayed string. The comments at the beginning of AutoExp.dat give more details, including more formatting options.

    This is great, but it's nothing compared to what we'll do next!

    You can write code that executes in the debugger process, and that can read the memory of the debugee! AutoExp.dat controls this feature too:

    • In the [AutoExpand] section of the AutoExp.dat file, replace the line that you added in Step 2 above with the following three lines.
      _OSVERSIONINFOEXA= $ADDIN(MyDbgEE.dll,?EE_OSVERSIONINFOEXA@@YGJKPAUtagDEBUGHELPER@@HHPADIK@Z)
      _WIN32_FIND_DATAA =$ADDIN(MyDbgEE.dll,?EE_WIN32_FIND_DATAA@@YGJKPAUtagDEBUGHELPER@@HHPADIK@Z)
      MyClass = $ADDIN(MyDbgEE.dll,?EE_MyClass@@YGJKPAUtagDEBUGHELPER@@HHPADIK@Z)
      

    The $ADDIN(DllName,FunctionName) syntax means that the DLL that is named will be loaded, and theFunctionName export in the DLL will be called. (Ignore the gobbledygook: it's just C++ name decorating, indicating the calling convention, the parameters, and so on.) If any error occurs—for example, the DLL can't be found, the export can't be found, or the DLL caused an exception, the displayed string will be{???}.

    Now, let's create the project that will build MyDbg.DLL, and add it to the current solution:

    1. Click File > New > Project >Visual C++ Win32 Project.
    2. Name the project MyDbgEE, and select Add to Solution (rather thanCreate New Solution).
    3. In the Win32 App Wizard that appears, change the application type to a DLL.
    4. Change the project properties as above to non-Unicode and no 64-bit issues.
    5. Add the following lines.
      #define ADDIN_API    __declspec(dllexport)
      
      typedef struct tagDEBUGHELPER
      {
          DWORD dwVersion;
          BOOL (WINAPI *ReadDebuggeeMemory)( struct tagDEBUGHELPER *pThis, DWORD dwAddr, DWORD nWant, VOID* pWhere, DWORD *nGot );
          // from here only when dwVersion >= 0x20000
          DWORDLONG (WINAPI *GetRealAddress)( struct tagDEBUGHELPER *pThis );
          BOOL (WINAPI *ReadDebuggeeMemoryEx)( struct tagDEBUGHELPER *pThis, DWORDLONG qwAddr, DWORD nWant, VOID* pWhere, DWORD *nGot );
          int (WINAPI *GetProcessorType)( struct tagDEBUGHELPER *pThis );
      } DEBUGHELPER;
      
      ADDIN_API  HRESULT WINAPI EE_OSVERSIONINFOEXA( DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved )
      {
         wsprintf(pResult,"Testing Addr = %x Uni = %d base = %d %x",dwAddress,bUniStrings, nBase, *(DWORD *)dwAddress);
         return S_OK;
      }
      
      ADDIN_API  HRESULT WINAPI EE_WIN32_FIND_DATAA( DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved )
      {
         WIN32_FIND_DATA   FAR ffd;
         DWORD nGot=0;
         pHelper->ReadDebuggeeMemory(pHelper,dwAddress,sizeof(ffd),&ffd,&nGot);
         wsprintf(pResult,"FindData found file '%s' DBG Process ID = %d",ffd.cFileName, GetCurrentProcessId());
         return S_OK;
      }
      

    Now, we need to tell Visual Studio where to put the built DLL, so that the debugger can find it. We can use the build events in the project:

    1. For the DLL project, click Project > Properties >Configuration Properties >Build Events > Post Build Event > Command Line.
    2. Enter copy $(TargetPath) "$(DevEnvDir)". Make sure that you have the quotation marks and parentheses right. If you put in a description string, that string will be echoed to the Output window when building. Now, when you rebuild, the debug DLL will be copied to the same directory as Devenv.exe.
    3. Press F5 and see the values in the Debug window! Bring up the Task Manager and notice that the Process ID shown is the same as that of the Devenv.exe debugger process.

    To make things more interesting, let's see how our debug code can read the debugger memory. We'll add some code to obscure a desired value, but we'll dig for it in the debug DLL.

    1. Add the following code after the #include "windows.h" line in the main Test code.
      struct MyClass {// normally this will go in #include file
         int mymem1;   // make the 1st few members irrelevant, so debugger won't show interesting info
         int mymem2;
         int mymem3;
         int mymem4;
         int mymem5;
         short *str;   // make this not a string, so debugger won't show it as a string
         MyClass * m_pNextClass;   // self referential, perhaps like a linklist
      };
      
    2. Add the following code to just before the return statement.
         MyClass * pMyClass = new MyClass();   // declare a new instance of MyClass
         pMyClass->str = new short(8);      // create a heap allocated byte array
         memcpy(pMyClass->str,"NotMe!",7);   // desired value to see in debugger
      
      
         pMyClass->m_pNextClass = new MyClass();   // make a submember instance
         pMyClass->m_pNextClass->str = new short(8);   // heap allocated submember string
         memcpy(pMyClass->m_pNextClass ->str,"Bingo!",7);   // desired value to see in pMyClass
      

      This code creates a class, MyClass, with a pointer to another instance ofMyClass that contains the desired debug display value.

    Now, we need to modify the debug DLL to dig for the value.

    1. Copy the same structure definition as above into the debug DLL code. (Typically, these definitions will be in a shared #include file.)
    2. Add the following code.
      ADDIN_API  HRESULT WINAPI EE_MyClass( DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved )
      {
         DWORD nGot=0;
         MyClass oMyClass;
         pHelper->ReadDebuggeeMemory(pHelper,dwAddress,sizeof(oMyClass),&oMyClass,&nGot); // read the debuggee's structure
         char szMainStr[100];
         char szMemberStr[100];
         *szMemberStr=0;   // init to empty string
         if (oMyClass.m_pNextClass)   // if there's a sub member
         {
            MyClass oNextClass;
            pHelper->ReadDebuggeeMemory(pHelper,(DWORD)oMyClass.m_pNextClass,sizeof(oNextClass),&oNextClass,&nGot); // read it
            pHelper->ReadDebuggeeMemory(pHelper,(DWORD)oNextClass.str,sizeof(szMemberStr),&szMemberStr,&nGot);      // read it's string
         }
         pHelper->ReadDebuggeeMemory(pHelper,(DWORD)oMyClass.str,sizeof(szMainStr),szMainStr,&nGot);   // read the string of the main struct
         wsprintf(pResult,"MyClass string is '%s'. Submem = '%s'",szMainStr,szMemberStr);
         return S_OK;
      }
      
    3. Press F5, and Bingo! You can still drill down into the class manually as before, so you haven't lost any functionality.

    The debug DLL can be rebuilt even while debugging: it's loaded/unloaded as needed by the debugger. This means that persisting values might be cumbersome. I've used custom registry keys for persisting values, such as global variables.

    I've been using this debug expression evaluator architecture for years for huge projects, including Visual Foxpro and Visual Basic.NET, and I find it indispensable and a huge time saver.

    //z 2013-07-16 19:57:50 IS2120@BG57IV3.T3274678781.K[T4,L254,R1,V14]

    设置_NT_SYMBOL_PATH(windbg)

    Format Specifiers in C++

    The following tables show the format specifiers that you can use in Visual Studio 2012 when you are not debugging interop (native and managed) code with C++/CLI or using C++ edit and continue.

    Specifiers in bold are not supported for interop debugging with C++/CLI or debugging with C++ edit and continue.

    //z 2014-03-31 18:10:29 BG57IV3@XCL T1671201559.K.F253293061 [T102,L1307,R60,V1836]

    The following tables show the format specifiers that you can use in Visual Studio 2012 when you are not debugging interop (native and managed) code with C++/CLI or using C++ edit and continue.

    Specifiers in bold are not supported for interop debugging with C++/CLI or debugging with C++ edit and continue.

    Specifier

    Format

    Expression

    Value Displayed

    d

    decimal integer

    0xF000F065, d

    -268373915

    o

    unsigned octal integer

    0xF065, o

    0170145

    x

    h

    Hexadecimal integer

    61546, x

    61541, h

    0x0000f06a

    X

    H

    Hexadecimal integer

    61541, X

    61546, H

    0x0000F06A

    c

    Single character

    0x0065, c

    101 'e'

    s

    ASCII string

    0x0012fde8, s

    "Hello world"

    sb

    ASCII string

    0x0012fde8, sb

    Hello world

    su

    Unicode string

    0x0012fde8, su

    L"Hello world"

    sub

    Unicode string

    0x0012fde8, sub

    Hello world

    s8

    UTF-8 string

    0x0012fde8, s8

    "Hello world"

    s8b

    UTF-8 string

    0x0012fde8, s8b

    Hello world

    bstr

    BSTR string

    0x0032fe8, bstr

    Hi there

    , na

    &myGlobal, n

    winmain, na

    The address of the pointer is not displayed.

    nd

    pb,nd

    Displays only the base class info of pb, ignoring derived classes

    hr

    HRESULT or Win32 error code. (The debugger now decodes HRESULTs automatically, so this specifier is not required in those cases.

    0x00000000L, hr

    S_OK

    wc

    Window class flag.

    0x00000040, wc

    WC_DEFAULTCHAR

    wm

    Windows message numbers

    0x0010, wm

    WM_CLOSE

    !

    raw format, ignoring any data type views customizations

    i !

    4

    If you have a pointer to an object you want to view as an array, you can use an integer or an expression to specify the number of array elements:

    Specifier

    Format

    Expression

    Value Displayed

    n

    Decimal or hexadecimal integer

    pBuffer,[32]

    pBuffer,[0x20]

    Displays pBuffer as a 32 element array.

    [exp]

    A valid C++ expression that evaluates to an integer.

    pBuffer,[bufferSize]

    Evaluates bufferSize and displays pBuffer as an array of the evaluated number of elements.

    expand(n)

    pBuffer, expand(1,2)

    Displays the third child of the second child of pBuffer

    Specifiers in bold are only supported for debugging native and C++/CLI code and debugging with C++ edit and continue.

    Specifier

    Format

    Expression

    Value Displayed

    d,i

    signed decimal integer

    0xF000F065, d

    -268373915

    u

    unsigned decimal integer

    0x0065, u

    101

    o

    unsigned octal integer

    0xF065, o

    0170145

    x,X

    Hexadecimal integer

    61541, x

    0x0000f065

    l,h

    long or short prefix for: d, i, u, o, x, X

    00406042,hx

    0x0c22

    f

    signed floating point

    (3./2.), f

    1.500000

    e

    signed scientific notation

    (3./2.), e

    1.500000e+000

    g

    signed floating point or signed scientific notation, whichever is shorter

    (3./2.), g

    1.5

    c

    Single character

    0x0065, c

    101 'e'

    s

    String

    0x0012fde8, s

    "Hello world"

    su

    Unicode string

    0x0012fde8, su

    L"Hello world"

    sub

    Unicode string

    0x0012fde8, sub

    Hello world

    s8

    UTF-8 string

    0x0012fde8, s8

    "Hello world"

    hr

    HRESULT or Win32 error code. (The debugger now decodes HRESULTs automatically, so this specifier is not required in those cases.

    0x00000000L, hr

    S_OK

    wc

    Window class flag.

    0x00000040, wc

    WC_DEFAULTCHAR

    wm

    Windows message numbers

    0x0010, wm

    WM_CLOSE

    !

    raw format, ignoring any data type views customizations

    i !

    4

    The following table contains formatting symbols used for memory locations. You can use a memory location specifier with any value or expression that evaluates to a location.

    Symbol

    Format

    Expression

    Value Displayed

    ma

    64 ASCII characters

    ptr, ma

    0x0012ffac .4...0...".0W&.......1W&.0.:W..1...."..1.JO&.1.2.."..1...0y....1

    m

    16 bytes in hexadecimal, followed by 16 ASCII characters

    ptr, m

    0x0012ffac B3 34 CB 00 84 30 94 80 FF 22 8A 30 57 26 00 00 .4...0...".0W&..

    mb

    16 bytes in hexadecimal, followed by 16 ASCII characters

    ptr, mb

    0x0012ffac B3 34 CB 00 84 30 94 80 FF 22 8A 30 57 26 00 00 .4...0...".0W&..

    mw

    8 words

    ptr, mw

    0x0012ffac 34B3 00CB 3084 8094 22FF 308A 2657 0000

    md

    4 doublewords

    ptr, md

    0x0012ffac 00CB34B3 80943084 308A22FF 00002657

    mq

    2 quadwords

    ptr, mq

    0x0012ffac 7ffdf00000000000 5f441a790012fdd4

    mu

    2-byte characters (Unicode)

    ptr, mu

    0x0012fc60 8478 77f4 ffff ffff 0000 0000 0000 0000

    If you have a pointer to an object you want to view as an array, you can use an integer to specify the number of array elements:

    Specifier

    Format

    Expression

    Value Displayed

    n

    Decimal integer

    pBuffer[32]

    Displays pBuffer as a 32 element array.




    @IS2120#CNBLOGS.T2169364049[T1,L65,R1,V259]:备忘
    $ € ₤ ₭ ₪ ₩ ₮ ₦ ₱ ฿ ₡ ₫ ﷼ ¥ ﷼ ₫ ₡ ฿ ₱ ₦ ₮ ₩ ₪ ₭ ₤ € $
  • 相关阅读:
    windows下区块链,私有链搭建详细教程(图文详解)
    MySQL 5.7 mysqldump的Bug导致复制异常
    关于MySQL 5.6 DDL阻塞DML的问题!
    mysqldump 根据时间字段导出数据的问题
    MySQL undo redo
    InnoDB undo, redo,binlog,data什么时候写?
    MySQL master 宕机导致slave数据比master多的case
    Jboss配置自动重连数据库
    星爷001正式开始写blog啦
    本地及远程二级缓存
  • 原文地址:https://www.cnblogs.com/IS2120/p/6745740.html
Copyright © 2020-2023  润新知