gpt4 book ai didi

c - 修复 STM32 Nucleo-F334R8 上可能由于 malloc 导致的内存覆盖错误

转载 作者:行者123 更新时间:2023-11-30 16:18:31 24 4
gpt4 key购买 nike

我希望这是对我的问题的清晰解释,我已经在各种手册上跑了一个多星期了,现在正在尝试解决这个问题:

最近,在 STM32 Nucleo-F334R8 上进行反馈和测试后,我一直在为一个类(class)项目重新设计软件设计(我最初的代码充满了内存和时序错误)

目前我遇到两个主要错误:

(此问题已解决)

我一直在使用 sprintf,没有考虑分配内存之外的尾随空字符写入。

When processing USART Data using USART 1 in Asynchronous mode at 115200 Baudrate:

Program received signal SIGTRAP, Trace/breakpoint trap. 0x08002c08 in memset ()

Program received signal SIGTRAP, Trace/breakpoint trap. 0x08002c08 in memset ()

Program received signal SIGTRAP, Trace/breakpoint trap. 0x08002c08 in memset ()

Program received signal SIGTRAP, Trace/breakpoint trap. 0x08002c08 in memset ()

Program received signal SIGTRAP, Trace/breakpoint trap. 0x080056b4 in std.isra ()

存储在相关地址 0x08002c08 处的值通常非常大 大的通常是十进制的 134228385。另外如果我 强制单步解决问题,程序继续运行良好 并且再也没有遇到这个问题,我觉得很奇怪 可能的原因?

更新:所以 我已经追踪了一点 memset 问题,发现它发生了 在我setOutputBuffer期间方法:

String>,%5d,%8s,%3d,%3d,%3d,%4d,%4d,%4d,%10.6f,%11.6f,%7.1f,%3d,%3.1f\n",uptime,timeString,temperature,pressure,humidity,acc1,acc2,acc3,latitude,longitude,altitude,current,voltage);
} ``` Which leads me to believe the issue lies in finding a value that
is being used to set the Output buffer message.

I would like advice on how to further troubleshoot these two issues
and whether there is a chance that the memset error is related the
later bss error.

My String Tokenizing code(edited):

```c void tokenize(char* in){ const char *p = in; const char
delim[] = ","; char *token = NULL; uint8_t n = 0;

do{

size_t length = strcspn(p, delim); if(length > 0){ if(token ==
NULL){
token = malloc(sizeof(char)*length); // create memory space for the token
memset(token, 0, length); // ensure initialized memory is blank
sprintf(token, "%.*s",(int)length,p); // store the token from a substring of Input Buffer
p+=length; // move pointer to next ','
parseToken(token, n); // extract information from the token be it latitude, longitude etc
memset(token, 0, length); // clear the token
free(token); // free up the token's spot in memory
token = NULL; // set token pointer to null
n++; }

}


}while(*((++p)+1) != '*'); // The expected string ends with a
checksum character '*' after the last ',' } ``` I've re-examined the
function and made a lot of changes now I can successfully step through
the entire function without issue, the program then returns to my main
loop, and I let it run for a while but then I suddenly run back into
the same memset issue, even without receiving any bytes over USART
here is the code for my main loop and the subsequent function calls it
makes:

```c

while (1) {
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

if (byteFlag){ byteRecieved(); byteFlag = 0; }

if(msgFlag){ msgRecieved(); msgFlag = 0; }

if(secFlag){ setOutputBuffer(); HAL_UART_Transmit(&huart1,
(uint8_t *)bufferOut, 91, 1000); secFlag = 0; }

} ``` byteReceived: ```c if((char) byteIn == '$'){
clearInputBuffer(); } else if((char) byteIn == '\n'){

msgFlag = 1; }

else{ storeChar(); } ```

msgReceived: ```c if(isValid()){ if (checksum()) {
tokenize(bufferIn); clearInputBuffer(); } } ```

isValid: ```c char substr[5]; strncpy(substr, (bufferIn+1), 5);
if(!strcmp(substr, "GPGGA")){ return 1; }

return 0; ```

checksum: ```c int checksum(){ int calc_checksum = 0; int
in_checksum; int i = 0; char checkstr[2]; uint8_t hasCheckSum = 0;

for(int j = 0; j<91; j++){ if (bufferIn[j] == '*') { hasCheckSum
= 1; i = 1; } }

if (hasCheckSum) { while (bufferIn[i] != '*'){ calc_checksum ^=
bufferIn[i]; i++; } checkstr[0] = bufferIn[i+1]; checkstr[1]
= bufferIn[i+2]; } else {return 0;}



in_checksum = parseStr_HexToInt(checkstr);

if (calc_checksum == in_checksum){ return 1; } else { return 0;
} } ```

clearInputBuffer: ```c void clearInputBuffer(){ int i = 0;

for(i = 0; i < 100; i++){ bufferIn[i] = ' '; } bufferIn[0] = '$';
} ```

(此问题已解决)

本质上,我的问题的根源是滥用 sprintf并用空字符覆盖程序代码

I encountered a breakpoint trap while filling the bss segment of the board's memory

And after adding Seven GPIO Ports for a 4bit mode LCD(namely PA12, PA11, PB12, PB11, PB2, PB1, PB15) and two for a two channel ADC in DMA mode (PA1, PA0):

Program received signal SIGTRAP, Trace/breakpoint trap. LoopFillZerobss () at ..\startup/startup_stm32f334x8.s:103 103 cmp r2, r3 While trying to implement LCD and ADC functionality I receive the breakpoint trap error during the LoopFillZerobss function of startup which proved fatal, particularly by stopping my USART from reporting at all(however it can still receive bytes as interrupt and process tokens etc, just refuses to transmit), After reading up into the bss segment I attempted to solve the issue by initializing as many global variables as I could to non-zero values, this did not work, the problem is observed after adding the STM32CubeMx settings for ADC and the 7 GPIO pins used in the LCD, however none of these use unitialized variables to my knowledge unless the predefined code generated by CubeMX is going beyond the bounds of the bss segment of memory and that the size of the bss segment is too large now for the board's memory (which I suspect is unlikely but can't rule out).

本质上,这个项目的想法是通过 USART、ADC 和后来的 I2C 接收各种数据,并通过 USART 和 LCD 显示当前数据的各个方面,如果我丢弃 ADC 和 LCD 错误,我的 USART 代码将充当 memset( )错误是非致命的,但我怀疑将其留在那里只会导致我以后出现问题,但我也不确定在哪里修复我的标记化代码,假设它是我问题的根源。

最佳答案

本质上,我的问题的根源是滥用 sprintf 并用空字符覆盖程序代码

通过确保使用 snprintf 而不是 sprintf 以及明确定义大小的字符串,我不再遇到内存问题。

关于c - 修复 STM32 Nucleo-F334R8 上可能由于 malloc 导致的内存覆盖错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55876836/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com