Skip to content

Commit

Permalink
Add fetching debug images by addresses
Browse files Browse the repository at this point in the history
update test

clean up

update test

update comments

remove file

fix imports

update docs

revert doc

use hashset

Format code

update naming

apiDump

Improve Nullability, consider case of null imageSize

Update tests, ensure code_file and debug_file are set
  • Loading branch information
buenaflor authored and markushi committed Feb 10, 2025
1 parent 0632191 commit febcd83
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public interface IDebugImagesLoader {
List<DebugImage> loadDebugImages();

@Nullable
Set<DebugImage> loadDebugImagesForAddresses(Set<Long> addresses);
Set<DebugImage> loadDebugImagesForAddresses(Set<String> addresses);

void clearDebugImages();
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public static NoOpDebugImagesLoader getInstance() {
}

@Override
public @Nullable Set<DebugImage> loadDebugImagesForAddresses(Set<Long> addresses) {
public @Nullable Set<DebugImage> loadDebugImagesForAddresses(Set<String> addresses) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public DebugImagesLoader(
debugImages = new ArrayList<>(debugImagesArr.length);
for (io.sentry.ndk.DebugImage d : debugImagesArr) {
final DebugImage debugImage = new DebugImage();
debugImage.setCodeFile(d.getCodeFile());
debugImage.setDebugFile(d.getDebugFile());
debugImage.setUuid(d.getUuid());
debugImage.setType(d.getType());
debugImage.setDebugId(d.getDebugId());
Expand Down Expand Up @@ -83,7 +85,8 @@ public DebugImagesLoader(
* @param addresses Set of memory addresses to find debug images for
* @return Set of matching debug images, or null if debug images couldn't be loaded
*/
public @Nullable Set<DebugImage> loadDebugImagesForAddresses(final @NotNull Set<Long> addresses) {
public @Nullable Set<DebugImage> loadDebugImagesForAddresses(
final @NotNull Set<String> addresses) {
try (final @NotNull ISentryLifecycleToken ignored = debugImagesLock.acquire()) {
final @Nullable List<DebugImage> allDebugImages = loadDebugImages();
if (allDebugImages == null) {
Expand Down Expand Up @@ -115,7 +118,7 @@ public DebugImagesLoader(
* @return The matching debug image or null if not found
*/
private @NotNull Set<DebugImage> filterImagesByAddresses(
final @NotNull List<DebugImage> images, final @NotNull Set<Long> addresses) {
final @NotNull List<DebugImage> images, final @NotNull Set<String> addresses) {
final Set<DebugImage> result = new HashSet<>();

for (int i = 0; i < images.size(); i++) {
Expand All @@ -125,35 +128,40 @@ public DebugImagesLoader(
final @Nullable String nextDebugImageAddress =
nextDebugImage != null ? nextDebugImage.getImageAddr() : null;

for (final @NotNull Long address : addresses) {
final @Nullable String imageAddress = image.getImageAddr();

if (imageAddress != null) {
try {
final long imageStart = Long.parseLong(imageAddress.replace("0x", ""), 16);
final long imageEnd;

final @Nullable Long imageSize = image.getImageSize();
if (imageSize != null) {
imageEnd = imageStart + imageSize;
} else if (nextDebugImageAddress != null) {
imageEnd = Long.parseLong(nextDebugImageAddress.replace("0x", ""), 16);
} else {
imageEnd = Long.MAX_VALUE;
}
if (address >= imageStart && address < imageEnd) {
result.add(image);
// once image is added we can skip the remaining addresses and go straight to the next
// image
break;
for (final @NotNull String rawAddress : addresses) {
try {
final long address = Long.parseLong(rawAddress.replace("0x", ""), 16);

final @Nullable String imageAddress = image.getImageAddr();
if (imageAddress != null) {
try {
final long imageStart = Long.parseLong(imageAddress.replace("0x", ""), 16);
final long imageEnd;

final @Nullable Long imageSize = image.getImageSize();
if (imageSize != null) {
imageEnd = imageStart + imageSize;
} else if (nextDebugImageAddress != null) {
imageEnd = Long.parseLong(nextDebugImageAddress.replace("0x", ""), 16);
} else {
imageEnd = Long.MAX_VALUE;
}
if (address >= imageStart && address < imageEnd) {
result.add(image);
// once image is added we can skip the remaining addresses and go straight to the
// next
// image
break;
}
} catch (NumberFormatException e) {
// ignored, invalid debug image address
}
} catch (NumberFormatException e) {
options.getLogger().log(SentryLevel.WARNING, e, "Failed to parse image address.");
}
} catch (NumberFormatException e) {
// ignored, invalid address supplied
}
}
}

return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class DebugImagesLoaderTest {
whenever(fixture.nativeLoader.loadModuleList()).thenReturn(arrayOf(image1, image2, image3))

val result = sut.loadDebugImagesForAddresses(
setOf(0x1500L, 0x2500L)
setOf("0x1500", "0x2500")
)

assertNotNull(result)
Expand All @@ -128,7 +128,7 @@ class DebugImagesLoaderTest {

whenever(fixture.nativeLoader.loadModuleList()).thenReturn(arrayOf(image1, image2))

val hexAddresses = setOf(-100, 0x1500L)
val hexAddresses = setOf("0xINVALID", "0x1500")
val result = sut.loadDebugImagesForAddresses(hexAddresses)

assertEquals(1, result!!.size)
Expand All @@ -150,7 +150,7 @@ class DebugImagesLoaderTest {

whenever(fixture.nativeLoader.loadModuleList()).thenReturn(arrayOf(image1, image2))

val hexAddresses = setOf(-100, 0x10500L)
val hexAddresses = setOf("0x100", "0x10500")
val result = sut.loadDebugImagesForAddresses(hexAddresses)

assertNull(result)
Expand All @@ -177,7 +177,7 @@ class DebugImagesLoaderTest {

whenever(fixture.nativeLoader.loadModuleList()).thenReturn(arrayOf(image1, image2, image3))

val hexAddresses = setOf(100L, 0x2000L, 0x2000L, 0x5000L)
val hexAddresses = setOf("0x100", "0x2000", "0x2000", "0x5000")
val result = sut.loadDebugImagesForAddresses(hexAddresses)

assertNotNull(result)
Expand Down

0 comments on commit febcd83

Please sign in to comment.