嵌入式技术论坛
直播中

贾永世

7年用户 1766经验值
私信 关注
[问答]

请教大神strcat会导致cpu异常吗 ?

各位大佬好, 打扰了,最近尝试 zynq7020 上使用 rt-thread, 发现了一个奇怪的问题, 在启用文件系统后, shell 线程触发了异常, 通过 map 文件定位到是在调用 strcat 时出现了问题。串口打印并未发现参数有误。尝试用一个自定义的 strcat 替换掉 strcat, 就可以正常运行了。请问哪位大佬知道可能是什么原因? 谢谢

报错:

initialize init_th:0 done
initialize finsh_system_init:0 done
running on cpu 0
data abort:Execption:
r00:0x00000005 r01:0x7f7f8000 r02:0x0011a9f1 r03:0x0000003e
r04:0x0011a9f0 r05:0xdeadbeef r06:0xdeadbeef r07:0xdeadbeef
r08:0xdeadbeef r09:0xdeadbeef r10:0xdeadbeef
fp :0x0011de04 ip :0x01010101
sp :0x0011ddf8 lr :0x0010efe0 pc :0x0010f008
cpsr:0x80000013
thread pri status sp stack size max used left tick error


tshell 20 running 0x00000040 0x00001000 13% 0x0000000a 000
test 20 suspend 0x000000a4 0x00000400 16% 0x00000004 000
ulog_async 30 ready 0x00000044 0x00000400 06% 0x00000014 000
tidle0 31 ready 0x00000040 0x00000200 12% 0x00000020 000
init 10 close 0x0000007c 0x00000800 15% 0x00000010 000
shutdown...
(0) assertion failed at function:rt_hw_cpu_shutdown, line number:38
尝试替换 strcat, 并打印 strcat 的位置:

diff --git a/rt-thread/components/finsh/shell.c b/rt-thread/components/finsh/shell.c
index 61f0b95..2b6f8f5 100644
--- a/rt-thread/components/finsh/shell.c
+++ b/rt-thread/components/finsh/shell.c
[url=home.php?mod=space&uid=1999721]@@[/url] -101,6 +101,18 @@ int finsh_set_prompt(const char * prompt)
#include <dfs_posix.h>
#endif /* RT_USING_DFS */
+char *t_strcat(char * dest, const char * src)
+{

char *tmp = dest;

while (*dest)

 dest++;

while ((*dest++ = *src++) != '\0')

 ;

return tmp;
+}

const char *finsh_get_prompt(void)
{
#define _MSH_PROMPT "msh "
@@ -131,7 +143,8 @@ const char *finsh_get_prompt(void)
getcwd(&finsh_prompt[rt_strlen(finsh_prompt)], RT_CONSOLEBUF_SIZE - rt_strlen(finsh_prompt));
#endif

  • strcat(finsh_prompt, ">");
  • rt_kprintf("str_cat: %p\n", strcat);
  • t_strcat(finsh_prompt, ">");
    return finsh_prompt;
    }
    输出:

initialize init_th:0 done
initialize finsh_system_init:0 done
running on cpu 0
str_cat: 0011556d
msh />
地址与map文件中一致

.text.strcat 0x0011556c 0x40 d:/env/tools/gnu_gcc/arm_gcc/mingw/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/lib/armv7-ar/thumb/fpu\libc.a(lib_a-strcat.o)
0x0011556c strcat

回帖(6)

贾伟刚

2023-2-17 11:51:25
感觉是非对齐的原因,反汇编再根据寄存器查一下。
举报

贾永世

2023-2-17 11:51:36
感谢大佬的回复,请问您指的是链接脚本的字节对齐设置吗? 个人对汇编了解不多,想请大佬帮忙再看看,万分感谢

  112d5c:    ebfffcee     bl    11211c
  112d60:    e30b0c14     movw    r0, #48148    ; 0xbc14
  112d64:    e3400011     movt    r0, #17
  112d68:    fa000ddb     blx    1164dc
  112d6c:    e1a03000     mov    r3, r0
  112d70:    e1a02003     mov    r2, r3
  112d74:    e30b3c14     movw    r3, #48148    ; 0xbc14
  112d78:    e3403011     movt    r3, #17
  112d7c:    e0822003     add    r2, r2, r3
  112d80:    e3093030     movw    r3, #36912    ; 0x9030
  112d84:    e3403011     movt    r3, #17
  112d88:    e1d330b0     ldrh    r3, [r3]
  112d8c:    e1c230b0     strh    r3, [r2]
  112d90:    e30b3c14     movw    r3, #48148    ; 0xbc14
  112d94:    e3403011     movt    r3, #17
  112d98:    e1a00003     mov    r0, r3
  112d9c:    e8bd8830     pop    {r4, r5, fp, pc}
