当我定义一个大型本地数组然后在程序中设置内存时,嵌入式系统中的守护程序崩溃。为什么数组在守护进程中跨越两个堆栈?
Daemon crash in embedded system when I define a large local array then memory set in program. Why the array spanned two stacks in daemon?
有人可以为这个问题提供建议吗?我试了两个星期也没找到解决方法。
问题是当我在守护进程中添加一个函数时,它会在嵌入式中崩溃linux:
#define BLOCK_SIZE 131072
static int newFuntion(unsigned int addr, unsigned int buflen, unsigned char *buf)
{
printf("BLOCK_SIZE:%d\n",BLOCK_SIZE);
UINT8 temp[BLOCK_SIZE]; /* sector buffer */
printf("temp:%x,sizeof UINT8:%d,temp_end:%x\n",temp,sizeof(UINT8),&temp[BLOCK_SIZE-1]);
memset(temp,0,sizeof(temp)); //processA daemon crash in there
return 0;
}
虽然我不能使用 gdb 来捕获崩溃信息,但我弄错了守护进程崩溃和变量声明之间的相关性。数组“temp”跨越守护进程中的两个堆栈。
这是此守护进程中的内存分配:
~ # cat /proc/pid/maps
00400000-0047c000 r-xp 00000000 1f:07 1083 /bin/processA
0048b000-00494000 rw-p 0007b000 1f:07 1083 /bin/processA
00494000-004ac000 rwxp 00000000 00:00 0
005b2000-005d3000 rwxp 00000000 00:00 0 [heap]
58800000-58a00000 rw-s 00000000 00:01 196614 /SYSV000004d2 (deleted)
775b0000-775c0000 rw-p 00000000 00:00 0
775c0000-775c1000 ---p 00000000 00:00 0
775c1000-776c0000 rwxp 00000000 00:00 0 *[stack:582]*
776c0000-776c1000 ---p 00000000 00:00 0
776c1000-776e0000 rwxp 00000000 00:00 0 *[stack:578]*
776e0000-777b6000 r-xp 00000000 1f:07 430 /lib/libm-2.20.so
777b6000-777c5000 ---p 000d6000 1f:07 430 /lib/libm-2.20.so
777c5000-777c6000 r--p 000d5000 1f:07 430 /lib/libm-2.20.so
777c6000-777c7000 rw-p 000d6000 1f:07 430 /lib/libm-2.20.so
.
.
.
77dec000-77e0d000 rw-p 00000000 00:00 0
77e0e000-77e2f000 r-xp 00000000 1f:07 473 /lib/ld-2.20.so
77e39000-77e3e000 rw-p 00000000 00:00 0
77e3e000-77e3f000 r--p 00020000 1f:07 473 /lib/ld-2.20.so
77e3f000-77e40000 rw-p 00021000 1f:07 473 /lib/ld-2.20.so
77e40000-77e41000 rw-p 00000000 00:00 0
7fa37000-7fa58000 rwxp 00000000 00:00 0 [stack]
7fff7000-7fff8000 r-xp 00000000 00:00 0 [vdso]
数组声明“temp”从[stack:582]开始到[stack:578]:
BLOCK_SIZE:131072
temp:776bcdb0,sizeof UINT8:1,temp_end:776dcdb0
我不确定为什么数组在 daemon.Is 中跨越两个堆栈会导致守护程序崩溃?
有什么解决方案可以让我仍然定义一个大的本地数组但避免守护进程崩溃吗?
--------最终解决方案------
非常感谢hesham_EE提出宝贵建议。
我使用 pthread_attr_setstacksize 来设置线程堆栈。
当我将线程堆栈大小从 128KB 更改为 1MB 时,守护进程在数组定义和内存设置时仍然存在。
从 0x7fa37000 开始的主堆栈未在执行打印的线程中使用。
有两个线程使用了它们自己的堆栈,这些线程标记为 [stack:582] 和 [stack:578]。此处的数字 582 和 578 是线程 ID。
来自您打印的堆栈地址转储:
temp:776bcdb0,sizeof UINT8:1,temp_end:776dcdb0
因为堆栈向上增长,从 [stack:578] 的最大值 776e0000 和缓冲区的结束地址 776dcdb0,这意味着打印来自此线程,即 [stack:578]。
你拥有的这个巨大的缓冲区,穿过第二个堆栈到第一个堆栈,经过中间区域:
776c0000-776c1000 ---p 00000000 00:00 0
您没有 read/write 访问权限。这就是崩溃的原因。
您要么需要检查代码并增加线程堆栈大小以足以容纳该缓冲区。或者,使用最大大小约为 776e0000-776c1000
的缓冲区,大约为 120 KB
以保留已使用堆栈的一些开销。不仅如此,它还会崩溃。
有人可以为这个问题提供建议吗?我试了两个星期也没找到解决方法。
问题是当我在守护进程中添加一个函数时,它会在嵌入式中崩溃linux:
#define BLOCK_SIZE 131072
static int newFuntion(unsigned int addr, unsigned int buflen, unsigned char *buf)
{
printf("BLOCK_SIZE:%d\n",BLOCK_SIZE);
UINT8 temp[BLOCK_SIZE]; /* sector buffer */
printf("temp:%x,sizeof UINT8:%d,temp_end:%x\n",temp,sizeof(UINT8),&temp[BLOCK_SIZE-1]);
memset(temp,0,sizeof(temp)); //processA daemon crash in there
return 0;
}
虽然我不能使用 gdb 来捕获崩溃信息,但我弄错了守护进程崩溃和变量声明之间的相关性。数组“temp”跨越守护进程中的两个堆栈。
这是此守护进程中的内存分配:
~ # cat /proc/pid/maps
00400000-0047c000 r-xp 00000000 1f:07 1083 /bin/processA
0048b000-00494000 rw-p 0007b000 1f:07 1083 /bin/processA
00494000-004ac000 rwxp 00000000 00:00 0
005b2000-005d3000 rwxp 00000000 00:00 0 [heap]
58800000-58a00000 rw-s 00000000 00:01 196614 /SYSV000004d2 (deleted)
775b0000-775c0000 rw-p 00000000 00:00 0
775c0000-775c1000 ---p 00000000 00:00 0
775c1000-776c0000 rwxp 00000000 00:00 0 *[stack:582]*
776c0000-776c1000 ---p 00000000 00:00 0
776c1000-776e0000 rwxp 00000000 00:00 0 *[stack:578]*
776e0000-777b6000 r-xp 00000000 1f:07 430 /lib/libm-2.20.so
777b6000-777c5000 ---p 000d6000 1f:07 430 /lib/libm-2.20.so
777c5000-777c6000 r--p 000d5000 1f:07 430 /lib/libm-2.20.so
777c6000-777c7000 rw-p 000d6000 1f:07 430 /lib/libm-2.20.so
.
.
.
77dec000-77e0d000 rw-p 00000000 00:00 0
77e0e000-77e2f000 r-xp 00000000 1f:07 473 /lib/ld-2.20.so
77e39000-77e3e000 rw-p 00000000 00:00 0
77e3e000-77e3f000 r--p 00020000 1f:07 473 /lib/ld-2.20.so
77e3f000-77e40000 rw-p 00021000 1f:07 473 /lib/ld-2.20.so
77e40000-77e41000 rw-p 00000000 00:00 0
7fa37000-7fa58000 rwxp 00000000 00:00 0 [stack]
7fff7000-7fff8000 r-xp 00000000 00:00 0 [vdso]
数组声明“temp”从[stack:582]开始到[stack:578]:
BLOCK_SIZE:131072
temp:776bcdb0,sizeof UINT8:1,temp_end:776dcdb0
我不确定为什么数组在 daemon.Is 中跨越两个堆栈会导致守护程序崩溃?
有什么解决方案可以让我仍然定义一个大的本地数组但避免守护进程崩溃吗?
--------最终解决方案------
非常感谢hesham_EE提出宝贵建议。 我使用 pthread_attr_setstacksize 来设置线程堆栈。 当我将线程堆栈大小从 128KB 更改为 1MB 时,守护进程在数组定义和内存设置时仍然存在。
从 0x7fa37000 开始的主堆栈未在执行打印的线程中使用。
有两个线程使用了它们自己的堆栈,这些线程标记为 [stack:582] 和 [stack:578]。此处的数字 582 和 578 是线程 ID。
来自您打印的堆栈地址转储:
temp:776bcdb0,sizeof UINT8:1,temp_end:776dcdb0
因为堆栈向上增长,从 [stack:578] 的最大值 776e0000 和缓冲区的结束地址 776dcdb0,这意味着打印来自此线程,即 [stack:578]。
你拥有的这个巨大的缓冲区,穿过第二个堆栈到第一个堆栈,经过中间区域:
776c0000-776c1000 ---p 00000000 00:00 0
您没有 read/write 访问权限。这就是崩溃的原因。
您要么需要检查代码并增加线程堆栈大小以足以容纳该缓冲区。或者,使用最大大小约为 776e0000-776c1000
的缓冲区,大约为 120 KB
以保留已使用堆栈的一些开销。不仅如此,它还会崩溃。