Forum > macOS / Mac OS X

IDE Leaks and Traces "Resolve" fails on Mac OSX (

(1/3) > >>

Having spent many hours reading forum posts on this topic, it appears that the Lazrus IDE "Leaks and Traces" Resolve when applied to an executable on OSX still fails to work.   Leaks are shown but without any line number or source file references.  As dbannon discovered years ago through much time and effort, it appears some complation/link step or post-link step on OSX strips the symbolic data from the executable.

As a test I ran dwarfdump (Molly suggestion long ago to dbannon) on a simple Lazarus example executable, with no code except for one deliberate unfreed memory allocation, no symbolic information appears in dwarfdump's output.    The same results on two different OSX machines one containing the latest Mac OSX and the other an earlier OSX version, but both machines with the latest FPC and Lazarus version releases from 2023-12-18 - Version 3.0 FPC Version: 3.2.2 Revision: x86_64-darwin-cocoa.

For history, see:,39255.msg270590.html#msg270590
(a bug report had been filed but was closed)

As suggested by dbannon, it appears leak testing can only work on a NON-Mac OS.  But in the hopes someone has come upon a solution, I thought I would raise the issue once again FWIW.

There are several possible causes...

1) Depending on the IDE version, "Leaks and Traces" use either the code from the RTL or from FpDebug to resolve addresses.
If it is the former, then I don't know which fpc version has support for which Mac CPU/OS-version....

2) If it is FpDebug, then the debug info must be on the exe.  (If FpDebug + lldb can debug the exe, then the info should be there)
  I am not sure, if "resolve" needs to select the bundle, or the exe inside the bundle.

3) "Resolve" can only work if the exe is compiled with a "fixed address" (not sure what the term is). That is, it is always loaded to the same address in memory.
If the OS loads it to different addresses on each run, then it can not be resolved => because the trace has absolute addresses, and any part of the exe could have been at any of the addresses.

I don't know how Mac executables behave in regards to the last point.

I do recall that the leaks and traces for Mac had been under investigation "recently" (last year?). I don't recall the outcome.

Thanks Martin for your input and expertise as always. Comments interspersed:

You may recall a couple years ago, you and I had a long thread in the course of getting debugging working consistently on the Mac.  The FpDebug & LLDB debug setup were still stablilizing at the time -- but in the end and even now, I was and am still able to debug my Lazarus projects on OSX, so symbolic info clearly is available to the debugger..

As to "resolve," that requires a filename found in the file dialog (not a directory), so resolve only proceeds if given a filename (NOT an .app bundle).  And "Resolve" does not see a Mac .app "bundle" as a directory, nor a "file", so it is impossible to navigate into .app/Contents/MacOS/executable_file using the dialog.  But one can get around that by setting up a link to the executable_file at the same level as the .app bundle.  That executable though seems to be stripped of symbol info, so nothing is resolved symbol-wise.

Dwarfdump of a simple project executable complied with debug info and line numbers shows:

     project1:   file format Mach-O 64-bit x86-64
    .debug_info contents:  (nothing listed!)

So maybe the "fixed address" is the problem or Lazarus debugging gets its symbolic information from somewhere other than the executable stored in the app bundle (object files?).

It may just be that Lazarus IDE Memory Leak tracing will never be possible due to OS compatiblity issues.  My understanding is that in the investigation (dbannon, Molly, and others), no resolution was ever achieved, so dbannon is only able to do leak tracing in NON Mac OS implementations.  My fate as well, I suspect :-)

You might be able to test the address stuff. Set a breakpoint, and open the assemble window. Now run the app a few times in the debugger. Does the address change or not?

If the address changes, then it would require
- the base address to be logged and added to the trace in such a way that it can be found
- leaks and traces to be extended
=> not anytime soon on my todo.

It's a while that I looked at how debug info on Mac is loaded...

IIRC (distant memory), the debug info is loaded from lots of files (all the .o files or something like this). You may try "external debug info", then you get a 2nd folder next to the app, with a different extension, and (afaik) all the files in it.

You can always check in fpdebug where it opens the file, some fpimagereader*
Probably (just glancing over the files, got other project open and in the works): TDbgMachoDataSource.ReadFile;
Then but writeln in there to indicate filenames, and if they where able to be opened.

If it finds, and opens all files ... -> good.

Btw, if you try to get traces with heaptrc... IIRC there was some mention that fpc trunk may be able to print them with already resolved names... But that is all hearsay.

So, the addresses shown in the assembler window did NOT vary :-)

Checking the Compiler Options/Debugging/Use external debug symbols file produced (as noted before) a single dSYM file: in my case "project1.dSYM"

I did a dwarfdump on project1.SYM and redirected the huge amount of output to a file and then reviewed it in TextEdit.  I looked specifically for the method Button1Click and here is what that small section looks like:

0x0003790d:     DW_TAG_member
                  DW_AT_name   ("BUTTON1")
                  DW_AT_data_member_location   (DW_OP_plus_uconst 0x7c0)
                  DW_AT_type   (0x00037a8c "TBUTTON")

0x0003791a:     DW_TAG_subprogram
                  DW_AT_name   ("BUTTON1CLICK")
                  DW_AT_prototyped   (0x01)
                  DW_AT_calling_convention   (DW_CC_GNU_borland_fastcall_i386)
                  DW_AT_external   (0x01)
                  DW_AT_low_pc   (0x0000000100056fe0)
                  DW_AT_high_pc   (0x000000010005700a)

0x00037932:       DW_TAG_formal_parameter
                    DW_AT_name   ("this")
                    DW_AT_location   (DW_OP_breg6 RBP-16)
                    DW_AT_artificial   (0x01)
                    DW_AT_type   (0x000378ef "TFORM1")

So this all looks good in that apparently Lazarus did indeed write the symbolic output to the standard Apple OSX dSYM file sized at 19.1 MB. Project1's executable is 15.5 MB under this scenario.  (The location of the dSYM file seems to vary in my couple test cases -- sometimes it exists at the same level as the .app bundle, and otherwise it is actually in the .app bundle.)

Building again but without checkbox set for "Use external debug symbols" of course produces no DSYM file and interestingly a Project1 executable sized at 15.8 MB (vs 15.5 before).  Obviously the increase of .3 MB is not enough to have the executable actually contain the additional 19.1 MB of data within it. 

A little google search on Apple dSYM found this:
[ "A dSYM file is a "debug symbols file". It is generated when the "Strip Debug Symbols" setting is enabled in the build settings of your project.
When this setting is enabled, symbol names of your objects are removed from the resulting compiled binary (one of the many countermeasures to try and prevent would be hackers/crackers from reverse engineering your code, amongst other optimisations for binary size, etc.).

To sum up, it appears that "Resolving" using the executable fails since it seems stripped of symbol information.  But it is accessible to Lazarus since it is discoverable when writing the debug info externally! 

So as dbannon discovered long ago, it appears process is stripping the executable of the symbolic info.

I have tinkered with trying to use the Leaks and Traces "resolve button dialog" to access the dSYM file but so far the Lazarus GUI says the file does not exist.


[0] Message Index

[#] Next page

Go to full version