Sign in Join

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

Mailing lists / fpc-devel / 2014-08

FPC ARM7 problems

7 messages · 4 people ·

Reply by email Subscribe to this list Your subscription

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

Sergio Flores

I have a somehow big pascal game (more than 200k lines of code) that I'm developing with FPC.
Right now I found a strange crashing bug that only happened in iOS, running in the device (in the iOS simulator does not crash). Desktop platforms don't have any problems running the same code (Windows, Linux etc). In Android I'm not sure, because while it does not crash in my devices, in many players devices the game just crashes in that exact spot.

So I have some questions.

1 - This bug only happens with -O2 on, but with optimizations off the game does not crash. I always thought that using optimizations was safe. Can there be a compiler bug in the ARM7 codegen?
Lately I've been shipping the game without optimizations, but of course, this means less performance.
I thought that the bug could be caused by differences in memory allocations on those different OSes, but I'm not sure.
Anyone has a clue how to discover the difference between O2 and O- that could cause such problems?

2 - I cannot get line info to work on iOS, all exceptions reported show just addresses. I am using -gl so it should work, or it works only in some targets?
If not possible to get automatic line info, is there any way to transform those adresses into line numbers with some tool?
I think in Android the same thing happens, line info not generated when using -gl, but I'm not 100% sure (I can check later).

3 - Finally, since I'm still using FPC 2.6.2 I decided to upgrade to 2.7.1 and try to recompile the game, to see if the crash in the game was gone. But, with FPC 2.7.2 I simply can't compile the game, it gives errors in the assembler stage.

Basically I get lots of errors similar to those
armv7/MinimonBattle.s:44518:co-processor offset out of range

I checked the asm of the lines in question, it is mostly just a bunch of labels, eg:
Lj21874:
.byte 0,0,32,64
Lj21879:
.long L_U_$MINIMONDB_$$_MOVEINFO$non_lazy_ptr-La1335-8 Lj21884:
.byte 0,0,32,64

Compilation switches are the following:
-Sgix -Cfvfpv2 -gw2 -gl -O2 -CRriot

The error happens with Cfvfpv3 instead, and with optimizations on or off. I'm using latest XCode, by the way.

Anyone has a clue why this happens? Could it be a compiler or assembler bug? I'm guessing it, but the problem might be because some of the game files are too big (10k lines of code or more), and as such too many labels are generated in just one file. Could this cause problems? Even if was because of the file size, FPC 2.6.2 generated asm code that worked fine, so I dont understand.
If anyone wants to take a look at the generated asm, tell me and I'll send you the file.

Regards,
Sergio

Reply by email

Jonas Maebe
to Sergio Flores
Sergio Flores wrote 5 lines
1 - This bug only happens with -O2 on, but with optimizations off the game does not crash. I always thought that using optimizations was safe. Can there be a compiler bug in the ARM7 codegen?

