DbgHelp: Wrong address of function parameter when it is a pass-by-value symbol on x64 Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!Function passed as template argumentDefault value of function parameternew[] expression does not respect alignment in Microsoft VC++Where to put default parameter value in C++?Are the days of passing const std::string & as a parameter over?x64 memset core, is passed buffer address truncated?How to convert a function address to a symbolDbgHelp - Get full symbol signature (function name + parameters types)iocp socket close_wait status, how to fix it?Allocation of Return Values of User Defined Functions: Performance?

calculator's angle answer for trig ratios that can work in more than 1 quadrant on the unit circle

Why are two-digit numbers in Jonathan Swift's "Gulliver's Travels" (1726) written in "German style"?

Sally's older brother

Baking rewards as operations

Is there a verb for listening stealthily?

Is the time—manner—place ordering of adverbials an oversimplification?

3D Masyu - A Die

Getting representations of the Lie group out of representations of its Lie algebra

How to make triangles with rounded sides and corners? (squircle with 3 sides)

Are there any irrational/transcendental numbers for which the distribution of decimal digits is not uniform?

First paper to introduce the "principal-agent problem"

Is this Kuo-toa homebrew race balanced?

Is the Mordenkainen's Sword spell underpowered?

Weaponising the Grasp-at-a-Distance spell

What is "Lambda" in Heston's original paper on stochastic volatility models?

NIntegrate on a solution of a matrix ODE

Where did Ptolemy compare the Earth to the distance of fixed stars?

Noise in Eigenvalues plot

"Destructive power" carried by a B-52?

Does the main washing effect of soap come from foam?

Inverse square law not accurate for non-point masses?

How do you write "wild blueberries flavored"?

How to name indistinguishable henchmen in a screenplay?

Long-end softness in a wide-angle lens



DbgHelp: Wrong address of function parameter when it is a pass-by-value symbol on x64



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!Function passed as template argumentDefault value of function parameternew[] expression does not respect alignment in Microsoft VC++Where to put default parameter value in C++?Are the days of passing const std::string & as a parameter over?x64 memset core, is passed buffer address truncated?How to convert a function address to a symbolDbgHelp - Get full symbol signature (function name + parameters types)iocp socket close_wait status, how to fix it?Allocation of Return Values of User Defined Functions: Performance?



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








0















I am using the Windows DbgHelp library to dump a callstack of my C++ application. The PDB is in the right place and I am successfully reporting the stack frames. I have an involved type traversal system that prints out all of the locals and this is mostly working. However, in some cases I am getting the wrong address and causing access violations. One case is when a function is passed an object by value:



struct Object float x,y,z; 

void foo( Object objectByValue)

// dump callstack



In this case, the address calculated for objectByValue is wrong. It is near the correct place on the stack, but not exactly. I am having some difficulties finding information on the right address. I am doing the following:



  • Set the correct context with SymSetContext(...)

  • Invoke SymEnumSymbols with a callback

  • Inside the callback, check if SYMFLAG_REGREL is set

  • Assign Address = SymInfo->Address + context.rbp or context.rsp depending on
    the SymInfo.Register value (CV_AMD64_RBP or CV_AMD64_RSP are only
    ever present )

  • Then I use that address to access the variable.

For variables on the stack this address is correct, as it is for most other cases. However, it is not in some, including this case.



I have included a working example below with the following output:



main-> Address of on stack: 000000000020B0D0 = 1.000000, 2.000000,
3.000000
foo-> Address of parameters: 000000000020D6F8 = 1.000000, 2.000000, 3.000000
Print stack from bottom up:
Frame: foo Variable: objByValue offset=0xe0 address=0x20b090 size=8204
Frame: main Variable: objOnStack offset=0x10 address=0x20b0d0 size=8204


You can see in the example that the address calculate from the variable on the stack is correct, but for the pass by value it is wrong.



Does anyone have any insight on how I can correctly calculate this value?



#include "stdafx.h"
#include <windows.h>
#include <stdint.h>

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

#pragma pack( push, before_imagehlp, 8 )
#include <imagehlp.h>
#pragma pack( pop, before_imagehlp )

// Normally it should be enough to use 'CONTEXT_FULL' (better would be 'CONTEXT_ALL')
#define USED_CONTEXT_FLAGS CONTEXT_FULL

