Merge "logd: switch asprintf to std::string"
diff --git a/libbacktrace/Backtrace.cpp b/libbacktrace/Backtrace.cpp
index 128bb04..97f0ef4 100644
--- a/libbacktrace/Backtrace.cpp
+++ b/libbacktrace/Backtrace.cpp
@@ -102,6 +102,11 @@
   uintptr_t relative_pc = BacktraceMap::GetRelativePc(frame->map, frame->pc);
 
   std::string line(StringPrintf("#%02zu pc %" PRIPTR "  %s", frame->num, relative_pc, map_name));
+  // Special handling for non-zero offset maps, we need to print that
+  // information.
+  if (frame->map.offset != 0) {
+    line += " (offset " + StringPrintf("0x%" PRIxPTR, frame->map.offset) + ")";
+  }
   if (!frame->func_name.empty()) {
     line += " (" + frame->func_name;
     if (frame->func_offset) {
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index 6bd7529..9ebd639 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -825,6 +825,15 @@
   EXPECT_EQ("#01 pc 123456dc  MapFake (ProcFake+645)",
 #endif
             backtrace->FormatFrameData(&frame));
+
+  // Check a non-zero map offset.
+  frame.map.offset = 0x1000;
+#if defined(__LP64__)
+  EXPECT_EQ("#01 pc 00000000123456dc  MapFake (offset 0x1000) (ProcFake+645)",
+#else
+  EXPECT_EQ("#01 pc 123456dc  MapFake (offset 0x1000) (ProcFake+645)",
+#endif
+            backtrace->FormatFrameData(&frame));
 }
 
 struct map_test_t {
diff --git a/libsparse/backed_block.c b/libsparse/backed_block.c
index 3e72b57..794cd6b 100644
--- a/libsparse/backed_block.c
+++ b/libsparse/backed_block.c
@@ -221,7 +221,8 @@
 		}
 		break;
 	case BACKED_BLOCK_FILE:
-		if (a->file.filename != b->file.filename ||
+		/* Already make sure b->type is BACKED_BLOCK_FILE */
+		if (strcmp(a->file.filename, b->file.filename) ||
 				a->file.offset + a->len != b->file.offset) {
 			return -EINVAL;
 		}
@@ -279,7 +280,10 @@
 	}
 
 	merge_bb(bbl, new_bb, new_bb->next);
-	merge_bb(bbl, bb, new_bb);
+	if (!merge_bb(bbl, bb, new_bb)) {
+		/* new_bb destroyed, point to retained as last_used */
+		bbl->last_used = bb;
+	}
 
 	return 0;
 }
diff --git a/metricsd/constants.h b/metricsd/constants.h
index d65e0e0..56dac0d 100644
--- a/metricsd/constants.h
+++ b/metricsd/constants.h
@@ -21,7 +21,7 @@
 static const char kMetricsDirectory[] = "/data/misc/metrics/";
 static const char kMetricsEventsFilePath[] = "/data/misc/metrics/uma-events";
 static const char kMetricsGUIDFilePath[] = "/data/misc/metrics/Sysinfo.GUID";
-static const char kMetricsServer[] = "http://clients4.google.com/uma/v2";
+static const char kMetricsServer[] = "https://clients4.google.com/uma/v2";
 static const char kConsentFilePath[] = "/data/misc/metrics/enabled";
 static const char kDefaultVersion[] = "0.0.0.0";
 }  // namespace metrics
diff --git a/metricsd/init.metrics_daemon.rc b/metricsd/init.metrics_daemon.rc
index ad78ea5..73ce673 100644
--- a/metricsd/init.metrics_daemon.rc
+++ b/metricsd/init.metrics_daemon.rc
@@ -1,5 +1,5 @@
 on boot
-    mkdir /data/misc/metrics 0700 system system
+    mkdir /data/misc/metrics 0770 system system
 
 service metrics_daemon /system/bin/metrics_daemon --uploader -nodaemon
     class late_start
diff --git a/metricsd/uploader/metrics_log.cc b/metricsd/uploader/metrics_log.cc
index 5f4c599..1f16ca1 100644
--- a/metricsd/uploader/metrics_log.cc
+++ b/metricsd/uploader/metrics_log.cc
@@ -48,6 +48,6 @@
   stability->set_unclean_system_shutdown_count(current + 1);
 }
 
-void MetricsLog::PopulateSystemProfile(SystemProfileSetter* profile_setter) {
-  profile_setter->Populate(uma_proto());
+bool MetricsLog::PopulateSystemProfile(SystemProfileSetter* profile_setter) {
+  return profile_setter->Populate(uma_proto());
 }
diff --git a/metricsd/uploader/metrics_log.h b/metricsd/uploader/metrics_log.h
index 50fed89..5e09070 100644
--- a/metricsd/uploader/metrics_log.h
+++ b/metricsd/uploader/metrics_log.h
@@ -39,7 +39,7 @@
   void IncrementUncleanShutdownCount();
 
   // Populate the system profile with system information using setter.
-  void PopulateSystemProfile(SystemProfileSetter* setter);
+  bool PopulateSystemProfile(SystemProfileSetter* setter);
 
  private:
   FRIEND_TEST(UploadServiceTest, LogContainsAggregatedValues);
diff --git a/metricsd/uploader/system_profile_cache.cc b/metricsd/uploader/system_profile_cache.cc
index 35910d7..7dd0323 100644
--- a/metricsd/uploader/system_profile_cache.cc
+++ b/metricsd/uploader/system_profile_cache.cc
@@ -75,7 +75,7 @@
 
   if (!base::SysInfo::GetLsbReleaseValue("BRILLO_BUILD_TARGET_ID",
                                          &profile_.build_target_id)) {
-    LOG(ERROR) << "Could not initialize system profile.";
+    LOG(ERROR) << "BRILLO_BUILD_TARGET_ID is not set in /etc/lsb-release.";
     return false;
   }
 
@@ -109,11 +109,12 @@
   return initialized_ || Initialize();
 }
 
-void SystemProfileCache::Populate(
+bool SystemProfileCache::Populate(
     metrics::ChromeUserMetricsExtension* metrics_proto) {
   CHECK(metrics_proto);
-  CHECK(InitializeOrCheck())
-      << "failed to initialize system information.";
+  if (not InitializeOrCheck()) {
+    return false;
+  }
 
   // The client id is hashed before being sent.
   metrics_proto->set_client_id(
@@ -132,6 +133,8 @@
   metrics::SystemProfileProto_BrilloDeviceData* device_data =
       profile_proto->mutable_brillo();
   device_data->set_build_target_id(profile_.build_target_id);
+
+  return true;
 }
 
 std::string SystemProfileCache::GetPersistentGUID(
diff --git a/metricsd/uploader/system_profile_cache.h b/metricsd/uploader/system_profile_cache.h
index c53a18e..ac80b47 100644
--- a/metricsd/uploader/system_profile_cache.h
+++ b/metricsd/uploader/system_profile_cache.h
@@ -52,7 +52,7 @@
   SystemProfileCache(bool testing, const std::string& config_root);
 
   // Populates the ProfileSystem protobuf with system information.
-  void Populate(metrics::ChromeUserMetricsExtension* metrics_proto) override;
+  bool Populate(metrics::ChromeUserMetricsExtension* metrics_proto) override;
 
   // Converts a string representation of the channel to a
   // SystemProfileProto_Channel
diff --git a/metricsd/uploader/system_profile_setter.h b/metricsd/uploader/system_profile_setter.h
index cd311a4..bd3ff42 100644
--- a/metricsd/uploader/system_profile_setter.h
+++ b/metricsd/uploader/system_profile_setter.h
@@ -27,7 +27,7 @@
  public:
   virtual ~SystemProfileSetter() {}
   // Populates the protobuf with system informations.
-  virtual void Populate(metrics::ChromeUserMetricsExtension* profile_proto) = 0;
+  virtual bool Populate(metrics::ChromeUserMetricsExtension* profile_proto) = 0;
 };
 
 #endif  // METRICS_UPLOADER_SYSTEM_PROFILE_SETTER_H_
diff --git a/metricsd/uploader/upload_service.cc b/metricsd/uploader/upload_service.cc
index 63b5789..2335630 100644
--- a/metricsd/uploader/upload_service.cc
+++ b/metricsd/uploader/upload_service.cc
@@ -73,7 +73,6 @@
   CHECK(!staged_log_) << "the staged log should be discarded before starting "
                          "a new metrics log";
   MetricsLog* log = new MetricsLog();
-  log->PopulateSystemProfile(system_profile_setter_.get());
   current_log_.reset(log);
 }
 
@@ -97,13 +96,12 @@
   // Previous upload successful, reading metrics sample from the file.
   ReadMetrics();
   GatherHistograms();
-
-  // No samples found. Exit to avoid sending an empty log.
-  if (!current_log_)
-    return;
-
   StageCurrentLog();
-  SendStagedLog();
+
+  // If a log is available for upload, upload it.
+  if (staged_log_) {
+    SendStagedLog();
+  }
 }
 
 void UploadService::SendStagedLog() {
@@ -225,6 +223,11 @@
 
   staged_log_.swap(current_log_);
   staged_log_->CloseLog();
+  if (!staged_log_->PopulateSystemProfile(system_profile_setter_.get())) {
+    LOG(WARNING) << "Error while adding metadata to the log. Discarding the "
+                 << "log.";
+    staged_log_.reset();
+  }
   failed_upload_count_ = 0;
 }