Not so much in the code generator as in the optimisers. There are a lot of ARM peephole optimisations and regularly new bugs are found (and fixed) in them. I know of another big project where they also cannot compile for ARM with -O2 or they get crashes (and they don't have time to isolate the causes).

What you could try with FPC 2.7.1 is -O2 -Oonopeephole, that may give you more performance than -O1 and should also be safe. On 2.6.x, that won't help because the logic to ensure that -Oonopeephole actually disabled peephole optimisations was not implemented there.

I thought that the bug could be caused by differences in memory allocations on those different OSes, but I'm not sure.

The simulator is an x86 program. It does not run ARM code but plain i386 code.

Anyone has a clue how to discover the difference between O2 and O- that could cause such problems?

You can start by compiling individual units with different optimisations to figure out in which unit a bug is triggered. After that, you can put {$optimization off} in that unit after the first, second, third, ... procedure to see in which procedure the problem occurs.

Show quoted text 5 lines
2 - I cannot get line info to work on iOS, all exceptions reported show just addresses. I am using -gl so it should work, or it works only in some targets?

-gl does has not yet been implemented for DWARF on OS X/iOS. Stabs is not supported on iOS, so you indeed cannot get the lineinfo unit to work on iOS.

If not possible to get automatic line info, is there any way to transform those adresses into line numbers with some tool?

If the program crashes, the Apple crash reporter should be able to read the line info from the debug information. If you just have a bunch of addresses from a backtrace generated by the system unit, you can use the tool mentioned in the first answer to http://stackoverflow.com/questions/1460892/symbolicating-iphone-app-crash-reports

I think in Android the same thing happens, line info not generated when using -gl, but I'm not 100% sure (I can check later).

That would be unlikely, because it's basically Linux and on linux -gl works with DWARF.

Show quoted text 30 lines
3 - Finally, since I'm still using FPC 2.6.2 I decided to upgrade to 2.7.1 and try to recompile the game, to see if the crash in the game was gone. But, with FPC 2.7.2 I simply can't compile the game, it gives errors in the assembler stage. Basically I get lots of errors similar to those armv7/MinimonBattle.s:44518:co-processor offset out of range I checked the asm of the lines in question, it is mostly just a bunch of labels, eg: Lj21874: .byte 0,0,32,64 Lj21879: .long L_U_$MINIMONDB_$$_MOVEINFO$non_lazy_ptr-La1335-8 Lj21884: .byte 0,0,32,64 Compilation switches are the following: -Sgix -Cfvfpv2 -gw2 -gl -O2 -CRriot The error happens with Cfvfpv3 instead, and with optimizations on or off. I'm using latest XCode, by the way. Anyone has a clue why this happens? Could it be a compiler or assembler bug?

That points to a code generator error in the compiler (or rather a layouting error, place the constant too far away from the instruction that tries to load it).

Jonas

Reply by email

Sven Barth
to Sergio Flores: I have a somehow big pascal game (more than 200k lines of code) that I'm developing with…
"Sergio Flores" wrote
I have a somehow big pascal game (more than 200k lines of code) that I'm

developing with FPC.

Right now I found a strange crashing bug that only happened in iOS,

running in the device (in the iOS simulator does not crash). Desktop platforms don't have any problems running the same code (Windows, Linux etc).

In Android I'm not sure, because while it does not crash in my devices,

in many players devices the game just crashes in that exact spot.

So I have some questions. 1 - This bug only happens with -O2 on, but with optimizations off the

game does not crash. I always thought that using optimizations was safe. Can there be a compiler bug in the ARM7 codegen?

Lately I've been shipping the game without optimizations, but of course,

this means less performance.

I thought that the bug could be caused by differences in memory

allocations on those different OSes, but I'm not sure.

Anyone has a clue how to discover the difference between O2 and O- that

could cause such problems?

It can indeed be that there is a bug in the optimizer. Does it also happen with -O1? Does it also happen when you switch on single optimizations (-OoSpecificOptimization)? AFAIR a list of available optimizations can be queried by "fpc -Parm -i" (among other information).

Regards,
Sven

Reply by email

Jonas Maebe
to Jonas Maebe: Not so much in the code generator as in the optimisers. There are a lot of ARM peephole…
Jonas Maebe wrote 5 lines
You can start by compiling individual units with different optimisations to figure out in which unit a bug is triggered. After that, you can put {$optimization off} in that unit after the first, second, third, ... procedure to see in which procedure the problem occurs.

You can of course speed this up by using a binary search: enable optimisations for half of the units -> if fail, disable for half of those, otherwise enable for half of the other half etc. Similarly, within a single unit you can put the {$optimization off} halfway and then move it up/down by half every time something fails or doesn't. Note that {$optimization off} won't work if you put it in the middle of a procedure.

Jonas

Reply by email

Nico Erfurth
to Sergio Flores: I have a somehow big pascal game (more than 200k lines of code) that I'm developing with…

Hi Sergio,

Show quoted text 8 lines
3 - Finally, since I'm still using FPC 2.6.2 I decided to upgrade to 2.7.1 and try to recompile the game, to see if the crash in the game was gone. But, with FPC 2.7.2 I simply can't compile the game, it gives errors in the assembler stage. Basically I get lots of errors similar to those armv7/MinimonBattle.s:44518:co-processor offset out of range

But this assembler-errors looks very strange to me, could you try to isolate that into a small function so we can try to reproduce it?

Also, we were fixing some peephole-optimizer bugs in trunk just last week. So it would be great if we could get trunk to compile your code.

Nico

Reply by email

Sergio Flores

I see guys, lots of useful info!
I did not know that optimizations where switchable per unit, that is quite interesting and I can probably use it to better isolate the problem. I will also try disabling peephole optimisations then, it can probably work as a temporary fix to let me use all other optimizations.

Any clue how I could work around for that assembler problem in 2.7.1. Could breaking the source file into smaller units help?

And Jonas, yes, I could apply a binary logic, I'll see. But I think I know the unit where the problematic code happens as I did lots of debugging those last days and found a function that did not crash but did corrupt the memory when optimizations were on. Maybe just disabling optimizations for this specific unit or the other units that this one uses could be enough.

Basically what seems to happen is the following, you have two method calls to the same object.
Eg:

Begin
X.A();
X.B();
End;

Calling A does not crash the program, nor does it read or write any invalid memory. However after method A exits normally and the code goes to call B(), X strangely is no longer valid, as if A() somehow changed the value of X, and thus calling X.B() crashes.

I don't have the knowledge of how the internals work, so I don't know how a function can actually modify the value of "self". I guess some stack corruption is happening somehow?

This is what I've discovered, not sure if it helps, maybe I could provide the asm code of that specific method with and without optimizations?

PS: I have no clue in the ammount of work necessary to add dwarf/lineinfo support to those platforms, but in case it is something doable without too much work, and can benefit both OSX and iOS, I'm willing to donate some money to have have such support implemented.

Reply by email

Jonas Maebe
to Sergio Flores
Sergio Flores wrote 8 lines
I see guys, lots of useful info! I did not know that optimizations where switchable per unit, that is quite interesting and I can probably use it to better isolate the problem. I will also try disabling peephole optimisations then, it can probably work as a temporary fix to let me use all other optimizations. Any clue how I could work around for that assembler problem in 2.7.1. Could breaking the source file into smaller units help?

No, but breaking down a procedure into smaller ones might help. However, it needs to be fixed. The only way it can be fixed is by providing us with a source code fragment that we can compile to reproduce the problem.

I don't have the knowledge of how the internals work, so I don't know how a function can actually modify the value of "self". I guess some stack corruption is happening somehow?

A broken optimisation can do anything with any possible random side effect.

This is what I've discovered, not sure if it helps, maybe I could provide the asm code of that specific method with and without optimizations?

That may help, but it might also be any of the called procedures that causes the problem.

PS: I have no clue in the ammount of work necessary to add dwarf/lineinfo support to those platforms, but in case it is something doable without too much work, and can benefit both OSX and iOS, I'm willing to donate some money to have have such support implemented.

At least I don't have time for it right now.

Jonas

Reply by email