Hi Larry,
On 27/09/12 06:25, Larry Baker wrote:
On 09/26/2012 12:49 PM, Larry Baker wrote:
I have been chasing what I suspect are stack overflows in NTP. I spotted
mention of that there was a gcc option, -fstack-check-symbol=__stack_start, for
run-time stack checking on uClinux. I tried that, but it caused an internal
compiler error. My development environment is the Sourcery (now Mentor
Graphics) CodeBench Lite for ColdFire uClinux SDK. I modified their GCC source
to add support for -fstack-limit-symbol. Unfortunately, using the
__stack_start symbol to detect stack overflow does not seem to be working out.
For my test uClinux executable, stack-overflow.c:
#include <stdio.h>
void overflow( int i ) {
/* Allocate automatic array j[256] so stack limit checking works. */
int j[256];
/* Stack limit checking tests only whether the stack is large enough for */
/* the initial stack allocation: saved registers and automatic variables. */
/* Stack limit checking does not test for stack overflow in the body of a */
/* function. That is what happens when j[] is not present. When j[] is */
/* too large, the program will abnormally terminate on its own (illegal */
/* instruction trap?). j[256] works. */
i++;
printf( "i = %i\n", i );
overflow( i );
}
int main() {
overflow( 0 );
return 0;
}
the stack is allocated 4K (0x1000).
How are you setting the app stack size?
I take the default. I build two images: one with and one without
-fstack-limit-symbol=__stack_start:
# toolchains/freescale-coldfire-2011.09-patched/bin/m68k-uclinux-gcc -mcpu=5208
-fomit-frame-pointer -fno-common -fno-builtin -fno-dwarf2-cfi-asm -msep-data -o
no-check-stack-overflow stack-overflow.c
# toolchains/freescale-coldfire-2011.09-patched/bin/m68k-uclinux-gcc -mcpu=5208
-fomit-frame-pointer -fno-common -fno-builtin -fno-dwarf2-cfi-asm -msep-data
-fstack-limit-symbol=__stack_start -o check-stack-overflow stack-overflow.c
The executable says the stack size is 0x1000:
# toolchains/freescale-coldfire-2011.09-patched/bin/m68k-uclinux-flthdr -p
check-stack-overflow
check-stack-overflow
Magic: bFLT
Rev: 4
Build Date: Wed Sep 26 11:54:28 2012
Entry: 0x44
Data Start: 0x3c60
Data End: 0x44e4
BSS End: 0x6590
Stack Size: 0x1000
Reloc Start: 0x44e4
Reloc Count: 0x29
Flags: 0x2 ( Has-PIC-GOT )
When I hacked the .s file to print out the stack pointer and __stack start, it
shows that there is more than 4K between the value in the stack pointer and
__stack_start:
%sp = 0x405f3ee4
__stack_start = 0x405f08b4
That is not what I was expecting.
This is a little deceptive, and not completely accurate in general.
If you look at what binfmt_flat.c does when loading a flat format file
you will see that that point is labeled the start of the "brk" region.
When allocating the memory for the process (text, data, stack) we may
get a larger region than requested(1). We use the extra space if we get
it, and that will push the stack further away from the end of the data
region if we do. This is probably what you are seeing.
If this were the case, __stack_start would still be an accurate value for
detecting stack overrun. I see signs of stack overrun before the stack check
trips. When I force a trap (trap #7), I get no messages from the O/S on the
console, and the shell prompt reappears. (Should I see something?
I don't recall off-hand what you will see by forcing a trap 7.
But it is easy to check, try a strait trap 7 call in a test program.
Is there a kernel build option I should enable?) When I run my stack checking
test program with j[32], the hardware watchdog timer trips. I'll have to hack
the .s file some more to print out __stack_start and %sp when this happens.
Perhaps the stack check for j[32] (128 bytes) passes, but the printf library
routine is using more stack and is actually causing the system failure.
There is no special kernel options to support this currently.
I am not familiar with gcc's stack checking options and code.
Does it just check the value of sp at function entry and exit?
Or is it more elaborate than that?
Be mindful that on older ColdFire Cores, that only had a single A7,
then the CPU will be pushing the exception frame onto the user
space stack (so an extra 8 bytes).
There should be nothing but stack between __stack_start and the end of the
region, where the initial %sp points, correct? If not, I can't use
__stack_start as a sentinel.
Normally there isn't. In the past it has been possible to use the brk
system call and use the "spare" space. But in practice I don't think
anybody ever used this support much.
Regards
Greg
------------------------------------------------------------------------
Greg Ungerer -- Principal Engineer EMAIL: g...@snapgear.com
SnapGear Group, McAfee PHONE: +61 7 3435 2888
8 Gardner Close FAX: +61 7 3217 5323
Milton, QLD, 4064, Australia WEB: http://www.SnapGear.com
_______________________________________________
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev