All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.sentry.protocol.DebugImage Maven / Gradle / Ivy

There is a newer version: 8.0.0-rc.3
Show newest version
package io.sentry.protocol;

import io.sentry.ILogger;
import io.sentry.JsonDeserializer;
import io.sentry.JsonSerializable;
import io.sentry.JsonUnknown;
import io.sentry.ObjectReader;
import io.sentry.ObjectWriter;
import io.sentry.vendor.gson.stream.JsonToken;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * Legacy apple debug images (MachO).
 *
 * 

This was also used for non-apple platforms with similar debug setups. * *

A generic (new-style) native platform debug information file. * *

The `type` key must be one of: * *

- `macho` - `elf`: ELF images are used on Linux platforms. Their structure is identical to * other native images. - `pe` * *

Examples: * *

```json { "type": "elf", "code_id": "68220ae2c65d65c1b6aaa12fa6765a6ec2f5f434", "code_file": * "/lib/x86_64-linux-gnu/libgcc_s.so.1", "debug_id": "e20a2268-5dc6-c165-b6aa-a12fa6765a6e", * "image_addr": "0x7f5140527000", "image_size": 90112, "image_vmaddr": "0x40000", "arch": "x86_64" * } ``` * *

```json { "type": "pe", "code_id": "57898e12145000", "code_file": * "C:\\Windows\\System32\\dbghelp.dll", "debug_id": "9c2a902b-6fdf-40ad-8308-588a41d572a0-1", * "debug_file": "dbghelp.pdb", "image_addr": "0x70850000", "image_size": "1331200", "image_vmaddr": * "0x40000", "arch": "x86" } ``` * *

```json { "type": "macho", "debug_id": "84a04d24-0e60-3810-a8c0-90a65e2df61a", "debug_file": * "libDiagnosticMessagesClient.dylib", "code_file": "/usr/lib/libDiagnosticMessagesClient.dylib", * "image_addr": "0x7fffe668e000", "image_size": 8192, "image_vmaddr": "0x40000", "arch": "x86_64", * } ``` * *

Proguard mapping file. * *