#if defined(_M_AMD64)
const int ImageFileMachine = IMAGE_FILE_MACHINE_AMD64;
#else
const int ImageFileMachine = IMAGE_FILE_MACHINE_I386;
#endif
struct BaseAddresses

uint64_t Rsp;
uint64_t Rbp;
;

const int C_X64_REGISTER_RBP = 334; // Frame Base Pointer register
const int C_X64_REGISTER_RSP = 335; // Stack Pointer register (common in release builds with frame pointer removal)

BOOL EnumSymbolsCallback(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext)

BaseAddresses * pBaseAddresses = (BaseAddresses*)UserContext;
ULONG64 base = 0;

if ((pSymInfo->Flags & SYMFLAG_REGREL) != 0)

switch (pSymInfo->Register)

case C_X64_REGISTER_RBP:
base = (ULONG64)pBaseAddresses->Rbp;
break;
case C_X64_REGISTER_RSP:
base = (ULONG64)pBaseAddresses->Rsp;
break;
default:
exit(0);



ULONG64 address = base + pSymInfo->Address;

printf("Variable: %s offset=0x%llx address=0x%llx size=%lun", pSymInfo->Name, pSymInfo->Address, address, pSymInfo->Size);

return TRUE;


DWORD DumpStackTrace()

HANDLE mProcess = GetCurrentProcess();
HANDLE mThread = GetCurrentThread();

if (!SymInitialize(mProcess, NULL, TRUE)) // load symbols, invasive
return 0;

CONTEXT c;

memset(&c, 0, sizeof(CONTEXT));
c.ContextFlags = USED_CONTEXT_FLAGS;
RtlCaptureContext(&c);

// SYMBOL_INFO & buffer storage
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;

STACKFRAME64 frame;
memset(&frame, 0, sizeof(STACKFRAME64));

DWORD64 displacement_from_symbol = 0;

printf("Print stack from bottom up:n");

int framesToSkip = 1; // skip reporting this frame
do

// Get next stack frame
if (!StackWalk64(ImageFileMachine, mProcess, mThread, &frame, &c, nullptr, SymFunctionTableAccess64, SymGetModuleBase64, nullptr))

break;

// Lookup symbol name using the address
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_SYM_NAME;
if (!SymFromAddr(mProcess, (ULONG64)frame.AddrPC.Offset, &displacement_from_symbol, pSymbol))
return false;

if (framesToSkip > 0)

framesToSkip--;
continue;


printf("Frame: %sn", pSymbol->Name);
// Setup the context to get to the parameters
IMAGEHLP_STACK_FRAME imSFrame = 0 ;
imSFrame.InstructionOffset = frame.AddrPC.Offset;

if (!SymSetContext(mProcess, &imSFrame, NULL))
return false;

BaseAddresses addresses;
addresses.Rbp = c.Rbp;
addresses.Rsp = c.Rsp;

if (!SymEnumSymbols(mProcess, 0, 0, EnumSymbolsCallback, &addresses))

return false;


if (strcmp(pSymbol->Name, "main") == 0)
break;


while (frame.AddrReturn.Offset != 0);

SymCleanup(mProcess);

return 0;


struct Structure

float x, y, z;
;

void foo(Structure objByValue)

printf("foo-> Address of parameters: %p = %f, %f, %f n", &objByValue, objByValue.x, objByValue.y, objByValue.z);
DumpStackTrace();


int main()

Structure objOnStack = 1, 2, 3 ;

printf("main-> Address of on stack: %p = %f, %f, %f n", &objOnStack, objOnStack.x, objOnStack.y, objOnStack.z);

foo(objOnStack);
return 0;










