IntelliJNativeFrameSymbolizer implements NativeFrameSymbolizer { @NotNull @Override public NativeCallStack.NativeFrame symbolize(String abi, NativeCallStack.NativeFrame unsymbolizedFrame) { Symbol symbol = null; long instructionOffset = getOffsetOfPreviousInstruction(unsymbolizedFrame.getModuleOffset()); try { symbol = mySymbolizer.symbolize(abi, unsymbolizedFrame.getModuleName(), instructionOffset); } catch (IOException | RuntimeException e) { getLogger().warn(e); } NativeCallStack.NativeFrame.Builder builder = unsymbolizedFrame.toBuilder(); if (symbol == null) { String unfoundSymbolName = String.format("0x%x", instructionOffset); builder.setSymbolName(unfoundSymbolName); } else { builder.setSymbolName(symbol.getName()) .setModuleName(symbol.getModule()) .setFileName(symbol.getSourceFile()) .setLineNumber(symbol.getLineNumber()); } return builder.build(); } IntelliJNativeFrameSymbolizer(@NotNull NativeSymbolizer symbolizer); @NotNull @Override NativeCallStack.NativeFrame symbolize(String abi, NativeCallStack.NativeFrame unsymbolizedFrame);  }
@Test public void testSymbolize() { IntelliJNativeFrameSymbolizer frameSymbolizer = new IntelliJNativeFrameSymbolizer(new FakeNativeSymbolizer()); NativeCallStack.NativeFrame unsymbolizedFrame = frameSymbolizer .symbolize("arm64", NativeCallStack.NativeFrame.newBuilder().setModuleName("test").setModuleOffset(100).build()); assertThat(unsymbolizedFrame.getSymbolName()).isEqualTo(String.format("0x%x", 100 - 1)); NativeCallStack.NativeFrame.Builder frameToSymbolize1 = NativeCallStack.NativeFrame.newBuilder().setModuleName("test2").setModuleOffset(100); NativeCallStack.NativeFrame symbolizedFrame1 = frameSymbolizer.symbolize("arm", frameToSymbolize1.build()); NativeCallStack.NativeFrame expectedSymbolizedFrame1 = frameToSymbolize1 .setSymbolName("arm_frame") .setModuleName("test2_symbolized") .setFileName("symbols.java") .setLineNumber(1000 + 100 + PREVIOUS_INSTRUCTION_OFFSET).build(); assertThat(symbolizedFrame1).isEqualTo(expectedSymbolizedFrame1); NativeCallStack.NativeFrame.Builder frameToSymbolize2 = NativeCallStack.NativeFrame.newBuilder().setModuleName("test3").setModuleOffset(200); NativeCallStack.NativeFrame symbolizedFrame2 = frameSymbolizer.symbolize("x86", frameToSymbolize2.build()); NativeCallStack.NativeFrame expectedSymbolizedFrame2 = frameToSymbolize2 .setSymbolName("x86_frame") .setModuleName("test3_symbolized") .setFileName("symbols.java") .setLineNumber(1000 + 200 + PREVIOUS_INSTRUCTION_OFFSET).build(); assertThat(symbolizedFrame2).isEqualTo(expectedSymbolizedFrame2); }