结构成员值为零但宏检查它是否为零 returns 0,为什么?
struct member value zero but macro checking if it's zero returns 0, why?
在arch/arm64/include/asm/pgtable-types.h
typedef struct { pgdval_t pgd; } pgd_t;
#define pgd_val(x) ((x).pgd)
#define __pgd(x) ((pgd_t) { (x) } )
并且在arch/arm64/include/asm/pgtable.h,
#define pgd_none(pgd) (!pgd_val(pgd))
在使用 qemu 和 gdb 进行调试期间,我在 arch/arm64/mm/mmu.c 中,它读取地址 pgdp 中的 pgd 条目,如果它为空,则用指向 bm_pud.[=16= 的指针填充它]
void __init early_fixmap_init(void)
{
pgd_t *pgdp, pgd;
pud_t *pudp;
pmd_t *pmdp;
unsigned long addr = FIXADDR_START;
pgdp = pgd_offset_k(addr);
pgd = READ_ONCE(*pgdp);
if (CONFIG_PGTABLE_LEVELS > 3 &&
!(pgd_none(pgd) || pgd_page_paddr(pgd) == __pa_symbol(bm_pud))) {
/*
* We only end up here if the kernel mapping and the fixmap
* share the top level pgd entry, which should only happen on
* 16k/4 levels configurations.
*/
BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES));
pudp = pud_offset_kimg(pgdp, addr);
} else {
if (pgd_none(pgd)) <====== here!!
__pgd_populate(pgdp, __pa_symbol(bm_pud), PUD_TYPE_TABLE);
pudp = fixmap_pud(addr);
}
当gdb在上面标有<=== here!!
的行时,
(gdb) p pgd
= {pgd = 0x0}
(gdb) p pgd_none(pgd)
= 0x0
pgd 值为 0,但 pgd_none 输出也为 0,而它应该为 1(真)并且它跳过了 __pgd_populate 函数。这里有什么问题?
(gdb) info func pgd_none
说了什么?
我怀疑您正在调用一个函数,而不是您打算“调用”的宏。
事实上,我不确定 GDB 是否甚至能够 计算宏。
更新:
正如 ssbssa@ 指出的那样,GDB documented 支持宏计算,如果使用 -g3
.
编译源代码,它将自动执行此操作
但是,GDB 中存在一个错误(当前版本 12.0.50.20220221-git
),除非使用 -gdwarf-4
编译代码。
这是一个简单的测试:
#define FOO(x) (x - 42)
int main()
{
int x = 42;
return FOO(x);
}
用gcc -g3 foo.c -gdwarf-4
编译。
Reading symbols from ./a.out...
(gdb) start
Temporary breakpoint 1 at 0x112d: file foo.c, line 5.
Starting program: /tmp/a.out
Temporary breakpoint 1, main () at foo.c:5
5 int x = 42;
(gdb) n
6 return FOO(x);
(gdb) p FOO(1)
= -41
在arch/arm64/include/asm/pgtable-types.h
typedef struct { pgdval_t pgd; } pgd_t;
#define pgd_val(x) ((x).pgd)
#define __pgd(x) ((pgd_t) { (x) } )
并且在arch/arm64/include/asm/pgtable.h,
#define pgd_none(pgd) (!pgd_val(pgd))
在使用 qemu 和 gdb 进行调试期间,我在 arch/arm64/mm/mmu.c 中,它读取地址 pgdp 中的 pgd 条目,如果它为空,则用指向 bm_pud.[=16= 的指针填充它]
void __init early_fixmap_init(void)
{
pgd_t *pgdp, pgd;
pud_t *pudp;
pmd_t *pmdp;
unsigned long addr = FIXADDR_START;
pgdp = pgd_offset_k(addr);
pgd = READ_ONCE(*pgdp);
if (CONFIG_PGTABLE_LEVELS > 3 &&
!(pgd_none(pgd) || pgd_page_paddr(pgd) == __pa_symbol(bm_pud))) {
/*
* We only end up here if the kernel mapping and the fixmap
* share the top level pgd entry, which should only happen on
* 16k/4 levels configurations.
*/
BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES));
pudp = pud_offset_kimg(pgdp, addr);
} else {
if (pgd_none(pgd)) <====== here!!
__pgd_populate(pgdp, __pa_symbol(bm_pud), PUD_TYPE_TABLE);
pudp = fixmap_pud(addr);
}
当gdb在上面标有<=== here!!
的行时,
(gdb) p pgd
= {pgd = 0x0}
(gdb) p pgd_none(pgd)
= 0x0
pgd 值为 0,但 pgd_none 输出也为 0,而它应该为 1(真)并且它跳过了 __pgd_populate 函数。这里有什么问题?
(gdb) info func pgd_none
说了什么?
我怀疑您正在调用一个函数,而不是您打算“调用”的宏。
事实上,我不确定 GDB 是否甚至能够 计算宏。
更新:
正如 ssbssa@ 指出的那样,GDB documented 支持宏计算,如果使用 -g3
.
但是,GDB 中存在一个错误(当前版本 12.0.50.20220221-git
),除非使用 -gdwarf-4
编译代码。
这是一个简单的测试:
#define FOO(x) (x - 42)
int main()
{
int x = 42;
return FOO(x);
}
用gcc -g3 foo.c -gdwarf-4
编译。
Reading symbols from ./a.out...
(gdb) start
Temporary breakpoint 1 at 0x112d: file foo.c, line 5.
Starting program: /tmp/a.out
Temporary breakpoint 1, main () at foo.c:5
5 int x = 42;
(gdb) n
6 return FOO(x);
(gdb) p FOO(1)
= -41