share|improve this question






























    0















    I am using the Windows DbgHelp library to dump a callstack of my C++ application. The PDB is in the right place and I am successfully reporting the stack frames. I have an involved type traversal system that prints out all of the locals and this is mostly working. However, in some cases I am getting the wrong address and causing access violations. One case is when a function is passed an object by value:



    struct Object float x,y,z; 

    void foo( Object objectByValue)

    // dump callstack



    In this case, the address calculated for objectByValue is wrong. It is near the correct place on the stack, but not exactly. I am having some difficulties finding information on the right address. I am doing the following:



    • Set the correct context with SymSetContext(...)

    • Invoke SymEnumSymbols with a callback

    • Inside the callback, check if SYMFLAG_REGREL is set

    • Assign Address = SymInfo->Address + context.rbp or context.rsp depending on
      the SymInfo.Register value (CV_AMD64_RBP or CV_AMD64_RSP are only
      ever present )

    • Then I use that address to access the variable.

    For variables on the stack this address is correct, as it is for most other cases. However, it is not in some, including this case.



    I have included a working example below with the following output:



    main-> Address of on stack: 000000000020B0D0 = 1.000000, 2.000000,
    3.000000
    foo-> Address of parameters: 000000000020D6F8 = 1.000000, 2.000000, 3.000000
    Print stack from bottom up:
    Frame: foo Variable: objByValue offset=0xe0 address=0x20b090 size=8204
    Frame: main Variable: objOnStack offset=0x10 address=0x20b0d0 size=8204


    You can see in the example that the address calculate from the variable on the stack is correct, but for the pass by value it is wrong.



    Does anyone have any insight on how I can correctly calculate this value?



    #include "stdafx.h"
    #include <windows.h>
    #include <stdint.h>

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

    #pragma pack( push, before_imagehlp, 8 )
    #include <imagehlp.h>
    #pragma pack( pop, before_imagehlp )

    // Normally it should be enough to use 'CONTEXT_FULL' (better would be 'CONTEXT_ALL')
    #define USED_CONTEXT_FLAGS CONTEXT_FULL

    #if defined(_M_AMD64)
    const int ImageFileMachine = IMAGE_FILE_MACHINE_AMD64;
    #else
    const int ImageFileMachine = IMAGE_FILE_MACHINE_I386;
    #endif
    struct BaseAddresses

    uint64_t Rsp;
    uint64_t Rbp;
    ;

    const int C_X64_REGISTER_RBP = 334; // Frame Base Pointer register
    const int C_X64_REGISTER_RSP = 335; // Stack Pointer register (common in release builds with frame pointer removal)

    BOOL EnumSymbolsCallback(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext)

    BaseAddresses * pBaseAddresses = (BaseAddresses*)UserContext;
    ULONG64 base = 0;

    if ((pSymInfo->Flags & SYMFLAG_REGREL) != 0)

    switch (pSymInfo->Register)

    case C_X64_REGISTER_RBP:
    base = (ULONG64)pBaseAddresses->Rbp;
    break;
    case C_X64_REGISTER_RSP:
    base = (ULONG64)pBaseAddresses->Rsp;
    break;
    default:
    exit(0);



    ULONG64 address = base + pSymInfo->Address;

    printf("Variable: %s offset=0x%llx address=0x%llx size=%lun", pSymInfo->Name, pSymInfo->Address, address, pSymInfo->Size);

    return TRUE;


    DWORD DumpStackTrace()

    HANDLE mProcess = GetCurrentProcess();
    HANDLE mThread = GetCurrentThread();

    if (!SymInitialize(mProcess, NULL, TRUE)) // load symbols, invasive
    return 0;

    CONTEXT c;

    memset(&c, 0, sizeof(CONTEXT));
    c.ContextFlags = USED_CONTEXT_FLAGS;
    RtlCaptureContext(&c);

    // SYMBOL_INFO & buffer storage
    char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
    PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;

    STACKFRAME64 frame;
    memset(&frame, 0, sizeof(STACKFRAME64));

    DWORD64 displacement_from_symbol = 0;

    printf("Print stack from bottom up:n");

    int framesToSkip = 1; // skip reporting this frame
    do

    // Get next stack frame
    if (!StackWalk64(ImageFileMachine, mProcess, mThread, &frame, &c, nullptr, SymFunctionTableAccess64, SymGetModuleBase64, nullptr))

    break;

    // Lookup symbol name using the address
    pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
    pSymbol->MaxNameLen = MAX_SYM_NAME;
    if (!SymFromAddr(mProcess, (ULONG64)frame.AddrPC.Offset, &displacement_from_symbol, pSymbol))
    return false;

    if (framesToSkip > 0)

    framesToSkip--;
    continue;


    printf("Frame: %sn", pSymbol->Name);
    // Setup the context to get to the parameters
    IMAGEHLP_STACK_FRAME imSFrame = 0 ;
    imSFrame.InstructionOffset = frame.AddrPC.Offset;

    if (!SymSetContext(mProcess, &imSFrame, NULL))
    return false;

    BaseAddresses addresses;
    addresses.Rbp = c.Rbp;
    addresses.Rsp = c.Rsp;

    if (!SymEnumSymbols(mProcess, 0, 0, EnumSymbolsCallback, &addresses))

    return false;


    if (strcmp(pSymbol->Name, "main") == 0)
    break;


    while (frame.AddrReturn.Offset != 0);

    SymCleanup(mProcess);

    return 0;


    struct Structure

    float x, y, z;
    ;

    void foo(Structure objByValue)

    printf("foo-> Address of parameters: %p = %f, %f, %f n", &objByValue, objByValue.x, objByValue.y, objByValue.z);
    DumpStackTrace();


    int main()

    Structure objOnStack = 1, 2, 3 ;

    printf("main-> Address of on stack: %p = %f, %f, %f n", &objOnStack, objOnStack.x, objOnStack.y, objOnStack.z);

    foo(objOnStack);
    return 0;










    share|improve this question


























      0












      0








      0








      I am using the Windows DbgHelp library to dump a callstack of my C++ application. The PDB is in the right place and I am successfully reporting the stack frames. I have an involved type traversal system that prints out all of the locals and this is mostly working. However, in some cases I am getting the wrong address and causing access violations. One case is when a function is passed an object by value:



      struct Object float x,y,z; 

      void foo( Object objectByValue)

      // dump callstack



      In this case, the address calculated for objectByValue is wrong. It is near the correct place on the stack, but not exactly. I am having some difficulties finding information on the right address. I am doing the following:



      • Set the correct context with SymSetContext(...)

      • Invoke SymEnumSymbols with a callback

      • Inside the callback, check if SYMFLAG_REGREL is set

      • Assign Address = SymInfo->Address + context.rbp or context.rsp depending on
        the SymInfo.Register value (CV_AMD64_RBP or CV_AMD64_RSP are only
        ever present )

      • Then I use that address to access the variable.

      For variables on the stack this address is correct, as it is for most other cases. However, it is not in some, including this case.



      I have included a working example below with the following output:



      main-> Address of on stack: 000000000020B0D0 = 1.000000, 2.000000,
      3.000000
      foo-> Address of parameters: 000000000020D6F8 = 1.000000, 2.000000, 3.000000
      Print stack from bottom up:
      Frame: foo Variable: objByValue offset=0xe0 address=0x20b090 size=8204
      Frame: main Variable: objOnStack offset=0x10 address=0x20b0d0 size=8204


      You can see in the example that the address calculate from the variable on the stack is correct, but for the pass by value it is wrong.



      Does anyone have any insight on how I can correctly calculate this value?



      #include "stdafx.h"
      #include <windows.h>
      #include <stdint.h>

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

      #pragma pack( push, before_imagehlp, 8 )
      #include <imagehlp.h>
      #pragma pack( pop, before_imagehlp )

      // Normally it should be enough to use 'CONTEXT_FULL' (better would be 'CONTEXT_ALL')
      #define USED_CONTEXT_FLAGS CONTEXT_FULL

      #if defined(_M_AMD64)
      const int ImageFileMachine = IMAGE_FILE_MACHINE_AMD64;
      #else
      const int ImageFileMachine = IMAGE_FILE_MACHINE_I386;
      #endif
      struct BaseAddresses

      uint64_t Rsp;
      uint64_t Rbp;
      ;

      const int C_X64_REGISTER_RBP = 334; // Frame Base Pointer register
      const int C_X64_REGISTER_RSP = 335; // Stack Pointer register (common in release builds with frame pointer removal)

      BOOL EnumSymbolsCallback(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext)

      BaseAddresses * pBaseAddresses = (BaseAddresses*)UserContext;
      ULONG64 base = 0;

      if ((pSymInfo->Flags & SYMFLAG_REGREL) != 0)

      switch (pSymInfo->Register)

      case C_X64_REGISTER_RBP:
      base = (ULONG64)pBaseAddresses->Rbp;
      break;
      case C_X64_REGISTER_RSP:
      base = (ULONG64)pBaseAddresses->Rsp;
      break;
      default:
      exit(0);



      ULONG64 address = base + pSymInfo->Address;

      printf("Variable: %s offset=0x%llx address=0x%llx size=%lun", pSymInfo->Name, pSymInfo->Address, address, pSymInfo->Size);

      return TRUE;


      DWORD DumpStackTrace()

      HANDLE mProcess = GetCurrentProcess();
      HANDLE mThread = GetCurrentThread();

      if (!SymInitialize(mProcess, NULL, TRUE)) // load symbols, invasive
      return 0;

      CONTEXT c;

      memset(&c, 0, sizeof(CONTEXT));
      c.ContextFlags = USED_CONTEXT_FLAGS;
      RtlCaptureContext(&c);

      // SYMBOL_INFO & buffer storage
      char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
      PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;

      STACKFRAME64 frame;
      memset(&frame, 0, sizeof(STACKFRAME64));

      DWORD64 displacement_from_symbol = 0;

      printf("Print stack from bottom up:n");

      int framesToSkip = 1; // skip reporting this frame
      do

      // Get next stack frame
      if (!StackWalk64(ImageFileMachine, mProcess, mThread, &frame, &c, nullptr, SymFunctionTableAccess64, SymGetModuleBase64, nullptr))

      break;

      // Lookup symbol name using the address
      pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
      pSymbol->MaxNameLen = MAX_SYM_NAME;
      if (!SymFromAddr(mProcess, (ULONG64)frame.AddrPC.Offset, &displacement_from_symbol, pSymbol))
      return false;

      if (framesToSkip > 0)

      framesToSkip--;
      continue;


      printf("Frame: %sn", pSymbol->Name);
      // Setup the context to get to the parameters
      IMAGEHLP_STACK_FRAME imSFrame = 0 ;
      imSFrame.InstructionOffset = frame.AddrPC.Offset;

      if (!SymSetContext(mProcess, &imSFrame, NULL))
      return false;

      BaseAddresses addresses;
      addresses.Rbp = c.Rbp;
      addresses.Rsp = c.Rsp;

      if (!SymEnumSymbols(mProcess, 0, 0, EnumSymbolsCallback, &addresses))

      return false;


      if (strcmp(pSymbol->Name, "main") == 0)
      break;


      while (frame.AddrReturn.Offset != 0);

      SymCleanup(mProcess);

      return 0;


      struct Structure

      float x, y, z;
      ;

      void foo(Structure objByValue)

      printf("foo-> Address of parameters: %p = %f, %f, %f n", &objByValue, objByValue.x, objByValue.y, objByValue.z);
      DumpStackTrace();


      int main()

      Structure objOnStack = 1, 2, 3 ;

      printf("main-> Address of on stack: %p = %f, %f, %f n", &objOnStack, objOnStack.x, objOnStack.y, objOnStack.z);

      foo(objOnStack);
      return 0;










      share|improve this question
















      I am using the Windows DbgHelp library to dump a callstack of my C++ application. The PDB is in the right place and I am successfully reporting the stack frames. I have an involved type traversal system that prints out all of the locals and this is mostly working. However, in some cases I am getting the wrong address and causing access violations. One case is when a function is passed an object by value:



      struct Object float x,y,z; 

      void foo( Object objectByValue)

      // dump callstack



      In this case, the address calculated for objectByValue is wrong. It is near the correct place on the stack, but not exactly. I am having some difficulties finding information on the right address. I am doing the following:



      • Set the correct context with SymSetContext(...)

      • Invoke SymEnumSymbols with a callback

      • Inside the callback, check if SYMFLAG_REGREL is set

      • Assign Address = SymInfo->Address + context.rbp or context.rsp depending on
        the SymInfo.Register value (CV_AMD64_RBP or CV_AMD64_RSP are only
        ever present )

      • Then I use that address to access the variable.

      For variables on the stack this address is correct, as it is for most other cases. However, it is not in some, including this case.



      I have included a working example below with the following output:



      main-> Address of on stack: 000000000020B0D0 = 1.000000, 2.000000,
      3.000000
      foo-> Address of parameters: 000000000020D6F8 = 1.000000, 2.000000, 3.000000
      Print stack from bottom up:
      Frame: foo Variable: objByValue offset=0xe0 address=0x20b090 size=8204
      Frame: main Variable: objOnStack offset=0x10 address=0x20b0d0 size=8204


      You can see in the example that the address calculate from the variable on the stack is correct, but for the pass by value it is wrong.



      Does anyone have any insight on how I can correctly calculate this value?



      #include "stdafx.h"
      #include <windows.h>
      #include <stdint.h>

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

      #pragma pack( push, before_imagehlp, 8 )
      #include <imagehlp.h>
      #pragma pack( pop, before_imagehlp )

      // Normally it should be enough to use 'CONTEXT_FULL' (better would be 'CONTEXT_ALL')
      #define USED_CONTEXT_FLAGS CONTEXT_FULL

      #if defined(_M_AMD64)
      const int ImageFileMachine = IMAGE_FILE_MACHINE_AMD64;
      #else
      const int ImageFileMachine = IMAGE_FILE_MACHINE_I386;
      #endif
      struct BaseAddresses

      uint64_t Rsp;
      uint64_t Rbp;
      ;

      const int C_X64_REGISTER_RBP = 334; // Frame Base Pointer register
      const int C_X64_REGISTER_RSP = 335; // Stack Pointer register (common in release builds with frame pointer removal)

      BOOL EnumSymbolsCallback(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext)

      BaseAddresses * pBaseAddresses = (BaseAddresses*)UserContext;
      ULONG64 base = 0;

      if ((pSymInfo->Flags & SYMFLAG_REGREL) != 0)

      switch (pSymInfo->Register)

      case C_X64_REGISTER_RBP:
      base = (ULONG64)pBaseAddresses->Rbp;
      break;
      case C_X64_REGISTER_RSP:
      base = (ULONG64)pBaseAddresses->Rsp;
      break;
      default:
      exit(0);



      ULONG64 address = base + pSymInfo->Address;

      printf("Variable: %s offset=0x%llx address=0x%llx size=%lun", pSymInfo->Name, pSymInfo->Address, address, pSymInfo->Size);

      return TRUE;


      DWORD DumpStackTrace()

      HANDLE mProcess = GetCurrentProcess();
      HANDLE mThread = GetCurrentThread();

      if (!SymInitialize(mProcess, NULL, TRUE)) // load symbols, invasive
      return 0;

      CONTEXT c;

      memset(&c, 0, sizeof(CONTEXT));
      c.ContextFlags = USED_CONTEXT_FLAGS;
      RtlCaptureContext(&c);

      // SYMBOL_INFO & buffer storage
      char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
      PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;

      STACKFRAME64 frame;
      memset(&frame, 0, sizeof(STACKFRAME64));

      DWORD64 displacement_from_symbol = 0;

      printf("Print stack from bottom up:n");

      int framesToSkip = 1; // skip reporting this frame
      do

      // Get next stack frame
      if (!StackWalk64(ImageFileMachine, mProcess, mThread, &frame, &c, nullptr, SymFunctionTableAccess64, SymGetModuleBase64, nullptr))

      break;

      // Lookup symbol name using the address
      pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
      pSymbol->MaxNameLen = MAX_SYM_NAME;
      if (!SymFromAddr(mProcess, (ULONG64)frame.AddrPC.Offset, &displacement_from_symbol, pSymbol))
      return false;

      if (framesToSkip > 0)

      framesToSkip--;
      continue;


      printf("Frame: %sn", pSymbol->Name);
      // Setup the context to get to the parameters
      IMAGEHLP_STACK_FRAME imSFrame = 0 ;
      imSFrame.InstructionOffset = frame.AddrPC.Offset;

      if (!SymSetContext(mProcess, &imSFrame, NULL))
      return false;

      BaseAddresses addresses;
      addresses.Rbp = c.Rbp;
      addresses.Rsp = c.Rsp;

      if (!SymEnumSymbols(mProcess, 0, 0, EnumSymbolsCallback, &addresses))

      return false;


      if (strcmp(pSymbol->Name, "main") == 0)
      break;


      while (frame.AddrReturn.Offset != 0);

      SymCleanup(mProcess);

      return 0;


      struct Structure

      float x, y, z;
      ;

      void foo(Structure objByValue)

      printf("foo-> Address of parameters: %p = %f, %f, %f n", &objByValue, objByValue.x, objByValue.y, objByValue.z);
      DumpStackTrace();


      int main()

      Structure objOnStack = 1, 2, 3 ;

      printf("main-> Address of on stack: %p = %f, %f, %f n", &objOnStack, objOnStack.x, objOnStack.y, objOnStack.z);

      foo(objOnStack);
      return 0;







      c++ windows debugging pdb-files diagnostics






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Mar 9 at 1:18







      Steven

















      asked Mar 9 at 0:49









      StevenSteven

      309115




      309115






















          1 Answer
          1






          active

          oldest

          votes


















          0














          After reading the documentation on X64 calling convention I discovered the following sentence:




          Any argument that doesn’t fit in 8 bytes, or isn't 1, 2, 4, or 8
          bytes, must be passed by reference 1




          So that explains the funny address - what the debug symbols are giving me is the address of the memory storing the reference to the full data. So my code flow essentially says:



          if ( symbol is a parameter and the size > 8 )
          address = *(uint64_t)address; // dereference



          And then passing that address through my type system resolves correctly.



          I thought other people might find this useful as it is not documented anywhere in the DbgHelp library, and while some people might understand the calling conventions, it didn't occur to me that the symbol data passed back wouldn't contain something helpful to indicate this.






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55072910%2fdbghelp-wrong-address-of-function-parameter-when-it-is-a-pass-by-value-symbol-o%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            After reading the documentation on X64 calling convention I discovered the following sentence:




            Any argument that doesn’t fit in 8 bytes, or isn't 1, 2, 4, or 8
            bytes, must be passed by reference 1




            So that explains the funny address - what the debug symbols are giving me is the address of the memory storing the reference to the full data. So my code flow essentially says:



            if ( symbol is a parameter and the size > 8 )
            address = *(uint64_t)address; // dereference



            And then passing that address through my type system resolves correctly.



            I thought other people might find this useful as it is not documented anywhere in the DbgHelp library, and while some people might understand the calling conventions, it didn't occur to me that the symbol data passed back wouldn't contain something helpful to indicate this.






            share|improve this answer



























              0














              After reading the documentation on X64 calling convention I discovered the following sentence:




              Any argument that doesn’t fit in 8 bytes, or isn't 1, 2, 4, or 8
              bytes, must be passed by reference 1




              So that explains the funny address - what the debug symbols are giving me is the address of the memory storing the reference to the full data. So my code flow essentially says:



              if ( symbol is a parameter and the size > 8 )
              address = *(uint64_t)address; // dereference



              And then passing that address through my type system resolves correctly.



              I thought other people might find this useful as it is not documented anywhere in the DbgHelp library, and while some people might understand the calling conventions, it didn't occur to me that the symbol data passed back wouldn't contain something helpful to indicate this.






              share|improve this answer

























                0












                0








                0







                After reading the documentation on X64 calling convention I discovered the following sentence:




                Any argument that doesn’t fit in 8 bytes, or isn't 1, 2, 4, or 8
                bytes, must be passed by reference 1




                So that explains the funny address - what the debug symbols are giving me is the address of the memory storing the reference to the full data. So my code flow essentially says:



                if ( symbol is a parameter and the size > 8 )
                address = *(uint64_t)address; // dereference



                And then passing that address through my type system resolves correctly.



                I thought other people might find this useful as it is not documented anywhere in the DbgHelp library, and while some people might understand the calling conventions, it didn't occur to me that the symbol data passed back wouldn't contain something helpful to indicate this.






                share|improve this answer













                After reading the documentation on X64 calling convention I discovered the following sentence:




                Any argument that doesn’t fit in 8 bytes, or isn't 1, 2, 4, or 8
                bytes, must be passed by reference 1




                So that explains the funny address - what the debug symbols are giving me is the address of the memory storing the reference to the full data. So my code flow essentially says:



                if ( symbol is a parameter and the size > 8 )
                address = *(uint64_t)address; // dereference



                And then passing that address through my type system resolves correctly.



                I thought other people might find this useful as it is not documented anywhere in the DbgHelp library, and while some people might understand the calling conventions, it didn't occur to me that the symbol data passed back wouldn't contain something helpful to indicate this.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Mar 13 at 17:59









                StevenSteven

                309115




                309115





























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55072910%2fdbghelp-wrong-address-of-function-parameter-when-it-is-a-pass-by-value-symbol-o%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    1928 у кіно

                    Захаров Федір Захарович

                    Ель Греко