Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2013-03

arm-embedded apps crash in exception handler initialization because heapmanager is not initialized

11 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Michael Ring

I am not sure if I have hit work in progress code here....

my arm-embedded app crashes during initialization, the reason is that now exceptions are part of the rtl but there is no properly initialized heapmanager:

Procedure InitExceptions;
{
   Must install uncaught exception handler (ExceptProc)
   and install exceptions for system exceptions or signals.
   (e.g: SIGSEGV -> ESegFault or so.)
}
begin
   ExceptionClass := Exception;
   ;
   // Create objects that may have problems when there is no memory.
   //CRASH BOOM BANG in the following line
   OutOfMemory:=EOutOfMemory.Create(SOutOfMemory);

Creating the object fails because the MemoryManager is not properly initialized yet.

When I put heapmgr unit before sysutils im my program (this should not be necesary, right???) I can debug a little deeper in object initialization but still the root cause exists that there has never been a call to RegisterHeapBlock so objects cannot be initiated because there's no memory block defined that heapmgr can draw memory from.

I can hack the RegisterHeapBlock call into the initialization code of the unit heapmgr but this is more a hack than a proper solution --> seems a bad idea to me.

How can this be properly solved?

Michael

Reply by email

Florian Klämpfl
to Michael Ring
Michael Ring wrote 25 lines
I am not sure if I have hit work in progress code here.... my arm-embedded app crashes during initialization, the reason is that now exceptions are part of the rtl but there is no properly initialized heapmanager: Procedure InitExceptions; { Must install uncaught exception handler (ExceptProc) and install exceptions for system exceptions or signals. (e.g: SIGSEGV -> ESegFault or so.) } begin ExceptionClass := Exception; ; // Create objects that may have problems when there is no memory. //CRASH BOOM BANG in the following line OutOfMemory:=EOutOfMemory.Create(SOutOfMemory); Creating the object fails because the MemoryManager is not properly initialized yet. When I put heapmgr unit before sysutils im my program (this should not be necesary, right???)

Yes, this is a requirement.

Show quoted text 10 lines
I can debug a little deeper in object initialization but still the root cause exists that there has never been a call to RegisterHeapBlock so objects cannot be initiated because there's no memory block defined that heapmgr can draw memory from. I can hack the RegisterHeapBlock call into the initialization code of the unit heapmgr but this is more a hack than a proper solution --> seems a bad idea to me. How can this be properly solved?

I think allocating a small block (128 bytes for arm?) during the start up of heapmgr should be fine?

var
  InitialBlock: array[0..255] of byte;
...
RegisterHeapBlock(@InitialBlock,sizeof(InitialBlock));

If one includes heapmgr he wants to use the heap after all.

Reply by email

Michael Ring
to Florian Klämpfl

Simple solutions are the best ;-) Thanks for opening my eyes to this easy approach.

I have created a patch for heapmgr.pp, could I ask you to commit it to svn?

For a little more flexible solution I would like to ask you one more questions, it may seem dumb to you but I have never been that deep into a compiler before so I am learning a lot atm.

I can see that the compiler param -Ch can be used to define the heapsize, I can also see in the assembler code of my main program that when I set -Ch I also get a section:

-Ch2048 results in this:

.section .data.n___heapsize
.balign 4
.globl __heapsize
__heapsize:
.long 2048

but I do not seem to be able to access __heapsize in my code, how could I use this information to make the heapsize configurable?

and, it is (as far as I understand) a must to include heapmgr in the code because if not the program will always die on startup because of the object created in Exception class, where would be the right place to do this?

Yes, I can put heapmgr as the first unit included in my main program, but wouldn't it be better to put it in some global initialization loop, like the VariantManager, which always gets initialized without me triggering this in any way.

Michael

Index: rtl/embedded/heapmgr.pp
=================================================================== --- rtl/embedded/heapmgr.pp (revision 23681)
+++ rtl/embedded/heapmgr.pp (working copy)
@@ -34,6 +34,7 @@

      var
        Blocks: PHeapBlock = nil;
+      InitialBlock: array[0..255] of byte;
      procedure InternalFreeMem(Addr: Pointer; Size: ptruint); forward;

@@ -242,6 +243,7 @@

  initialization
    SetMemoryManager(MyMemoryManager);
