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;
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
add a comment |
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
add a comment |
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
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
c++ windows debugging pdb-files diagnostics
edited Mar 9 at 1:18
Steven
asked Mar 9 at 0:49
StevenSteven
309115
309115
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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.
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
add a comment |
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.
add a comment |
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.
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.
answered Mar 13 at 17:59
StevenSteven
309115
309115
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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