美文网首页
#pragma pack(1) 引发的血案

#pragma pack(1) 引发的血案

作者: 乐十七 | 来源:发表于2019-08-05 20:59 被阅读0次

    问题

    static VCUStateEvt smlPoolSto[20];
    上述变量中的 smlPoolSto[0]的值被第三方修改,反复查找没有找到变量本身被修改的地方,也没有找到有指针直接指向这个变量。

    解决过程

    本着程序员不相信玄学的精神,打断点调试,找到问题的边界

           LightEvt *test;
           test = Q_NEW(LightEvt, wake_up_SIG);
           QF_PUBLISH(&test->super, "tt");
    

    上面的代码运行20遍就会出现。
    当然这个这个断点是不会手动按21次了,设置断点触发条件。


    捕获.PNG

    在触发的临界点在使能变量断点


    捕获1.PNG

    只监控变量的写入位置,手动检测到了这里跳出的时候,变量的值发生了变化

     if (p_obj != (OS_PEND_OBJ *)0) {
            p_tcb->DbgNamePtr =  p_obj->NamePtr;                /* Task pending on this object ... save name in TCB       */
            p_pend_list       = &p_obj->PendList;               /* Find name of HP task pending on this object ...        */
            p_pend_data       =  p_pend_list->HeadPtr;
            p_tcb1            =  p_pend_data->TCBPtr;
            p_obj->DbgNamePtr = p_tcb1->NamePtr;                /* ... Save in object                                     */
        } else {
            switch (p_tcb->PendOn) {
                case OS_TASK_PEND_ON_TASK_Q:
                     p_tcb->DbgNamePtr = (CPU_CHAR *)((void *)"Task Q");
                     break;
    
                case OS_TASK_PEND_ON_TASK_SEM:
                     p_tcb->DbgNamePtr = (CPU_CHAR *)((void *)"Task Sem");
                     break;
    
                default:
                     p_tcb->DbgNamePtr = (CPU_CHAR *)((void *)" ");
                     break;
            }
        }
    

    这段代码和 smlPoolSto[0] 没有任何联系,在进一步打断点,发现是下面的复制语句让变量值改变、
    ···C
    p_tcb->DbgNamePtr = (CPU_CHAR *)((void *)"Task Q");
    ···

    显然指针和我们开头描述的变量地址是一样的。
    通过查找map文件,最终发现了问题所在

    .bss                zero     0x2001c708     0xb4  App_BLEProtocol.o [1]
      .bss                zero     0x2001c7bc     0xa0  qp_bsp.o [1]
    

    pcb指向的结构体和 smlPoolSto在相邻的RAM区域,而且PCB的结构体实际指针大小应该是0xB8
    难道是编译器算错了,我试着在pcb的前后加变量偏移pcb的位置等操作,发现不论怎样地址是多少,pcb的大小都是0xb4.
    于是pcb旁边定义变量计算大小。
    uint32_t len = sizeof(pcb);
    输出结果竟让是179,竟然是奇数对齐,这时才发现这个问题可能是字节对其的原因。

    结果

    果不其然在其对应的头文件中发现了

    #pragma pack(1) 
    
    

    一个孤独的 #pragma pack(1)
    辛亏这个头文件没有大范围应用,不然真不知道会发生什么。
    最终解决方案很简单,

    #pragma pack(1) 
    
    
    #pragma pack() 
    
    

    给它找个对象就OK了。

    相关文章

      网友评论

          本文标题:#pragma pack(1) 引发的血案

          本文链接:https://www.haomeiwen.com/subject/htmvdctx.html