Need help from GCC masters: Questions because of hanging program and memory related
trancefreak
Posts: 186
Hi,
I ran into a problem with a hanging (not working program). It's quite difficult to describe the issue without creating a long story, so I'll try to keep short but informative.
I've attached the zipped program converted to a simpleIDE project because I think most of the propGCC users use simpleIDE or have it installed at least.
The project is set up to be compiled in XMMC memory model. To test, a quickstart board is enough because the EEPROM is big enough to execute the program in XMMC mode.
Make sure to set up the XMM cache with 2kb because that is the setting I'm using.
IMPORTANT:
I'm using the propgcc default branch, not the one included with the simpleIDE binaries. Reason is because the default branch supports multiple cogs executing code in XMM model while the release branch just supports one cog (you cannot use cogstart - or it doesn't work - in the release branch).
What does the program:
Basically, it just starts up one cog with cogstart which executes code in a loop (write out "Scheduler COG running...\n" every 1/4 second).
The main cog also executes some code in a loop.
If you compile and execute the program, you will notice that it doesn't print out "Scheduler COG running...\n" which means the started cog hangs.
If you change line 49 of main.cpp from:
the program prints out the logline above.
The issue is, there should be way enough HUB RAM available to hold the test array with size of 5000 bytes.
If I use propeller-elf-objdump -h main.elf I get the following (with the 5000 bytes array in the code):
As far as I understand, the HUB RAM relevant parts are:
.hub (??) and .bss (stack size).
If I sum up these values I get:
33D8h => 13272d
So 13272 bytes used by the program itself. Additionally I have to add two XMM caches a 2048 bytes (2k cache size). So the overall usage is about 17368.
This size is not 100% correct, there could be additional RAM usage, but I'm sure not in the x kb area. So I think the program should run (with the 5kb testArr size), but it doesn't.
Only reducing the value to at least 4000 bytes solves the issue.
??? Why can't I use the complete available HUB RAM which should be free according to propeller-elf-objdump? There should be more than 10kb left.
Hope some of you C/C++ masters or propgcc developers could help me out with some thoughts or ideas.
Thanks,
Christian
I ran into a problem with a hanging (not working program). It's quite difficult to describe the issue without creating a long story, so I'll try to keep short but informative.
I've attached the zipped program converted to a simpleIDE project because I think most of the propGCC users use simpleIDE or have it installed at least.
The project is set up to be compiled in XMMC memory model. To test, a quickstart board is enough because the EEPROM is big enough to execute the program in XMMC mode.
Make sure to set up the XMM cache with 2kb because that is the setting I'm using.
IMPORTANT:
I'm using the propgcc default branch, not the one included with the simpleIDE binaries. Reason is because the default branch supports multiple cogs executing code in XMM model while the release branch just supports one cog (you cannot use cogstart - or it doesn't work - in the release branch).
What does the program:
Basically, it just starts up one cog with cogstart which executes code in a loop (write out "Scheduler COG running...\n" every 1/4 second).
The main cog also executes some code in a loop.
If you compile and execute the program, you will notice that it doesn't print out "Scheduler COG running...\n" which means the started cog hangs.
If you change line 49 of main.cpp from:
const uint32_t testIndex = 5000;to
const uint32_t testIndex = 1000;
the program prints out the logline above.
The issue is, there should be way enough HUB RAM available to hold the test array with size of 5000 bytes.
If I use propeller-elf-objdump -h main.elf I get the following (with the 5000 bytes array in the code):
main.elf: file format elf32-propeller Sections: Idx Name Size VMA LMA File off Algn 0 .xmmkernel 00000688 00000000 e0000000 00009350 2**2 CONTENTS, ALLOC, LOAD, CODE 1 .init 0000013c 30000000 30000000 0000196c 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 2 .text 000070d8 3000013c 3000013c 00001aa8 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 3 IODriver.cog 00000794 00000000 30007214 00008b80 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 4 .fini 0000003c 300079a8 300079a8 00009314 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 5 .hub 00001558 00000000 00000000 00000154 2**2 CONTENTS, ALLOC, LOAD, CODE 6 .math.kerext 000000dc 000006c0 00001558 000016ac 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 7 .start.kerext 000000cc 000006c0 00001634 00001788 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 8 .float.kerext 000000fc 000006c0 00001700 00001854 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 9 .ctors 0000000c 000017fc 000017fc 00001950 2**2 CONTENTS, ALLOC, LOAD, CODE 10 .dtors 00000010 00001808 00001808 0000195c 2**2 CONTENTS, ALLOC, LOAD, CODE 11 .bss 00001e80 00001818 00001818 0000196c 2**2 ALLOC 12 .hub_heap 00000004 00003698 00003698 0000196c 2**0 ALLOC 13 .debug_aranges 00000100 00000000 00000000 000099d8 2**0 CONTENTS, READONLY, DEBUGGING 14 .debug_info 000023fc 00000000 00000000 00009ad8 2**0 CONTENTS, READONLY, DEBUGGING 15 .debug_abbrev 0000084c 00000000 00000000 0000bed4 2**0 CONTENTS, READONLY, DEBUGGING 16 .debug_line 000006e8 00000000 00000000 0000c720 2**0 CONTENTS, READONLY, DEBUGGING 17 .debug_frame 00000164 00000000 00000000 0000ce08 2**2 CONTENTS, READONLY, DEBUGGING 18 .debug_str 00000014 00000000 00000000 0000cf6c 2**0 CONTENTS, READONLY, DEBUGGING 19 .debug_loc 00001bc4 00000000 00000000 0000cf80 2**0 CONTENTS, READONLY, DEBUGGING 20 .debug_ranges 00000280 00000000 00000000 0000eb44 2**0 CONTENTS, READONLY, DEBUGGING
As far as I understand, the HUB RAM relevant parts are:
.hub (??) and .bss (stack size).
If I sum up these values I get:
33D8h => 13272d
So 13272 bytes used by the program itself. Additionally I have to add two XMM caches a 2048 bytes (2k cache size). So the overall usage is about 17368.
This size is not 100% correct, there could be additional RAM usage, but I'm sure not in the x kb area. So I think the program should run (with the 5kb testArr size), but it doesn't.
Only reducing the value to at least 4000 bytes solves the issue.
??? Why can't I use the complete available HUB RAM which should be free according to propeller-elf-objdump? There should be more than 10kb left.
Hope some of you C/C++ masters or propgcc developers could help me out with some thoughts or ideas.
Thanks,
Christian
Comments
This is the main program:
If I comment out the starting of the driver everything works reliable and as expected.
For testing, I made the stack size for the COGC driver 1200 bytes, but this didn't solve the issue and the driver never needs this big stack size.
Interestingly, the driver works and runs while the main program hangs.
Does anyone have an idea what I could check to be sure that there are no stack issues or what could cause the hanging when the COGC driver is copied to a COG and started there.
I'm helpless, completely.
Christian
That's what I wanted to try out today evening when I'm at home, currently I'm at the office (Making a simple COGC which just blinks an LED).
First I completele want to strip down the main program to be as slim as possible then I will add the simple COGC driver.
Additionally I found out that it has nothing to do with the start of a second XMM cog. If I comment out the line the main loop still loops for 2 or 3 times then hangs or doesn't loop at all. So no difference of having that line in or out.
Only calling the startIODriver stuff influences the program. The main loop doesn't get hang up if I lower the index of the testArr[] to 4000 or lower.
So I assume there is something weird going on with regards to stack allocation or something else.
I'll try this out today evening and post an update.
Thanks for chiming in! :-)
Christian
Hmmm, odd. One thing to watch out for is that cogstart() itself needs quite a lot of stack (2KB) in the caller, because it makes a copy of the current COG's memory to use to start the new C cog. This isn't required for COGC code, just for running XMM/LMM in another COG.
Regards,
Eric
I played several hours now but I don't get what's going on. I've stripped the code quite down and have attached the project as simpleIDE project. Maybe you can do a quick test with a quickstart board.
If I comment out the line startIODriver(&ioDriverPar.ioDriverMailbox); the schedulerCog prints the message in a loop and everything works.
As soon as I uncomment the startIODriver line, the schedulerCog hangs. The COGC driver which is started with startIODriver(&ioDriverPar.ioDriverMailbox); is a completely stripped down COGC program which just blinks LED on pin 16 of the quickstart board.
If you could give the program a try maybe you are able to find out what's going wrong, I think I'm not able to find out why propgcc reacts so strange. There is enough HUB ram available so that cannot be the problem.
Looks like somehow there could be a stack conflict or something similar.
Regards,
Christian
I think I found out what causes the problem. It looks like cognew overwrites memory if executed in xmmc mode.
In CMM mode everything is OK.
I added two functions which fill the stackarea of the cog driver with the pattern 0xAABB and check a handed over array for this pattern.
If I execute the program in CMM mode the stack area does not get changed and still holds the filled pattern. This is OK because the code just blinks an LED, so no stack is used.
If I execute the program in XMMC mode, the stack area gets overwritten with 0. I don't know how much is overwritten. I checked 6000 Bytes but didn't go further.
I tested the code with the release branch of propgcc and there the problem does not exist. Please could you check if there is an issue in the default branch when using xmmc mode and cognew.
I attached the code if you want to test.
Regards,
Christian
I tried the propgcc Windows build from SwimDude0614 (found in this thread: http://forums.parallax.com/showthread.php/160431-propgcc-now-in-the-Parallax-github) because this build is up to date.
But the problem with overwriting Hub RAM still exists. It does not have anything to do with using cogstart to start a new XMM Kernel in a new COG. The RAM get's corrupted when cognew is used.
Some variables have a new value after cognew because of the memory corruption.
@David Betz or Eric:
Do you have an idea why cognew damages the RAM? My test project is attached one message above.
Would be great if one of you could find the issue :-)
Regards,
Christian
As a work around I suggest starting your COGC file as early as possible. and then telling it to wait for some flag to become non-zero before it continues (if it needs some initialization data from the host).
Thanks for the bug report!
Thanks for taking the time to have a look! I will try to use the workaround. As long as no code section gets overwritten this should be fine for me.
Regards,
Christian
Where is the _C_LOCK variable defined? If I try to set the _C_LOCK |= 0x100 I get the following compiler error:
Regards,
Christian
I had it that way when the error message came up:
If I move the code snippet into the function which uses cognew, it works:
I'm going to play a bit tomorrow and test if it fixes the problem.
Thank you very much, Eric!
Regards,
Christian
Stack no longer gets overwritten.