Merge "Fix bug in summary trace to text."
diff --git a/src/ftrace_reader/cpu_reader.cc b/src/ftrace_reader/cpu_reader.cc
index ecb949c..fb20a3c 100644
--- a/src/ftrace_reader/cpu_reader.cc
+++ b/src/ftrace_reader/cpu_reader.cc
@@ -215,41 +215,6 @@
 #endif
 }
 
-// static
-std::map<uint64_t, std::string> CpuReader::GetFilenamesForInodeNumbers(
-    const std::set<uint64_t>& inode_numbers) {
-  std::map<uint64_t, std::string> inode_to_filename;
-  if (inode_numbers.empty())
-    return inode_to_filename;
-  std::queue<std::string> queue;
-  // Starts reading files from current directory
-  queue.push(".");
-  while (!queue.empty()) {
-    struct dirent* entry;
-    std::string filepath = queue.front();
-    filepath += "/";
-    DIR* dir = opendir(queue.front().c_str());
-    queue.pop();
-    if (dir == nullptr)
-      continue;
-    while ((entry = readdir(dir)) != nullptr) {
-      std::string filename = entry->d_name;
-      if (filename.compare(".") == 0 || filename.compare("..") == 0)
-        continue;
-      uint64_t inode_number = entry->d_ino;
-      // Check if this inode number matches any of the passed in inode
-      // numbers from events
-      if (inode_numbers.find(inode_number) != inode_numbers.end())
-        inode_to_filename.emplace(inode_number, filepath + filename);
-      // Continue iterating through files if current entry is a directory
-      if (entry->d_type == DT_DIR)
-        queue.push(filepath + filename);
-    }
-    closedir(dir);
-  }
-  return inode_to_filename;
-}
-
 bool CpuReader::Drain(const std::array<const EventFilter*, kMaxSinks>& filters,
                       const std::array<BundleHandle, kMaxSinks>& bundles,
                       const std::array<FtraceMetadata*, kMaxSinks>& metadatas) {
@@ -385,6 +350,9 @@
         const uint8_t* start = ptr;
         const uint8_t* next = ptr + event_size;
 
+        if (next > end)
+          return 0;
+
         uint16_t ftrace_event_id;
         if (!ReadAndAdvance<uint16_t>(&ptr, end, &ftrace_event_id))
           return 0;
@@ -456,7 +424,11 @@
 
   switch (field.strategy) {
     case kUint8ToUint32:
+      ReadIntoVarInt<uint8_t>(field_start, field_id, message);
+      return true;
     case kUint16ToUint32:
+      ReadIntoVarInt<uint16_t>(field_start, field_id, message);
+      return true;
     case kUint32ToUint32:
     case kUint32ToUint64:
       ReadIntoVarInt<uint32_t>(field_start, field_id, message);
@@ -465,7 +437,11 @@
       ReadIntoVarInt<uint64_t>(field_start, field_id, message);
       return true;
     case kInt8ToInt32:
+      ReadIntoVarInt<int8_t>(field_start, field_id, message);
+      return true;
     case kInt16ToInt32:
+      ReadIntoVarInt<int16_t>(field_start, field_id, message);
+      return true;
     case kInt32ToInt32:
     case kInt32ToInt64:
       ReadIntoVarInt<int32_t>(field_start, field_id, message);
diff --git a/src/ftrace_reader/cpu_reader.h b/src/ftrace_reader/cpu_reader.h
index e320ac6..d88c039 100644
--- a/src/ftrace_reader/cpu_reader.h
+++ b/src/ftrace_reader/cpu_reader.h
@@ -166,14 +166,6 @@
         (((min)&0xffffff00ULL) << 12) | (((min)&0xffULL)));
   }
 
-  // Iterate through every file in the current directory and check if the inode
-  // number of each file matches any of the inode numbers saved in events.
-  // Returns map of inode number to filename for every inode number that is
-  // found in the filesystem. If the inode number saved from events is not
-  // found, nothing is added to the map.
-  static std::map<uint64_t, std::string> GetFilenamesForInodeNumbers(
-      const std::set<uint64_t>& inode_numbers);
-
   // Parse a raw ftrace page beginning at ptr and write the events a protos
   // into the provided bundle respecting the given event filter.
   // |table| contains the mix of compile time (e.g. proto field ids) and
diff --git a/src/traced/probes/filesystem/inode_file_data_source.cc b/src/traced/probes/filesystem/inode_file_data_source.cc
index fd70ff7..cc4c34c 100644
--- a/src/traced/probes/filesystem/inode_file_data_source.cc
+++ b/src/traced/probes/filesystem/inode_file_data_source.cc
@@ -36,6 +36,7 @@
 constexpr uint64_t kScanIntervalMs = 10000;  // 10s
 constexpr uint64_t kScanDelayMs = 10000;     // 10s
 constexpr uint64_t kScanBatchSize = 15000;
+constexpr uint64_t kFlushBeforeEndMs = 500;
 
 uint64_t OrDefault(uint64_t value, uint64_t def) {
   if (value != 0)
@@ -126,7 +127,22 @@
       static_file_map_(static_file_map),
       cache_(cache),
       writer_(std::move(writer)),
-      weak_factory_(this) {}
+      weak_factory_(this) {
+  auto weak_this = GetWeakPtr();
+  // Flush TracePacket of current scan shortly before we expect the trace
+  // to end, to retain information from any scan that might be in
+  // progress.
+  task_runner_->PostDelayedTask(
+      [weak_this] {
+        if (!weak_this) {
+          PERFETTO_DLOG("Giving up flush.");
+          return;
+        }
+        PERFETTO_DLOG("Flushing.");
+        weak_this->ResetTracePacket();
+      },
+      source_config_.trace_duration_ms() - kFlushBeforeEndMs);
+}
 
 void InodeFileDataSource::AddInodesFromStaticMap(
     BlockDeviceID block_device_id,
@@ -296,13 +312,17 @@
   return !missing_inodes_.empty();
 }
 
-void InodeFileDataSource::OnInodeScanDone() {
-  // Finalize the accumulated trace packets.
+void InodeFileDataSource::ResetTracePacket() {
   current_block_device_id_ = 0;
   current_file_map_ = nullptr;
   if (has_current_trace_packet_)
     current_trace_packet_->Finalize();
   has_current_trace_packet_ = false;
+}
+
+void InodeFileDataSource::OnInodeScanDone() {
+  // Finalize the accumulated trace packets.
+  ResetTracePacket();
   file_scanner_.reset();
   if (next_missing_inodes_.empty()) {
     scan_running_ = false;
diff --git a/src/traced/probes/filesystem/inode_file_data_source.h b/src/traced/probes/filesystem/inode_file_data_source.h
index 1f4197f..1282c53 100644
--- a/src/traced/probes/filesystem/inode_file_data_source.h
+++ b/src/traced/probes/filesystem/inode_file_data_source.h
@@ -88,6 +88,7 @@
 
  private:
   InodeFileMap* AddToCurrentTracePacket(BlockDeviceID block_device_id);
+  void ResetTracePacket();
   void FindMissingInodes();
   bool OnInodeFound(BlockDeviceID block_device_id,
                     Inode inode_number,