我正在为ARM Cortex M0上运行的GSM调制解调器编写驱动程序。系统上唯一的UART用于与调制解调器通信,因此我最好能够记录与调制解调器的UART对话,即在内存中构建一个字符串并使用GDB进行观察。
以下是我的UART日志记录功能。
// Max number of characters user in the UART log, when in use.
#define GSM_MAX_UART_LOG_CHARS (2048)
static char m_gsm_uart_log[GSM_MAX_UART_LOG_CHARS] = "";
static uint16_t m_gsm_uart_log_index = 0;
// Write a character to the in-memory log of all UART messages.
static void gsm_uart_log_char(const char value)
{
m_gsm_uart_log_index++;
if (m_gsm_uart_log_index > GSM_MAX_UART_LOG_CHARS)
{
// Clear and restart log.
memset(&m_gsm_uart_log, 0, GSM_MAX_UART_LOG_CHARS); // <-- Breakpoint here
m_gsm_uart_log_index = 0;
}
m_gsm_uart_log[m_gsm_uart_log_index] = value;
}
// Write a string to the in-memory log of all UART messages.
static void gsm_uart_log_string(const char *value)
{
uint16_t i = 0;
char ch = value[i++];
while (ch != '\0')
{
gsm_uart_log_char(ch);
ch = value[i++];
}
}
如果我在上面显示的行上设置断点,第一次到达时,m_gsm_uart_log_index已经超过2048.我已经看到2154和2048到2200之间的一堆其他值左右
这怎么可能?没有其他代码可以在任何地方触及m_gsm_uart_log_index。
答案 0 :(得分:3)
发生了缓冲区溢出,可能会在m_gsm_uart_log_index
上进行操作。
检查缓冲区的结尾应该是:
if (m_gsm_uart_log_index >= GSM_MAX_UART_LOG_CHARS) {
...
}
目前,m_gsm_uart_log_index
可以达到2048,所以写m_gsm_uart_log_index[2048]
可能会在m_gsm_uart_log_index
存储的位置。
答案 1 :(得分:0)
您在m_gsm_uart_log_index == GSM_MAX_UART_LOG_CHARS
时写入缓冲区,这意味着您将缓冲区超过1个字符。这会写入m_gsm_uart_log_index
的第一个字节并破坏它。
变化:
if (m_gsm_uart_log_index > GSM_MAX_UART_LOG_CHARS)
为:
if (m_gsm_uart_log_index >= GSM_MAX_UART_LOG_CHARS)