我有两个指向同一地址的指针变量:
(gdb) p a
$1 = (MyClass *) 0x7fd7251e58f8
(gdb) p store._head._ptr
$2 = (MyClass *) 0x7fd7251e58f8
但是当我取消引用它们时,我会得到不同的结果:
(gdb) p *a
$3 = {<MyBase> = {_state = 0}, price = 1, quantity = 1,
arrivalTime = 1430087034755819, matchTime =
"-18:23:53.000\000\000\000\000\000\000\000\035"}
(gdb) p *store._head._ptr
$4 = {<MyBase> = {_state = 0}, price = 1, quantity = 1,
arrivalTime = 1430087034755819, matchTime =
"20150427-18:23:53.000"}
看到区别?它只在matchTime
字段中显示。所以我检查了两个实例中字段的相对偏移量:
(gdb) p ((char*)&a->matchTime) - (char*)a
$5 = 28
(gdb) p ((char*)&store._head._ptr->matchTime) - (char*)store._head._ptr
$6 = 20
我能理解为什么我得到20,因为有3个32位整数,后跟64位整数,总共3 * 4 + 8 = 20个字节。
显然,GDB认为两个指针变量的类型名称相同,MyClass*
。但它显然也认为每个变量都是不同的类型!
我怎样才能深入挖掘?我怎样才能区分每种类型?
更新:问题是链接器问题。代码链接到库和标题的错误版本。这导致通过store._head._ptr
访问的指针变量具有与库代码的其余部分相同的(旧)类型信息,而指针变量a
具有不兼容(较新)的类型信息。
但我的问题仍然存在。 GDB是如何知道存在差异的? 如何向GDB询问用于解除引用的类型?
在每个变量上使用ptype
会产生MyClass*
类型信息的相同输出。但是GDB仍然在每个指针变量上进行不同的解除引用。
我尝试在可执行文件和库上使用nm
和objdump
,但我无法使用其输出来区分不同的类型。
那么如何更详细地查询GDB有关每个变量的类型和调试信息呢?
答案 0 :(得分:1)
是的,所以我们现在可以看到您调用了未定义的行为。只要有足够的时间和精力,就可能重现问题并使用GDB源代码来跟踪导致您目睹的症状的精确事件序列。然而,这可能会填补(枯燥的)博士论文,完全没有价值。当您看到像这样的奇怪,不一致的行为时,出现了错误,在尝试使用受影响的工具/输出/机制进行任何进一步诊断之前,找到UB的来源符合您的最佳利益。 / p>
答案 1 :(得分:0)
在每个变量上使用ptype产生相同的MyClass *类型信息输出。
但使用ptype *a
和ptype *store._head._ptr
应该会显示差异。