diff options
| author | 2025-01-22 13:46:27 -0800 | |
|---|---|---|
| committer | 2025-01-23 00:15:23 +0000 | |
| commit | 8623733336a2a73d98f5107d0942d3db40c612dc (patch) | |
| tree | cc96d51bf056e3d20005230280cca69ae0e4c394 | |
| parent | 1dd200f972b74346d6794ede34344c730a8977a2 (diff) | |
Distinguish the reason why decoding failed.
We were throwing a RuntimeException that the message hash wasn't in the
viewer config file, but this can also happen when the viewer config file
wasn't loaded into memory from disk, which is more likely a bug.
Update the exception to clarify what's happening.
Test: atest com.android.internal.protolog.ProtoLogViewerConfigReaderTest
Bug: 388235335
Flag: EXEMPT updating error message clarity
Change-Id: I484c918ec196d57bb910900e3a7a7870923d64a5
3 files changed, 70 insertions, 4 deletions
diff --git a/core/java/com/android/internal/protolog/ProcessedPerfettoProtoLogImpl.java b/core/java/com/android/internal/protolog/ProcessedPerfettoProtoLogImpl.java index e0a77d2be724..1f9df3cc842a 100644 --- a/core/java/com/android/internal/protolog/ProcessedPerfettoProtoLogImpl.java +++ b/core/java/com/android/internal/protolog/ProcessedPerfettoProtoLogImpl.java @@ -28,6 +28,7 @@ import com.android.internal.protolog.common.IProtoLogGroup; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.IOException; import java.util.ArrayList; public class ProcessedPerfettoProtoLogImpl extends PerfettoProtoLogImpl { @@ -161,15 +162,39 @@ public class ProcessedPerfettoProtoLogImpl extends PerfettoProtoLogImpl { messageString = message.getMessage(mViewerConfigReader); if (messageString == null) { - throw new RuntimeException("Failed to decode message for logcat. " - + "Message hash (" + message.getMessageHash() + ") either not available in " - + "viewerConfig file (" + mViewerConfigFilePath + ") or " - + "not loaded into memory from file before decoding."); + // Either we failed to load the config for this log message from the viewer config file + // into memory, or the message hash is simply not available in the viewer config file. + // We want to confirm that the message hash is not available in the viewer config file + // before throwing an exception. + throw new RuntimeException(getReasonForFailureToGetMessageString(message)); } return messageString; } + private String getReasonForFailureToGetMessageString(Message message) { + if (message.getMessageHash() == null) { + return "Trying to get message from null message hash"; + } + + try { + if (mViewerConfigReader.messageHashIsAvailableInFile(message.getMessageHash())) { + return "Failed to decode message for logcat logging. " + + "Message hash (" + message.getMessageHash() + ") is not available in " + + "viewerConfig file (" + mViewerConfigFilePath + "). This might be due " + + "to the viewer config file and the executing code being out of sync."; + } else { + return "Failed to decode message for logcat. " + + "Message hash (" + message.getMessageHash() + ") was available in the " + + "viewerConfig file (" + mViewerConfigFilePath + ") but wasn't loaded " + + "into memory from file before decoding! This is likely a bug."; + } + } catch (IOException e) { + return "Failed to get string message to log but could not identify the root cause due " + + "to an IO error in reading the viewer config file."; + } + } + private void loadLogcatGroupsViewerConfig(@NonNull IProtoLogGroup[] protoLogGroups) { final var groupsLoggingToLogcat = new ArrayList<String>(); for (IProtoLogGroup protoLogGroup : protoLogGroups) { diff --git a/core/java/com/android/internal/protolog/ProtoLogViewerConfigReader.java b/core/java/com/android/internal/protolog/ProtoLogViewerConfigReader.java index 524f64225084..f77179949fbf 100644 --- a/core/java/com/android/internal/protolog/ProtoLogViewerConfigReader.java +++ b/core/java/com/android/internal/protolog/ProtoLogViewerConfigReader.java @@ -100,6 +100,36 @@ public class ProtoLogViewerConfigReader { } } + /** + * Return whether or not the viewer config file contains a message with the specified hash. + * @param messageHash The hash message we are looking for in the viewer config file + * @return True iff the message with message hash is contained in the viewer config. + * @throws IOException if there was an issue reading the viewer config file. + */ + public boolean messageHashIsAvailableInFile(long messageHash) + throws IOException { + try (var pisWrapper = mViewerConfigInputStreamProvider.getInputStream()) { + final var pis = pisWrapper.get(); + while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) { + if (pis.getFieldNumber() == (int) MESSAGES) { + final long inMessageToken = pis.start(MESSAGES); + + while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) { + if (pis.getFieldNumber() == (int) MESSAGE_ID) { + if (pis.readLong(MESSAGE_ID) == messageHash) { + return true; + } + } + } + + pis.end(inMessageToken); + } + } + } + + return false; + } + @NonNull private Map<Long, String> loadViewerConfigMappingForGroup(@NonNull String group) throws IOException { diff --git a/tests/Tracing/src/com/android/internal/protolog/ProtoLogViewerConfigReaderTest.java b/tests/Tracing/src/com/android/internal/protolog/ProtoLogViewerConfigReaderTest.java index 9e029a8d5e57..72b1780ceb06 100644 --- a/tests/Tracing/src/com/android/internal/protolog/ProtoLogViewerConfigReaderTest.java +++ b/tests/Tracing/src/com/android/internal/protolog/ProtoLogViewerConfigReaderTest.java @@ -33,6 +33,7 @@ import org.junit.runners.JUnit4; import perfetto.protos.ProtologCommon; import java.io.File; +import java.io.IOException; @Presubmit @RunWith(JUnit4.class) @@ -159,4 +160,14 @@ public class ProtoLogViewerConfigReaderTest { loadViewerConfig(); unloadViewerConfig(); } + + @Test + public void testMessageHashIsAvailableInFile() throws IOException { + Truth.assertThat(mConfig.messageHashIsAvailableInFile(1)).isTrue(); + Truth.assertThat(mConfig.messageHashIsAvailableInFile(2)).isTrue(); + Truth.assertThat(mConfig.messageHashIsAvailableInFile(3)).isTrue(); + Truth.assertThat(mConfig.messageHashIsAvailableInFile(4)).isTrue(); + Truth.assertThat(mConfig.messageHashIsAvailableInFile(5)).isTrue(); + Truth.assertThat(mConfig.messageHashIsAvailableInFile(6)).isFalse(); + } } |