How to Fix Instruments Showing No Symbols or Unreadable Stack Traces

When Instruments displays addresses instead of function names, your traces are unreadable. Here is how to fix missing symbols and get clean, source-mapped stack traces.

The Symptom

You record a trace, open the Call Tree, and instead of function names you see raw hexadecimal addresses or vague library names. The data is there, but it is unreadable.

This is a symbolication problem. Symbolication is the process of mapping memory addresses back to human-readable function names and source lines.

Without symbols, a trace is nearly useless. You cannot tell which of your functions is hot if everything shows as an address.

The good news is that this is almost always a configuration or build issue, not a bug in your code. A handful of checks usually restores readable traces.

Cause 1: Profiling Without Debug Symbols

A common cause is a build that lacks debug information. If the symbols are not present, Instruments has nothing to map addresses against.

The cleanest fix is to profile through Xcode using Product, then Profile, rather than attaching to an unrelated build. That path produces a build with matching symbol information and hands it to Instruments correctly.

Check your build settings for the debug information format. A standard configuration that produces dSYM files helps ensure symbols are available for profiling.

If you changed these settings to speed up builds, that may explain the missing names. Restore a configuration that generates full debug information for your profiling builds.

Cause 2: Mismatched or Missing dSYM

Even when symbols exist, they must match the exact binary you profiled. A dSYM from a different build will not symbolicate the current trace.

This often bites teams who profile a binary built elsewhere, such as a CI artifact, without the matching dSYM. The unique build identifier must line up.

The reliable fix is to rebuild and profile the same binary locally so the symbols are guaranteed to match. When that is not possible, ensure you have the precise dSYM that corresponds to that exact build.

Keeping dSYMs archived alongside each build you might profile is a good long-term habit. It saves you from unreadable traces later.

Cause 3: Only System Libraries Are Symbolicated

Sometimes your own code is readable but a function still resolves only to a system framework address, or vice versa. This can make a trace look half-broken.

Instruments offers a re-symbolicate option that lets you point it at the symbol information it needs. Use it to load symbols for the binaries that are not resolving.

For your own app, the fix is usually ensuring the matching dSYM is present, as described above. For system frameworks, full symbol detail is not always available, which is normal.

Focus on getting your own code readable first. That is what you can act on, and it is the part that matters most for fixing performance issues.

Cause 4: Stale or Corrupted Trace Data

Occasionally the trace document itself is in a confused state, perhaps after switching devices or builds mid-session. Re-symbolication may not take effect cleanly.

The simplest remedy is to start fresh. Close the trace, rebuild your app, and record a brand-new session rather than fighting an old one.

A fresh Product then Profile run sidesteps most stale-state issues. It helps you get a clean binary, clean symbols, and a clean document.

If problems persist, restarting Instruments and even the device clears transient glitches. A clean slate is often faster than debugging the tool's state.

Step-by-Step Recovery

First, in Xcode select your app and a real device, then choose Product, then Profile. This is among the most reliable ways to get matching symbols.

Second, confirm your debug information format produces dSYM output in the configuration you are profiling. Adjust it if someone disabled it for speed.

Third, in Instruments, use the option to hide system libraries and invert the call tree so your own symbolicated code rises to the top. This often reveals that your code was readable all along.

Fourth, if names are still missing, use the re-symbolicate option and point Instruments at the correct dSYM. Then record a fresh trace to confirm the fix.

Prevention

Make profiling builds a deliberate, repeatable process. Go through Product then Profile rather than improvising with arbitrary binaries.

Archive dSYMs for any build you may need to analyze later, including CI builds. Matching symbols are far easier to keep than to recover.

Keep your debug information settings sane for profiling configurations. Trading symbols for build speed is a false economy when you are chasing performance bugs.

Finally, note the native scope. Instruments symbolicates compiled native binaries, so if your output is web code from an app builder rather than native Swift, you would first compile a real native build in Xcode before any of this applies.

Why Symbolication Can Drift

It helps to understand why symbols and binaries can fall out of sync in the first place, because that makes the fixes feel less like guesswork.

When the compiler builds your app, it can strip human-readable names out of the binary and place them in a separate debug-symbol file. The binary then refers to addresses, and the symbol file is what translates those addresses back into names.

Every build produces a binary with a unique identifier, and the matching symbol file carries the same identifier. Symbolication works only when those identifiers line up, which is why a symbol file from a slightly different build cannot resolve the current trace.

This is also why rebuilding and profiling the same binary locally is so reliable: the binary and its symbols are produced together and are guaranteed to match. Most symbolication failures are simply a case of the two halves coming from different builds, and reuniting them resolves the problem.

For App Store and TestFlight builds, this is also why archiving and keeping the produced symbol files matters. If you ever need to analyze a build that shipped, the only thing that will symbolicate it cleanly is the exact symbol file generated for that exact build, so storing them deliberately is worth the small effort.

When It Is Not Your Fault

Some frames will never fully symbolicate, and that is expected. Deep system frameworks may show partial information, and you can usually ignore them.

What matters is that your own functions resolve to names and source lines. As long as that holds, you can do real performance work.

If only third-party closed-source frameworks are unreadable, treat them as black boxes and reason about how you call into them. You can often fix performance by changing your usage rather than their internals.

Keep your focus on the readable, actionable parts of the trace. A few opaque system frames rarely block a successful investigation.

Frequently Asked Questions

Why does Instruments show hex addresses instead of function names?

The trace is not symbolicated, meaning Instruments cannot map addresses to names. This usually happens when debug symbols are missing or the dSYM does not match the profiled binary.

What is a dSYM and why does it matter?

A dSYM is a file containing the debug symbols for a specific build. Instruments needs the dSYM that matches the binary you profiled in order to show readable function names and source lines.

How do I guarantee matching symbols?

Profile through Xcode using Product, then Profile, on the same machine that built the app. This produces a binary with matching symbol information and hands it to Instruments automatically.

Some system frames are still unreadable. Is that a problem?

Usually not. Deep system frameworks may only partially symbolicate, which is normal. As long as your own code resolves to names, you can do effective performance work.