硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1611|回复: 4
收起左侧

搞了n多天,解决了一个动态内存使用的时候溢出的问题

[复制链接]

97

主题

537

回帖

843

积分

金牌会员

积分
843
发表于 2024-11-4 15:57:39 | 显示全部楼层 |阅读模式
本帖最后由 会飞的猪_2020 于 2024-11-4 15:59 编辑

之前有一份代码,在STM32F103上运行没问题。


最近不是在研究bl602吗,把它移植过去了。然后发现程序直接跑到core dump的地方(类似于Hardfault)

然后研究了一下bl602自带的backtrace,发现死之前最后调用了malloc。


一开始怀疑是sdk里的heap5内存管理有问题,换成了heap4还是卡死在同样的地方。
最后换成了tlsf之后,malloc不卡死了,但是后面strcmp的地方卡死。

发现是malloc之后有一个指针变成了null,导致strcmp的地方卡死。

因为bl602这颗芯片,我没研究过怎么接jlink调试,就只能打印。看了几天。
百思不得其解。
都快要放弃了。

今天试了一下把stm32f103的代码和bl602代码加了很多打印。最后发现同样的代码打印出来的有一个结构体的长度不一样。
打印出来的buffsize,stm32f103里面是5个字节,而bl602里面打印出来是8个字节

[C] 纯文本查看 复制代码
DATA_CENTER_TRACE("account[%s] cached %dx2 bytes\n", id, buffer_size);


这个buffsize的结构体来源于下面这里
[C] 纯文本查看 复制代码
typedef struct {
enum {
DP_BLE_START,
DP_BLE_STOP,
} cmd;
char *name;
} dp_ble_info_t;

DATA_PROC_DEF(ble, sizeof(dp_ble_info_t));


我猜测是由于enum的长度,f103里面是char,bl602里面是int导致的。
于是把MDK里面的设置改成了int。
改了之后f103的代码里面也不正常了

这真是激动人心的一幕,我可以在F103里面复现这个bug了。
然后就是接jlink调试,发现了前面malloc的size有问题没有乘2。

改成如下内容后终于正常了。
[C] 纯文本查看 复制代码
account_t *account_init(const char *id, data_center_t *center, unsigned int buffer_size, void *user_data)
{
    account_t *new = __malloc(sizeof(account_t));
    bool error = false;
    do {
        if (new == NULL) {
            DATA_CENTER_TRACE("malloc new account failed.\n");
            break;
        }

        error = true;
        memset(&new->priv, 0, sizeof(new->priv));
        new->id = id;
        new->center = center;
        new->user_data = user_data;
        INIT_LIST_HEAD(&new->fans_list);
        INIT_LIST_HEAD(&new->followers_list);
        if (buffer_size != 0) {
            unsigned char *buffer = __malloc(buffer_size * 2);
            if (buffer == NULL) {
                DATA_CENTER_TRACE("account[%s] buffer malloc failed\n", id);
                break;
            }
            memset(buffer, 0, buffer_size * 2);
            unsigned char *buf0 = buffer;
            unsigned char *buf1 = buffer + buffer_size;
            pingpong_buffer_init(&new->priv.buffer_manager, buf0, buf1);
            new->priv.buffer_size = buffer_size;
            DATA_CENTER_TRACE("account[%s] cached %dx2 bytes\n", id, buffer_size);
        }
        if (datacenter_add_account(center, new) == false) {
            DATA_CENTER_TRACE("account[%s] add to center[%s] failed\n", id, center->name);
            break;
        }
        error = false;
    } while (0);

    if (error == true) {
        __free(new);
        new = NULL;
    }
    return new;
}


这个代码我之前看了好几天居然都没看出来问题出来这里,应该很明显才对。但是就是没发现。
而且之前f103的地方居然也没测出来。可能用的是mircolib里面的malloc,有一点点溢出所以没发现?

总之,困扰我很多的bug总算是解决了。

评分

参与人数 2金币 +12 收起 理由
CheneyY + 10 赞一个!
摸鱼校尉 + 2 赞一个!

查看全部评分

共产主义一定胜利!
回复

使用道具 举报

18

主题

34

回帖

93

积分

初级会员

积分
93
发表于 2024-11-4 17:19:48 | 显示全部楼层
看着像x-track里的发布订阅模块
回复

使用道具 举报

3

主题

163

回帖

172

积分

初级会员

积分
172
发表于 2024-11-5 09:14:13 | 显示全部楼层
分配长度问题导致溢出有时确实很难发现
回复

使用道具 举报

0

主题

36

回帖

36

积分

新手上路

积分
36
发表于 2024-11-11 21:27:47 | 显示全部楼层
给软件同事做的demo板挂了一片32MB的SDRAM他还老觉得不够大
回复

使用道具 举报

684

主题

3514

回帖

5591

积分

论坛元老

积分
5591
发表于 2025-3-11 09:33:32 | 显示全部楼层
CheneyY 发表于 2024-11-11 21:27
给软件同事做的demo板挂了一片32MB的SDRAM他还老觉得不够大

32MB 不能够大那就挂 128MB 的 sdram , 2片 16bit 64MB k可以搞定  
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-6-11 04:18 , Processed in 0.247969 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表