+  RegisterHeapBlock(@InitialBlock,sizeof(InitialBlock));
  finalization
    //FinalizeHeap;
  end.
Florian Klämpfl wrote 53 lines
Am 02.03.2013 23:17, schrieb Michael Ring: > I am not sure if I have hit work in progress code here.... > > my arm-embedded app crashes during initialization, the reason is that > now exceptions are part of the rtl but there is no properly initialized > heapmanager: > > Procedure InitExceptions; > { > Must install uncaught exception handler (ExceptProc) > and install exceptions for system exceptions or signals. > (e.g: SIGSEGV -> ESegFault or so.) > } > begin > ExceptionClass := Exception; > ; > // Create objects that may have problems when there is no memory. > //CRASH BOOM BANG in the following line > OutOfMemory:=EOutOfMemory.Create(SOutOfMemory); > > > Creating the object fails because the MemoryManager is not properly > initialized yet. > > When I put heapmgr unit before sysutils im my program (this should not > be necesary, right???) Yes, this is a requirement. > I can debug a little deeper in object > initialization but still the root cause exists that there has never been > a call to RegisterHeapBlock so objects cannot be initiated because > there's no memory block defined that heapmgr can draw memory from. > > I can hack the RegisterHeapBlock call into the initialization code of > the unit heapmgr but this is more a hack than a proper solution --> > seems a bad idea to me. > > How can this be properly solved? I think allocating a small block (128 bytes for arm?) during the start up of heapmgr should be fine? var InitialBlock: array[0..255] of byte; ... RegisterHeapBlock(@InitialBlock,sizeof(InitialBlock)); If one includes heapmgr he wants to use the heap after all. _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Sven Barth
to Michael Ring
Michael Ring wrote 18 lines
For a little more flexible solution I would like to ask you one more questions, it may seem dumb to you but I have never been that deep into a compiler before so I am learning a lot atm. I can see that the compiler param -Ch can be used to define the heapsize, I can also see in the assembler code of my main program that when I set -Ch I also get a section: -Ch2048 results in this: .section .data.n___heapsize .balign 4 .globl __heapsize __heapsize: .long 2048 but I do not seem to be able to access __heapsize in my code, how could I use this information to make the heapsize configurable?

Did you try

=== code begin ===

var
   heapsize: LongWord; external name '__heapsize';

=== code end ===

?

Regards,
Sven

Reply by email

Michael Ring
to Sven Barth

This helped me to understand another puzzle piece.

Please correct me if I am wrong:

sram - Memory is divided in several areas on arm-embedded:

_data starts at start of sram ($20000000 in my case) _edata is end of _data segment ($200009b4)
_bss_start defines start of static vars ($200009b4) _bss_end defines end of static vars ($20000e90)

all memory from here on is used for stack, stack grows from end of avaliable sram ($20010000) downto _bss_end

so what I could do is allocate memory for heap starting at address _bss_end with the size of _heapsize. or, perhaps even better:

I start using memory at address _stack_top - _stklen - _heapsize

Correct ??

Michael

Sven Barth wrote 37 lines
On 03.03.2013 11:04, Michael Ring wrote: > For a little more flexible solution I would like to ask you one more > questions, it may seem dumb to you but I have never been that deep into > a compiler before so I am learning a lot atm. > > I can see that the compiler param -Ch can be used to define the > heapsize, I can also see in the assembler code of my main program that > when I set -Ch I also get a section: > > -Ch2048 results in this: > > .section .data.n___heapsize > .balign 4 > .globl __heapsize > __heapsize: > .long 2048 > > but I do not seem to be able to access __heapsize in my code, how could > I use this information to make the heapsize configurable? Did you try === code begin === var heapsize: LongWord; external name '__heapsize'; === code end === ? Regards, Sven _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Michael Ring
to Michael Ring

That would of course be even better, the compiler could calculate if vars+stack+heap fit in the given memory configuration and issue at minimum a warning or even better a compile error.

But this is definitely something that is out of my league, Florin, could you implement this?

Michael