Proguard images refer to `mapping.txt` files generated when Proguard obfuscates function * names. The Java SDK integrations assign this file a unique identifier, which has to be included * in the list of images. */ public final class DebugImage implements JsonUnknown, JsonSerializable { public static final String PROGUARD = "proguard"; public static final String JVM = "jvm"; /** * The unique UUID of the image. * *

UUID computed from the file contents, assigned by the Java SDK. */ private @Nullable String uuid; private @Nullable String type; /** * Unique debug identifier of the image. * *

- `elf`: Debug identifier of the dynamic library or executable. If a code identifier is * available, the debug identifier is the little-endian UUID representation of the first 16-bytes * of that identifier. Spaces are inserted for readability, note the byte order of the first * fields: * *

```text code id: f1c3bcc0 2798 65fe 3058 404b2831d9e6 4135386c debug id: * c0bcc3f1-9827-fe65-3058-404b2831d9e6 ``` * *

If no code id is available, the debug id should be computed by XORing the first 4096 bytes * of the `.text` section in 16-byte chunks, and representing it as a little-endian UUID (again * swapping the byte order). * *

- `pe`: `signature` and `age` of the PDB file. Both values can be read from the CodeView * PDB70 debug information header in the PE. The value should be represented as little-endian * UUID, with the age appended at the end. Note that the byte order of the UUID fields must be * swapped (spaces inserted for readability): * *

```text signature: f1c3bcc0 2798 65fe 3058 404b2831d9e6 age: 1 debug_id: * c0bcc3f1-9827-fe65-3058-404b2831d9e6-1 ``` * *

- `macho`: Identifier of the dynamic library or executable. It is the value of the `LC_UUID` * load command in the Mach header, formatted as UUID. */ private @Nullable String debugId; /** * Path and name of the debug companion file. * *

- `elf`: Name or absolute path to the file containing stripped debug information for this * image. This value might be _required_ to retrieve debug files from certain symbol servers. * *

- `pe`: Name of the PDB file containing debug information for this image. This value is * often required to retrieve debug files from specific symbol servers. * *

- `macho`: Name or absolute path to the dSYM file containing debug information for this * image. This value might be required to retrieve debug files from certain symbol servers. */ private @Nullable String debugFile; /** * Optional identifier of the code file. * *

- `elf`: If the program was compiled with a relatively recent compiler, this should be the * hex representation of the `NT_GNU_BUILD_ID` program header (type `PT_NOTE`), or the value of * the `.note.gnu.build-id` note section (type `SHT_NOTE`). Otherwise, leave this value empty. * *

Certain symbol servers use the code identifier to locate debug information for ELF images, * in which case this field should be included if possible. * *

- `pe`: Identifier of the executable or DLL. It contains the values of the `time_date_stamp` * from the COFF header and `size_of_image` from the optional header formatted together into a hex * string using `%08x%X` (note that the second value is not padded): * *

```text time_date_stamp: 0x5ab38077 size_of_image: 0x9000 code_id: 5ab380779000 ``` * *

The code identifier should be provided to allow server-side stack walking of binary crash * reports, such as Minidumps. * *

* *

- `macho`: Identifier of the dynamic library or executable. It is the value of the `LC_UUID` * load command in the Mach header, formatted as UUID. Can be empty for Mach images, as it is * equivalent to the debug identifier. */ private @Nullable String codeId; /** * Path and name of the image file (required). * *

The absolute path to the dynamic library or executable. This helps to locate the file if it * is missing on Sentry. * *

- `pe`: The code file should be provided to allow server-side stack walking of binary crash * reports, such as Minidumps. */ private @Nullable String codeFile; /** * Starting memory address of the image (required). * *

Memory address, at which the image is mounted in the virtual address space of the process. * Should be a string in hex representation prefixed with `"0x"`. */ private @Nullable String imageAddr; /** * Size of the image in bytes (required). * *

The size of the image in virtual memory. If missing, Sentry will assume that the image spans * up to the next image, which might lead to invalid stack traces. */ private @Nullable Long imageSize; /** * CPU architecture target. * *

Architecture of the module. If missing, this will be backfilled by Sentry. */ private @Nullable String arch; @SuppressWarnings("unused") private @Nullable Map unknown; public @Nullable String getUuid() { return uuid; } public void setUuid(final @Nullable String uuid) { this.uuid = uuid; } public @Nullable String getType() { return type; } public void setType(final @Nullable String type) { this.type = type; } public @Nullable String getDebugId() { return debugId; } public void setDebugId(final @Nullable String debugId) { this.debugId = debugId; } public @Nullable String getDebugFile() { return debugFile; } public void setDebugFile(final @Nullable String debugFile) { this.debugFile = debugFile; } public @Nullable String getCodeFile() { return codeFile; } public void setCodeFile(final @Nullable String codeFile) { this.codeFile = codeFile; } public @Nullable String getImageAddr() { return imageAddr; } public void setImageAddr(final @Nullable String imageAddr) { this.imageAddr = imageAddr; } public @Nullable Long getImageSize() { return imageSize; } public void setImageSize(final @Nullable Long imageSize) { this.imageSize = imageSize; } /** * Sets the image size. * * @param imageSize the image size. */ public void setImageSize(long imageSize) { this.imageSize = imageSize; } public @Nullable String getArch() { return arch; } public void setArch(final @Nullable String arch) { this.arch = arch; } public @Nullable String getCodeId() { return codeId; } public void setCodeId(final @Nullable String codeId) { this.codeId = codeId; } // JsonKeys public static final class JsonKeys { public static final String UUID = "uuid"; public static final String TYPE = "type"; public static final String DEBUG_ID = "debug_id"; public static final String DEBUG_FILE = "debug_file"; public static final String CODE_ID = "code_id"; public static final String CODE_FILE = "code_file"; public static final String IMAGE_ADDR = "image_addr"; public static final String IMAGE_SIZE = "image_size"; public static final String ARCH = "arch"; } // JsonUnknown @Override public @Nullable Map getUnknown() { return unknown; } @Override public void setUnknown(@Nullable Map unknown) { this.unknown = unknown; } // JsonSerializable @Override public void serialize(final @NotNull ObjectWriter writer, final @NotNull ILogger logger) throws IOException { writer.beginObject(); if (uuid != null) { writer.name(JsonKeys.UUID).value(uuid); } if (type != null) { writer.name(JsonKeys.TYPE).value(type); } if (debugId != null) { writer.name(JsonKeys.DEBUG_ID).value(debugId); } if (debugFile != null) { writer.name(JsonKeys.DEBUG_FILE).value(debugFile); } if (codeId != null) { writer.name(JsonKeys.CODE_ID).value(codeId); } if (codeFile != null) { writer.name(JsonKeys.CODE_FILE).value(codeFile); } if (imageAddr != null) { writer.name(JsonKeys.IMAGE_ADDR).value(imageAddr); } if (imageSize != null) { writer.name(JsonKeys.IMAGE_SIZE).value(imageSize); } if (arch != null) { writer.name(JsonKeys.ARCH).value(arch); } if (unknown != null) { for (String key : unknown.keySet()) { Object value = unknown.get(key); writer.name(key).value(logger, value); } } writer.endObject(); } // JsonDeserializer public static final class Deserializer implements JsonDeserializer { @Override public @NotNull DebugImage deserialize(@NotNull ObjectReader reader, @NotNull ILogger logger) throws Exception { DebugImage debugImage = new DebugImage(); Map unknown = null; reader.beginObject(); while (reader.peek() == JsonToken.NAME) { final String nextName = reader.nextName(); switch (nextName) { case JsonKeys.UUID: debugImage.uuid = reader.nextStringOrNull(); break; case JsonKeys.TYPE: debugImage.type = reader.nextStringOrNull(); break; case JsonKeys.DEBUG_ID: debugImage.debugId = reader.nextStringOrNull(); break; case JsonKeys.DEBUG_FILE: debugImage.debugFile = reader.nextStringOrNull(); break; case JsonKeys.CODE_ID: debugImage.codeId = reader.nextStringOrNull(); break; case JsonKeys.CODE_FILE: debugImage.codeFile = reader.nextStringOrNull(); break; case JsonKeys.IMAGE_ADDR: debugImage.imageAddr = reader.nextStringOrNull(); break; case JsonKeys.IMAGE_SIZE: debugImage.imageSize = reader.nextLongOrNull(); break; case JsonKeys.ARCH: debugImage.arch = reader.nextStringOrNull(); break; default: if (unknown == null) { unknown = new HashMap<>(); } reader.nextUnknown(logger, unknown, nextName); break; } } reader.endObject(); debugImage.setUnknown(unknown); return debugImage; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy