Sign in Join

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

Mailing lists / fpc-devel / 2015-06

Status of debug line info

6 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

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

Sergio Flores

Some time ago I already talked a bit about it, but let's discuss this again.

I have developed a very complex game with FPC, that includes a crash log reporting (by mail).
Recently a update did introduce some weird bug, and I keep receiving reports by mail.
Sadly, except the ones that come from Windows users, the others have a stack dump that just has addresses.

Please correct if I'm wrong, but it seems that line info is not working in those 3 major platforms:

- Android
- iOS
- OSX

From what I gathered last time, both iOS and OSX need fpc support for DWARF

debug info, and thats why they not work (again, I not 100% sure if I'm correct).

Now, about Android, which actually is more important for me now, I did some investigation and experiments.

I asked FPC to generate a map file for Android (via -Xm) and noticed that all addresses there are way different than the addresses in the stack dumps. This makes sense, because when the .SO file that contains pascal code is loaded in Android, it gets reallocated, so the addresses in the .map file are just relative addresses.

Question 1:
Is it possible that this is a simple problem caused by FPC not calculating the base address correctly and thus not finding the routine/line info? If yes, anyone can point to the right place so I can try to 2: Related to question 1, but more broad. Can anyone give me a fast resume how line info actually works in FPC. What files in FPC source should I look at in case I want to add support for example for line info in Android/OSX/iOS?

Question 3:
I also found this C library that converts crashes that happen in native code to proper Java exceptions with a neat stack dump of the native code. I though I might try using this for now, but it requires some compile flags that I dont know if I can pass to FPC.

  LOCAL_CFLAGS := -funwind-tables -Wl,--no-merge-exidx-entries

Is it possible to pass the flags?
If yes, maybe I could even try to study the source of this and try to add Android line info support for FPC.

Reply by email

Michael Van Canneyt
to Sergio Flores
Sergio Flores wrote 14 lines
Some time ago I already talked a bit about it, but let's discuss this again. I have developed a very complex game with FPC, that includes a crash log reporting (by mail). Recently a update did introduce some weird bug, and I keep receiving reports by mail. Sadly, except the ones that come from Windows users, the others have a stack dump that just has addresses. Please correct if I'm wrong, but it seems that line info is not working in those 3 major platforms: - Android - iOS - OSX From what I gathered last time, both iOS and OSX need fpc support for DWARF debug info, and thats why they not work (again, I not 100% sure if I'm correct).

FPC does support DWARF info.

There is a bug/shortcoming in the lineinfo unit for DWARF that may cause the problems you are seeing, but we are aware of this. (please check the bugtracker, it's a recent bug).

Show quoted text 14 lines
Now, about Android, which actually is more important for me now, I did some investigation and experiments. I asked FPC to generate a map file for Android (via -Xm) and noticed that all addresses there are way different than the addresses in the stack dumps. This makes sense, because when the .SO file that contains pascal code is loaded in Android, it gets reallocated, so the addresses in the .map file are just relative addresses. Question 1: Is it possible that this is a simple problem caused by FPC not calculating the base address correctly and thus not finding the routine/line info? If yes, anyone can point to the right place so I can try to look at it. Question 2: Related to question 1, but more broad. Can anyone give me a fast resume how line info actually works in FPC. What files in FPC source should I look at in case I want to add support for example for line info in Android/OSX/iOS?

This support exists.

Show quoted text 8 lines
Question 3: I also found this C library that converts crashes that happen in native code to proper Java exceptions with a neat stack dump of the native code. I though I might try using this for now,  but it requires some compile flags that I dont know if I can pass to FPC. LOCAL_CFLAGS := -funwind-tables -Wl,--no-merge-exidx-entries Is it possible to pass the flags?

No, they look like C compiler flags, not linker flags.

Michael.

Reply by email

Jonas Maebe
to Sergio Flores: Some time ago I already talked a bit about it, but let's discuss this again. I have…

Sergio Flores wrote on Mon, 22 Jun 2015:

Show quoted text 13 lines
Sadly, except the ones that come from Windows users, the others have a stack dump that just has addresses. Please correct if I'm wrong, but it seems that line info is not working in those 3 major platforms: - Android - iOS - OSX From what I gathered last time, both iOS and OSX need fpc support for DWARF debug info, and thats why they not work (again, I not 100% sure if I'm correct).

FPC's lineinfo unit for DWARF does not support reading the DWARF info on OS X/iOS. The reason is that unlike on Linux, on OS X/iOS the DWARF info is not put in the linked binary. Instead,
a) if you don't use -Xg, the the linked binary contains references to the object files. The lineinfo unit would need support to read these references, and then relocate the addresses in the stack trace to offsets within the object files (or vice versa).
b) if you do use -Xg, the dsymutil utility is used to copy the DWARF information from all object files into a single object file, which is stored in a .dSYM bundle in the same directory as the binary. This bundle/file can be found based on a UUID that is stored inside the linked binary (it doesn't have to stay in the same directory as the binary), and the addresses in that debug object will also have to be remapped onto the linked binary. The DWARF lineinfo unit doesn't contain support for this either.

All that said, you're simply using the wrong approach. You obviously do not want to ship all object files of your program to your customers, and I doubt Apple would be very happy (or even allow) you to ship a .dSYM debug bundle with your application on iOS. As far as I know, all crash reporters in general use work by collecting only addresses and base load address information (for the binary and all shared libraries) when the crash occurs, send this information to the developer, and the developer then uses the debug information to symbolicate everything on his machine.

That is also what you should do with FPC. The lineinfo units are just some minor convenience units that may help with local debugging. Making a program that may already be crashing and burning start looking for debug info, read it in, parse it, interpret it based on load addresses etc is inherently a bad approach, since that code will be running in a potentially corrupted environment (which is why the lineinfo units contain all of that code to abort in case an error has been detected, in order to keep them from endlessly tripping over themselves in case e.g. the heap got corrupted). When something goes wrong, you want to terminate as soon as possible and do as little extra work as possible (and definitely not something IO-related or something that may need extra memory).

Show quoted text 10 lines
I asked FPC to generate a map file for Android (via -Xm) and noticed that all addresses there are way different than the addresses in the stack dumps. This makes sense, because when the .SO file that contains pascal code is loaded in Android, it gets reallocated, so the addresses in the .map file are just relative addresses. Question 1: Is it possible that this is a simple problem caused by FPC not calculating the base address correctly and thus not finding the routine/line info? If yes, anyone can point to the right place so I can try to can only point to rtl/inc/lnfodwrf.pas. I don't know whether it

contains support for dynamic libraries.

Question 2: Related to question 1, but more broad. Can anyone give me a fast resume how line info actually works in FPC. What files in FPC source should I look at in case I want to add support for example for line info in Android/OSX/iOS?

Again: if your interest is a crash reporter, relying on the lineinfo units is simply the wrong approach (especially for iOS, but in general there's no reason to ship debug info --even only partial one-- to your customers).

Show quoted text 9 lines
Question 3: I also found this C library that converts crashes that happen in native code to proper Java exceptions with a neat stack dump of the native code. I though I might try using this for now, but it requires some compile flags that I dont know if I can pass to FPC. LOCAL_CFLAGS := -funwind-tables -Wl,--no-merge-exidx-entries Is it possible to pass the flags?

FPC does not support generating unwind tables at this time, except on Windows.

Jonas

Reply by email

Sergio Flores

I was trying to get lineinfo to work in the crash reporter since I've seen some comercial games doing the same (reporting a stack dump with lines/filename.cpp).
The problem with gathering just addresses is that they change with every build (and I ship daily builds).
Anyway I could try that, but I still need the base address, and I have no
clue how to obtain that in FPC.
Is there any easy way to find it?
Probably reading it from /proc/pid/maps in unix platforms could work... Another question, I thought about a idea for platform independent way to support line info.
Could the compiler generate a internal table/array that mapped all functions addresses to strings?
Let's say a additional-Gsomething flag is added for this, then a special
internal function would be generated, and called at run-time, before units
initialization. The function would just build a huge table of adress associations, like this.

- Ignored:
    procedure init_debuginfo();
    begin
      register_debug_address(@unitX_funcA, 'unitX', 'funcA');
      register_debug_address(@unitX_funcB, 'unitX', 'funcB');
      register_debug_address(@unitY_funcA, 'unitY', 'funcA');
    // all other functions/methods/procedures in the whole program ...
    end;

Probably not as simple of that, it might need more info (range of the functions address, not just starting point).
Then calling BackTraceStrFunc() would look up the address using the table
built before.

Even though this would just be useful to print routine names and not lines,
would this work?

Reply by email

Sergio Flores

Thanks Michael and Jonas for the answers.

I was trying to get lineinfo to work in the crash reporter since I've seen some comercial games doing the same (reporting a stack dump with lines/filename.cpp).

The problem with gathering just addresses is that they change with every build (and I ship daily builds).
Anyway I could try that, but I still need the base address, and I have no clue how to obtain that in FPC.
Is there any easy way to find it?
Probably reading it from /proc/pid/maps in unix platforms could work...

Another question, I thought about a idea for platform independent way to support line info.

Could the compiler generate a internal table/array that mapped all functions addresses to strings?

Let's say a additional-Gsomething flag is added for this, then a special internal function would be generated, and called at run-time, before units initialization. The function would just build a huge table of adress associations, like this.

procedure init_debuginfo();
begin
  register_debug_address(@unitX_funcA, 'unitX', 'funcA');
  register_debug_address(@unitX_funcB, 'unitX', 'funcB');
  register_debug_address(@unitY_funcA, 'unitY', 'funcA');
// all other functions/methods/procedures in the whole program ...
end;

Probably not as simple of that, it might need more info (range of the functions address, not just starting point).
Then calling BackTraceStrFunc() would look up the address using the table built before.

Even though this would just be useful to print routine names and not lines, would this work?

Reply by email

Jonas Maebe
to Sergio Flores

Sergio Flores wrote on Tue, 23 Jun 2015:

The problem with gathering just addresses is that they change with every build (and I ship daily builds).

That's what -Xg is for (and on iOS/OS X, also the embedded UUIDs), so you can keep the debug info along with the build that you shipped out.

Anyway I could try that, but I still need the base address, and I have no clue how to obtain that in FPC.

That's unrelated to the compiler or programming language, and specific to the OS. Your best bet is to look into the code of existing crash reporter frameworks.

Could the compiler generate a internal table/array that mapped all functions addresses to strings?

Yes, but since it would just duplicate part of the debug information in another format, I don't think it would be worth it.

Jonas

Reply by email