Florian Klämpfl wrote 45 lines
Am 03.03.2013 21:27, schrieb Michael Ring: > I have created a new patch, this time it uses the values of the two > commandline parameters -Ch and -Cs to set the size of Stack and Heap. I > am not sure if those params were for this use case but in my opinion it > makes sense. > > Florian, could I ask you to apply the patch to trunk if what I am doing > is is ok? It looks reasonable, but after some thinking I came to the conclusion that maybe the heap should be already allocated during linking, i.e. so heapmgr does not need to calculate an _heap_start. > > > Index: rtl/embedded/heapmgr.pp > =================================================================== > --- rtl/embedded/heapmgr.pp (revision 23681) > +++ rtl/embedded/heapmgr.pp (working copy) > @@ -34,7 +34,13 @@ > > var > Blocks: PHeapBlock = nil; > + _heap_start : pointer; > + _heapsize: longWord; external name '__heapsize'; > + _stklen: longword; external name '__stklen'; > + _bss_end: record end; external name '_bss_end'; > + _stack_top: record end; external name '_stack_top'; > > + > procedure InternalFreeMem(Addr: Pointer; Size: ptruint); forward; > > function FindSize(p: pointer): ptruint; > @@ -242,6 +248,11 @@ > > initialization > SetMemoryManager(MyMemoryManager); > + _heap_start := @_stack_top - _heapsize - _stklen; > + // Only initialize Heap when there is enough space available > + if _heap_start >= @_bss_end then > + RegisterHeapBlock(_heap_start,_heapsize); > + > finalization > //FinalizeHeap; > end.
Michael Ring wrote 66 lines
This helped me to understand another puzzle piece. Please correct me if I am wrong: sram - Memory is divided in several areas on arm-embedded: _data starts at start of sram ($20000000 in my case) _edata is end of _data segment ($200009b4) _bss_start defines start of static vars ($200009b4) _bss_end defines end of static vars ($20000e90) all memory from here on is used for stack, stack grows from end of avaliable sram ($20010000) downto _bss_end so what I could do is allocate memory for heap starting at address _bss_end with the size of _heapsize. or, perhaps even better: I start using memory at address _stack_top - _stklen - _heapsize Correct ?? Michael Am 03.03.13 11:14, schrieb Sven Barth: > On 03.03.2013 11:04, Michael Ring wrote: >> For a little more flexible solution I would like to ask you one more >> questions, it may seem dumb to you but I have never been that deep into >> a compiler before so I am learning a lot atm. >> >> I can see that the compiler param -Ch can be used to define the >> heapsize, I can also see in the assembler code of my main program that >> when I set -Ch I also get a section: >> >> -Ch2048 results in this: >> >> .section .data.n___heapsize >> .balign 4 >> .globl __heapsize >> __heapsize: >> .long 2048 >> >> but I do not seem to be able to access __heapsize in my code, how could >> I use this information to make the heapsize configurable? > > Did you try > > === code begin === > > var > heapsize: LongWord; external name '__heapsize'; > > === code end === > > ? > > Regards, > Sven > _______________________________________________ > fpc-devel maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-devel > _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Florian Klämpfl
to Michael Ring
Michael Ring wrote 6 lines
That would of course be even better, the compiler could calculate if vars+stack+heap fit in the given memory configuration and issue at minimum a warning or even better a compile error. But this is definitely something that is out of my league, Florin, could you implement this?

I'll look into this the next days.

Reply by email

Michael Ring
to Florian Klämpfl

Florian, did you find some spare time to work on this?

Michael

Florian Klämpfl wrote 14 lines
Am 03.03.2013 22:09, schrieb Michael Ring: > That would of course be even better, the compiler could calculate if > vars+stack+heap fit in the given memory configuration and issue at > minimum a warning or even better a compile error. > > But this is definitely something that is out of my league, Florin, could > you implement this? I'll look into this the next days. _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Florian Klämpfl
to Michael Ring
Florian, did you find some spare time to work on this?

Not yet but still on my todo list.

Show quoted text 23 lines
Michael Am 03.03.13 22:59, schrieb Florian Klämpfl: > Am 03.03.2013 22:09, schrieb Michael Ring: >> That would of course be even better, the compiler could calculate if >> vars+stack+heap fit in the given memory configuration and issue at >> minimum a warning or even better a compile error. >> >> But this is definitely something that is out of my league, Florin, could >> you implement this? > > I'll look into this the next days. > > _______________________________________________ > fpc-devel maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-devel > _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email