tencent cloud

Tencent Cloud Observability Platform

Overview

Download
Focus Mode
Font Size
Last updated: 2026-05-25 18:53:27

symbol table

Definition

A symbol table has slightly different meanings across platforms, but its purpose is always to restore obfuscated stack traces to human-readable file names, method names, and line numbers.
On the Android platform, there are two types of symbol tables: shared object (SO) symbol tables and Java mapping files. For detailed explanations, see Android Symbol Tables.
Android Java Stack Deobfuscation:

Android Native Stack Deobfuscation:

On the iOS platform, a symbol table refers to a dSYM file. For detailed explanations, see iOS Symbol Tables. An example of iOS stack trace deobfuscation is as follows:

On the Harmony platform, there are two types of symbol tables: shared object (SO) symbol tables and nameCache & SourceMaps files. For detailed explanations, see Harmony (Hongmeng) Symbol Tables.


Distinguishing Symbol Tables

During deobfuscation, the required symbol table for restoration can be determined by the context of the exception stack trace:
Platform
Type
Description
Android Platform
Android Java Stack Trace
The symbol table file is the mapping file.
Locate the symbol table file via the App version and build number.
For the same App version and build, multiple mapping files can be uploaded simultaneously and distinguished by their filenames.
During symbol deobfuscation, eligible mapping files are identified by the App version and build number. These mapping files are then combined into a single comprehensive mapping before translation.
Android Native Stack Trace
The symbol table is an SO containing symbol information.
Symbol tables can be located using the UUID of the SO, meaning that during the same build, both the SO containing symbol tables and the SO with symbol tables removed can be generated, and they share the same UUID.
App version, build number, CPU architecture, and module name are merely for enhanced readability, while the SO's UUID serves as the unique identifier.
iOS Platform
iOS Stack Trace
The symbol table file is the dSYM file.
Locate the symbol table via UUID.
App version, build number, CPU architecture, and module name are merely for enhanced readability, while the UUID serves as the unique identifier.
Harmony Platform
JS Stack Trace
The symbol table file is the SourceMap file.
Locate the symbol table file via the App version and build number.
For the same App version and build, multiple SourceMap files can be uploaded simultaneously and distinguished by their filenames.
During symbol deobfuscation, eligible SourceMap files are identified by the App version and build number. All these files are then combined into a single comprehensive SourceMap before the translation process.

Manage symbol tables

Users can view the symbol table information for the current product under Setting > Symbol Table.
1. Check whether the specified symbol table has been uploaded by applying filter criteria.
2. Upload the symbol table; for details, see Upload the symbol table.
3. Click View Details to view the overall status of the product symbol table.

Users can query uploaded symbol table information in the Symbol Table List Tab using filter criteria such as Symbol table type, Version No., build number, upload ID, Upload Method, and Symbol Table Infomation.


UUID

Definition

The UUID is used to uniquely identify a module. Both Android's SO symbol tables and iOS's dSYM files use UUIDs to uniquely identify a symbol table file. After capturing an exception stack, the SDK will obtain the UUID of the corresponding module. The symbol deobfuscation platform then uses this UUID to search for the corresponding symbol table file.
Example 1: The Android Native stack contains UUID information, and the deobfuscation system uses the UUID to search for the symbol table.

Example 2: In iOS exceptions, the Binary Images section of the crash.log file contains mappings of module address ranges to UUIDs and module names.



UUID Retrieval Guidance

Android SO UUID

There are two methods for generating UUIDs in Android NDK.
Generate at compile time
Read the .note.gnu.build-id Section; if a value is found, use the UUID generated during compilation.
readelf -x .note.gnu.build-id libBugly.SO

Hex dump of section '.note.gnu.build-id':
0x000001c8 04000000 14000000 03000000 474e5500 ............GNU.
0x000001d8 c21c5005 a226dedc 83a5a5b3 1611a3d6 ..P..&..........
0x000001e8 27713fd9 'q?.
Among them:
0x000001c8: indicates the offset address of the .note.gnu.build-id section in the elf file.
04000000: indicates the name size, which corresponds to 4 bytes in decimal.
14000000: indicates the size occupied by the UUID, corresponding to 20 bytes in decimal.
03000000: indicates the type.
474e5500 is 4 bytes, which corresponds to the name GNU.
c21c5005 a226dedc 83a5a5b3 1611a3d6 27713fd9 totals 20 bytes, corresponding to the UUID generated during the compilation process. The compiled UUID is 160 bits, while the platform uses 16 bytes (128 bits). If the UUID exceeds 128 bits, the platform discards the first 32 bits. Therefore, the UUID actually obtained by the platform here is a226dedc83a5a5b31611a3d627713fd9, which is the last 16 bytes.
Note:
The platform uses a 16-byte UUID, specifically the last 16 bytes of the UUID generated during compilation.
Generate at runtime
When the .note.gnu.build-id section is absent in an elf file, the platform's method of generating a 16-byte UUID by hashing the first 4096 bytes of the .text section may cause conflicts due to minor byte differences. Even expanding the calculation scope to the entire .text section cannot resolve UUID conflicts between two code versions differing only by a few lines of whitespace (where .text content remains identical but compiles to different UUIDs). Moreover, runtime calculation of the entire .text section impacts program efficiency. While developers might disable .note.gnu.build-id generation for compilation efficiency, compilation time is negligible compared to runtime overhead. Therefore, to strictly guarantee UUID uniqueness, the .note.gnu.build-id must be generated during SO build configuration. You can enable .note.gnu.build-id generation during compilation through the following two methods:
NDK build: Configure LOCAL_LDFLAGS += -Xlinker --build-id in Android.mk.
Clang build: Refer here.

Mach-O UUID

Mach-O UUID is generated during build time and stored in the Mach-O header. There are two methods to query the UUID of a dSYM.
Read from the command line
dwarfdump -u path/to/compile/executable
Read from the code
#import <mach-o/ldsyms.h>
NSString *executableUUID()
{
const uint8_t *command = (const uint8_t *)(&_mh_execute_header + 1);
for (uint32_t idx = 0; idx < _mh_execute_header.ncmds; ++idx) {
if (((const struct load_command *)command)->cmd == LC_UUID) {
command += sizeof(struct load_command);
return [NSString stringWithFormat:@"%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
command[0], command[1], command[2], command[3],
command[4], command[5],
command[6], command[7],
command[8], command[9],
command[10], command[11], command[12], command[13], command[14], command[15]];
} else {
command += ((const struct load_command *)command)->cmdsize;
}
}
return nil;
}

Under what circumstances will UUIDs be the same

Each binary file in an app—the main app executable, frameworks, and app extensions—has its own dSYM file. The compiled binary and its companion dSYM file are tied together by a build UUID, that’s recorded by both the built binary and dSYM file. If you build two binaries from the same source code but with different Xcode versions or build settings, the build UUIDs for the two binaries won’t match. A binary and a dSYM file are only compatible with each other when they have identical build UUIDs. Keep the dSYM files for the specific builds you distribute, and use them when diagnosing issues from crash reports.
The above explanation is referenced from the article Building Your App to Include Debugging Information. This rule also applies to the Android Native / Linux platform.
Note:
The module UUIDs will be equal only when both conditions are simultaneously met:
The code is completely identical.
The build platform configuration is completely identical.

Help and Support

Was this page helpful?

Help us improve! Rate your documentation experience in 5 mins.

Feedback