00112da0 :
running on cpu 0
data abort:Execption:
r00:0x00000005 r01:0x7f7f8000 r02:0x0011bc19 r03:0x0000003e
r04:0x0011bc18 r05:0xdeadbeef r06:0xdeadbeef r07:0xdeadbeef
r08:0xdeadbeef r09:0xdeadbeef r10:0xdeadbeef
fp :0x0011eee4 ip :0x01010101
sp :0x0011eed8 lr :0x00112d6c pc :0x00112d94
cpsr:0x80000013
thread           pri  status      sp     stack size max used left tick  error
---------------- ---  ------- ---------- ----------  ------  ---------- ---
tshell            20  running 0x00000040 0x00001000    13%   0x0000000a 000
test              20  suspend 0x000000a4 0x00000400    16%   0x00000005 000
ulog_async        30  ready   0x00000044 0x00000400    06%   0x00000014 000
tidle0            31  ready   0x00000040 0x00000200    12%   0x00000020 000
init              10  close   0x0000007c 0x00000800    15%   0x00000007 000
shutdown...
(0) assertion failed at function:rt_hw_cpu_shutdown, line number:38
举报

贾虎世

2023-2-17 11:51:47
反汇编一般是编译生成的asm文件,也可以用编译器命令arm-none-eabi-objdump -D elf文件生成反汇编文件,一般是看你PC寄存器的值,说明CPU在此处触发了异常,然后再看LR的值,看看是谁是父函数,然后进行进一步分析,你截图里面是有PC与LR的值的,可以分析下。
或者从strcat本身分析,是不是可能是buffer溢出、地址非对齐等方面进行排查。
举报

贾永世

2023-2-17 11:52:02
今天尝试写了几个测试函数,发现问题似乎与 strcat 的第二个参数直接给了字符串字面量有关。怀疑与链接 有关。不知各位大佬如何看,谢谢 !
测试代码:

#include
int test_strcat(int argc, char **argv)
{
    char tmp[20] = "0n";
    static const char s2[] = "12n";
    strcat(tmp, s2);
    rt_kprintf(tmp);
    return 0;
}
MSH_CMD_EXPORT(test_strcat, test strcat);
int test_strcat_2(int argc, char **argv)
{
    char tmp[20] = "0n";
    strcat(tmp, "12");
    rt_kprintf(tmp);
    return 0;
}
MSH_CMD_EXPORT(test_strcat_2, test strcat);
测试结果: test_strcat 正常,test_strcat_2 崩了

msh />test_strcat
0
12
msh />test_strcat_2
test_strcat_2
msh />test_strcat_2data abort:Execption:
r00:0x0012d9c5 r01:0x0012db05 r02:0x80000000 r03:0x00000074
r04:0x0012d93c r05:0x0012d93c r06:0xdeadbeef r07:0xdeadbeef
r08:0xdeadbeef r09:0xdeadbeef r10:0xdeadbeef
fp :0x0012ebc4 ip :0x0012d9ba
sp :0x0012ebb0 lr :0x00121e14 pc :0x00104a7a
cpsr:0xa0000033
thread           pri  status      sp     stack size max used left tick  error
---------------- ---  ------- ---------- ----------  ------  ---------- ---
tshell            20  running 0x000000cc 0x00001000    13%   0x00000001 000
test              20  suspend 0x000000a0 0x00000400    15%   0x00000005 000
ulog_async        30  suspend 0x000000ac 0x00000400    25%   0x00000009 000
tidle0            31  ready   0x00000070 0x00000200    28%   0x00000014 000
shutdown...
(0) assertion failed at function:rt_hw_cpu_shutdown, line number:38
反汇编结果
pc 似乎运行到了 memcpy

  104a62:    d008          beq.n    104a76
  104a64:    07d2          lsls    r2, r2, #31
  104a66:    bf1c          itt    ne
  104a68:    f811 3b01     ldrbne.w    r3, [r1], #1
  104a6c:    f800 3b01     strbne.w    r3, [r0], #1
  104a70:    d301          bcc.n    104a76
  104a72:    880b          ldrh    r3, [r1, #0]
  104a74:    8003          strh    r3, [r0, #0]
  104a76:    4660          mov    r0, ip
  104a78:    4770          bx    lr
  104a7a:    bf00          nop
  104a7c:    2a08          cmp    r2, #8
  104a7e:    d313          bcc.n    104aa8
  104a80:    078b          lsls    r3, r1, #30
  104a82:    d0b1          beq.n    1049e8
  104a84:    f010 0303     ands.w    r3, r0, #3
  104a88:    d0ae          beq.n    1049e8
两个测试函数的反汇编结果:

00104cb4 :
  104cb4:    e92d4800     push    {fp, lr}
  104cb8:    e28db004     add    fp, sp, #4
  104cbc:    e24dd020     sub    sp, sp, #32
  104cc0:    e50b0020     str    r0, [fp, #-32]    ; 0xffffffe0
  104cc4:    e50b1024     str    r1, [fp, #-36]    ; 0xffffffdc
  104cc8:    e3a03ea3     mov    r3, #2608    ; 0xa30
  104ccc:    e50b3018     str    r3, [fp, #-24]    ; 0xffffffe8
  104cd0:    e24b3014     sub    r3, fp, #20
  104cd4:    e3a02000     mov    r2, #0
  104cd8:    e5832000     str    r2, [r3]
  104cdc:    e5832004     str    r2, [r3, #4]
  104ce0:    e5832008     str    r2, [r3, #8]
  104ce4:    e583200c     str    r2, [r3, #12]
  104ce8:    e24b3018     sub    r3, fp, #24
  104cec:    e3081278     movw    r1, #33400    ; 0x8278
  104cf0:    e3401012     movt    r1, #18
  104cf4:    e1a00003     mov    r0, r3
  104cf8:    fa008061     blx    124e84
  104cfc:    e24b3018     sub    r3, fp, #24
  104d00:    e1a00003     mov    r0, r3
  104d04:    eb000a4c     bl    10763c
  104d08:    e3a03000     mov    r3, #0
  104d0c:    e1a00003     mov    r0, r3
  104d10:    e24bd004     sub    sp, fp, #4
  104d14:    e8bd8800     pop    {fp, pc}
00104d18 :
  104d18:    e92d4800     push    {fp, lr}
  104d1c:    e28db004     add    fp, sp, #4
  104d20:    e24dd020     sub    sp, sp, #32
  104d24:    e50b0020     str    r0, [fp, #-32]    ; 0xffffffe0
  104d28:    e50b1024     str    r1, [fp, #-36]    ; 0xffffffdc
  104d2c:    e3a03ea3     mov    r3, #2608    ; 0xa30
  104d30:    e50b3018     str    r3, [fp, #-24]    ; 0xffffffe8
  104d34:    e24b3014     sub    r3, fp, #20
  104d38:    e3a02000     mov    r2, #0
  104d3c:    e5832000     str    r2, [r3]
  104d40:    e5832004     str    r2, [r3, #4]
  104d44:    e5832008     str    r2, [r3, #8]
  104d48:    e583200c     str    r2, [r3, #12]
  104d4c:    e24b3018     sub    r3, fp, #24
  104d50:    e1a00003     mov    r0, r3
  104d54:    fa008089     blx    124f80
  104d58:    e1a03000     mov    r3, r0
  104d5c:    e1a02003     mov    r2, r3
  104d60:    e24b3018     sub    r3, fp, #24
  104d64:    e0832002     add    r2, r3, r2
  104d68:    e3053b78     movw    r3, #23416    ; 0x5b78
  104d6c:    e3403012     movt    r3, #18
  104d70:    e1d310b0     ldrh    r1, [r3]
  104d74:    e5d33002     ldrb    r3, [r3, #2]
  104d78:    e1c210b0     strh    r1, [r2]
  104d7c:    e5c23002     strb    r3, [r2, #2]
  104d80:    e24b3018     sub    r3, fp, #24
  104d84:    e1a00003     mov    r0, r3
  104d88:    eb000a2b     bl    10763c
  104d8c:    e3a03000     mov    r3, #0
  104d90:    e1a00003     mov    r0, r3
  104d94:    e24bd004     sub    sp, fp, #4
  104d98:    e8bd8800     pop    {fp, pc}
举报

贾虎世

2023-2-17 11:52:10
建议明确一下第2个参数字符串的地址,可以放到全局变量位置,方便在map文件中确认地址,
测试时,同时在此地址上加1,以改变地址对比验证。
可以根据map中字符串地址,以及dump出来的寄存器交叉确认。
你是不是cache没开?没开时是不能非对齐访问的。
举报

贾永世

2023-2-17 11:52:18
多谢,确实是 cache 没开的原因。。。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分