GDB并获得结构字段的绝对地址?

发布于 2025-02-10 02:07:46 字数 2630 浏览 1 评论 0原文

我想做与如何为具有该类型的每个结构变量观看结构的成员? - 但是我在嵌入式上,并且有问题。说,我想看(((tcb_t*)pxreadytaskslists [1] .pxindex.pxnext.pvowner).xtaskRunstate,但是,pxreadytaskslists是动态分配的结构,因此我没有一个我可以在“编译”时间使用的绝对地址。因此,我在gdb中尝试了此操作,在我的MAIN函数已足够进步之后,pxreadyTaskSlists是分配的:

(gdb) p &(((TCB_t*)pxReadyTasksLists[1].pxIndex.pxNext.pvOwner))
$41 = (TCB_t **) 0x200015c4 <pxReadyTasksLists+40>

好,所以我拥有看起来像可访问的东西地址在这里;但是,如果我尝试找到该字段的地址:

(gdb) p &(((TCB_t*)pxReadyTasksLists[1].pxIndex.pxNext.pvOwner).xTaskRunState)
$43 = (volatile TaskRunning_t *) 0x38

(gdb) ptype TaskRunning_t
type = long int

...我得到0x38,这对我来说很可疑;实际上,这就是结构中的字段的偏移:

(gdb) ptype /o (TCB_t*)pxReadyTasksLists[1].pxIndex.pxNext.pvOwner
type = struct tskTaskControlBlock {
/*      0      |       4 */    volatile StackType_t *pxTopOfStack;
/*      4      |       4 */    UBaseType_t uxCoreAffinityMask;
/*      8      |      20 */    ListItem_t xStateListItem;
/*     28      |      20 */    ListItem_t xEventListItem;
/*     48      |       4 */    UBaseType_t uxPriority;
/*     52      |       4 */    StackType_t *pxStack;
/*     56      |       4 */    volatile TaskRunning_t xTaskRunState;
/*     60      |       4 */    BaseType_t xIsIdle;
/*     64      |      16 */    char pcTaskName[16];
/*     80      |       4 */    UBaseType_t uxCriticalNesting;
/*     84      |       4 */    UBaseType_t uxTCBNumber;
/*     88      |       4 */    UBaseType_t uxTaskNumber;
/*     92      |       4 */    UBaseType_t uxBasePriority;
/*     96      |       4 */    UBaseType_t uxMutexesHeld;
/*    100      |      20 */    void *pvThreadLocalStoragePointers[5];
/*    120      |      12 */    volatile uint32_t ulNotifiedValue[3];
/*    132      |       3 */    volatile uint8_t ucNotifyState[3];
/*    135      |       1 */    uint8_t ucDelayAborted;

                               /* total size (bytes):  136 */
                             } *

(gdb) p /x 56
$46 = 0x38

因此,地址0x38上的观察点不会(也不会)触发。

我当然可以计算0x200015c4+0x38并在那里设置“长int”手表;但是,如果我重新运行 gdb中的程序,则动态分配pxreadytaskslists我想观看的特定XTASKRUNSTATE的地址。

因此,在这种情况下,是否可以制作一个表达式,gdb可以使用(there)pxreadytaskslists [1] .pxIndex.pxnext.pvowner.xtaskRunstate pxreadytaskslists ,以便我可以在该地址设置一个观察点?

I want to do the same as in How to watch a member of a struct for every struct variable that has that type? - but I am on embedded, and have a problem. Say, I want to watch ((TCB_t*)pxReadyTasksLists[1].pxIndex.pxNext.pvOwner).xTaskRunState, however, pxReadyTasksLists is dynamically allocated array of structs, and so I don't have an absolute address I can use at "compile" time. So I tried this in gdb after my main function has advanced enough, so pxReadyTasksLists is allocated:

(gdb) p &(((TCB_t*)pxReadyTasksLists[1].pxIndex.pxNext.pvOwner))
$41 = (TCB_t **) 0x200015c4 <pxReadyTasksLists+40>

Good, so I have what looks like an accessible address here; however, if I try to find the address of the field:

(gdb) p &(((TCB_t*)pxReadyTasksLists[1].pxIndex.pxNext.pvOwner).xTaskRunState)
$43 = (volatile TaskRunning_t *) 0x38

(gdb) ptype TaskRunning_t
type = long int

... I get 0x38, which is kind of suspicious to me; in fact, that is the offset of the field in the struct:

(gdb) ptype /o (TCB_t*)pxReadyTasksLists[1].pxIndex.pxNext.pvOwner
type = struct tskTaskControlBlock {
/*      0      |       4 */    volatile StackType_t *pxTopOfStack;
/*      4      |       4 */    UBaseType_t uxCoreAffinityMask;
/*      8      |      20 */    ListItem_t xStateListItem;
/*     28      |      20 */    ListItem_t xEventListItem;
/*     48      |       4 */    UBaseType_t uxPriority;
/*     52      |       4 */    StackType_t *pxStack;
/*     56      |       4 */    volatile TaskRunning_t xTaskRunState;
/*     60      |       4 */    BaseType_t xIsIdle;
/*     64      |      16 */    char pcTaskName[16];
/*     80      |       4 */    UBaseType_t uxCriticalNesting;
/*     84      |       4 */    UBaseType_t uxTCBNumber;
/*     88      |       4 */    UBaseType_t uxTaskNumber;
/*     92      |       4 */    UBaseType_t uxBasePriority;
/*     96      |       4 */    UBaseType_t uxMutexesHeld;
/*    100      |      20 */    void *pvThreadLocalStoragePointers[5];
/*    120      |      12 */    volatile uint32_t ulNotifiedValue[3];
/*    132      |       3 */    volatile uint8_t ucNotifyState[3];
/*    135      |       1 */    uint8_t ucDelayAborted;

                               /* total size (bytes):  136 */
                             } *

(gdb) p /x 56
$46 = 0x38

So, obviously a watchpoint on address 0x38 would not (and does not) trigger.

I can of course calculate 0x200015c4+0x38 and set a "long int" watch there; but then, if I re-run the program in gdb, as pxReadyTasksLists is dynamically allocated, its base address will change, and so will ultimately the address of the particular xTaskRunState that I want to watch.

So in this case, is it possible to craft an expression, which gdb can use to derive the absolute address of (here) pxReadyTasksLists[1].pxIndex.pxNext.pvOwner.xTaskRunState, such that I can set a watchpoint on that address?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文