Set warning for dex pc not in map.

This way, the profilers will know they have to reparse maps.

Bug: 163130539

Test: Verified updated unit tests pass.
Change-Id: I88a801ffdda12811eab5e4833dcf472f2d75c09a
diff --git a/libunwindstack/Unwinder.cpp b/libunwindstack/Unwinder.cpp
index 2d867cd..b904632 100644
--- a/libunwindstack/Unwinder.cpp
+++ b/libunwindstack/Unwinder.cpp
@@ -75,7 +75,7 @@
     frame->rel_pc = dex_pc - info->start;
   } else {
     frame->rel_pc = dex_pc;
-    return;
+    warnings_ |= WARNING_DEX_PC_NOT_IN_MAP;
   }
 
   if (!resolve_names_) {
@@ -142,6 +142,7 @@
 void Unwinder::Unwind(const std::vector<std::string>* initial_map_names_to_skip,
                       const std::vector<std::string>* map_suffixes_to_ignore) {
   frames_.clear();
+  warnings_ = WARNING_NONE;
   last_error_.code = ERROR_NONE;
   last_error_.address = 0;
   elf_from_memory_not_file_ = false;
diff --git a/libunwindstack/include/unwindstack/Error.h b/libunwindstack/include/unwindstack/Error.h
index 72ec454..66fefe7 100644
--- a/libunwindstack/include/unwindstack/Error.h
+++ b/libunwindstack/include/unwindstack/Error.h
@@ -21,6 +21,13 @@
 
 namespace unwindstack {
 
+// A bit map of warnings, multiple warnings can be set at the same time.
+enum WarningCode : uint64_t {
+  WARNING_NONE = 0,
+  WARNING_DEX_PC_NOT_IN_MAP = 0x1,  // A dex pc was found, but it doesn't exist
+                                    // in any valid map.
+};
+
 enum ErrorCode : uint8_t {
   ERROR_NONE,                 // No error.
   ERROR_MEMORY_INVALID,       // Memory read failed.
diff --git a/libunwindstack/include/unwindstack/Unwinder.h b/libunwindstack/include/unwindstack/Unwinder.h
index 4d49f23..a974b63 100644
--- a/libunwindstack/include/unwindstack/Unwinder.h
+++ b/libunwindstack/include/unwindstack/Unwinder.h
@@ -113,6 +113,7 @@
 
   ErrorCode LastErrorCode() { return last_error_.code; }
   uint64_t LastErrorAddress() { return last_error_.address; }
+  uint64_t warnings() { return warnings_; }
 
   // Builds a frame for symbolization using the maps from this unwinder. The
   // constructed frame contains just enough information to be used to symbolize
@@ -141,6 +142,7 @@
   // file. This is only true if there is an actual file backing up the elf.
   bool elf_from_memory_not_file_ = false;
   ErrorData last_error_;
+  uint64_t warnings_;
 };
 
 class UnwinderFromPid : public Unwinder {
diff --git a/libunwindstack/tests/UnwinderTest.cpp b/libunwindstack/tests/UnwinderTest.cpp
index dd33aa9..d10af2f 100644
--- a/libunwindstack/tests/UnwinderTest.cpp
+++ b/libunwindstack/tests/UnwinderTest.cpp
@@ -168,6 +168,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(3U, unwinder.NumFrames());
@@ -233,6 +234,7 @@
   unwinder.SetResolveNames(false);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(3U, unwinder.NumFrames());
@@ -293,6 +295,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
@@ -323,6 +326,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
@@ -353,6 +357,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
@@ -384,6 +389,7 @@
   unwinder.SetEmbeddedSoname(false);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
@@ -421,6 +427,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
@@ -454,6 +461,7 @@
   Unwinder unwinder(20, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(20U, unwinder.NumFrames());
@@ -497,6 +505,7 @@
   std::vector<std::string> skip_libs{"libunwind.so", "libanother.so"};
   unwinder.Unwind(&skip_libs);
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(3U, unwinder.NumFrames());
@@ -559,6 +568,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(2U, unwinder.NumFrames());
@@ -607,6 +617,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
@@ -627,6 +638,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
@@ -642,6 +654,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
@@ -679,6 +692,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(3U, unwinder.NumFrames());
@@ -745,6 +759,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_INVALID_MAP, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(2U, unwinder.NumFrames());
@@ -795,6 +810,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(2U, unwinder.NumFrames());
@@ -843,6 +859,7 @@
   std::vector<std::string> skip_names{"libanother.so"};
   unwinder.Unwind(&skip_names);
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(0U, unwinder.NumFrames());
@@ -866,6 +883,7 @@
   std::vector<std::string> suffixes{"oat"};
   unwinder.Unwind(nullptr, &suffixes);
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(2U, unwinder.NumFrames());
@@ -925,6 +943,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_REPEATED_FRAME, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(3U, unwinder.NumFrames());
@@ -984,6 +1003,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(2U, unwinder.NumFrames());
@@ -1028,6 +1048,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(2U, unwinder.NumFrames());
@@ -1072,6 +1093,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_DEX_PC_NOT_IN_MAP, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(2U, unwinder.NumFrames());
@@ -1119,6 +1141,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(3U, unwinder.NumFrames());
@@ -1178,6 +1201,7 @@
   Unwinder unwinder(1, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
@@ -1208,6 +1232,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_TRUE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
@@ -1238,6 +1263,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
@@ -1268,6 +1294,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());
@@ -1298,6 +1325,7 @@
   Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
   unwinder.Unwind();
   EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
+  EXPECT_EQ(WARNING_NONE, unwinder.warnings());
   EXPECT_FALSE(unwinder.elf_from_memory_not_file());
 
   ASSERT_EQ(1U, unwinder.NumFrames());