Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0f837fe8 authored by Yabin Cui's avatar Yabin Cui Committed by Gerrit Code Review
Browse files

Merge "libprocinfo: add functions reading process map file."

parents da6ab734 3841accb
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -91,7 +91,10 @@ cc_library {
                "libdexfile",
            ],

            static_libs: ["libcutils"],
            static_libs: [
                "libcutils",
                "libprocinfo",
            ],

            // libdexfile will eventually properly export headers, for now
            // include these directly.
+16 −24
Original line number Diff line number Diff line
@@ -28,6 +28,9 @@
#include <backtrace/Backtrace.h>
#include <backtrace/BacktraceMap.h>
#include <backtrace/backtrace_constants.h>
#if defined(__linux__)
#include <procinfo/process_map.h>
#endif

#include "thread_utils.h"

@@ -60,27 +63,19 @@ void BacktraceMap::FillIn(uint64_t addr, backtrace_map_t* map) {
  *map = {};
}

bool BacktraceMap::ParseLine(const char* line, backtrace_map_t* map) {
#if defined(__APPLE__)
static bool ParseLine(const char* line, backtrace_map_t* map) {
  uint64_t start;
  uint64_t end;
  char permissions[5];
  int name_pos;

#if defined(__APPLE__)
// Mac OS vmmap(1) output:
// __TEXT                 0009f000-000a1000 [    8K     8K] r-x/rwx SM=COW  /Volumes/android/dalvik-dev/out/host/darwin-x86/bin/libcorkscrew_test\n
// 012345678901234567890123456789012345678901234567890123456789
// 0         1         2         3         4         5
  if (sscanf(line, "%*21c %" SCNx64 "-%" SCNx64 " [%*13c] %3c/%*3c SM=%*3c  %n",
             &start, &end, permissions, &name_pos) != 3) {
#else
// Linux /proc/<pid>/maps lines:
// 6f000000-6f01e000 rwxp 00000000 00:0c 16389419   /system/lib/libcomposer.so\n
// 012345678901234567890123456789012345678901234567890123456789
// 0         1         2         3         4         5
  if (sscanf(line, "%" SCNx64 "-%" SCNx64 " %4s %*x %*x:%*x %*d %n",
             &start, &end, permissions, &name_pos) != 3) {
#endif
    return false;
  }

@@ -107,24 +102,15 @@ bool BacktraceMap::ParseLine(const char* line, backtrace_map_t* map) {
        map->flags, map->name.c_str());
  return true;
}
#endif  // defined(__APPLE__)

bool BacktraceMap::Build() {
#if defined(__APPLE__)
  char cmd[sizeof(pid_t)*3 + sizeof("vmmap -w -resident -submap -allSplitLibs -interleaved ") + 1];
#else
  char path[sizeof(pid_t)*3 + sizeof("/proc//maps") + 1];
#endif
  char line[1024];

#if defined(__APPLE__)
  // cmd is guaranteed to always be big enough to hold this string.
  snprintf(cmd, sizeof(cmd), "vmmap -w -resident -submap -allSplitLibs -interleaved %d", pid_);
  FILE* fp = popen(cmd, "r");
#else
  // path is guaranteed to always be big enough to hold this string.
  snprintf(path, sizeof(path), "/proc/%d/maps", pid_);
  FILE* fp = fopen(path, "r");
#endif
  if (fp == nullptr) {
    return false;
  }
@@ -135,13 +121,19 @@ bool BacktraceMap::Build() {
      maps_.push_back(map);
    }
  }
#if defined(__APPLE__)
  pclose(fp);
  return true;
#else
  fclose(fp);
  return android::procinfo::ReadProcessMaps(
      pid_, [&](uint64_t start, uint64_t end, uint16_t flags, uint64_t, const char* name) {
        maps_.resize(maps_.size() + 1);
        backtrace_map_t& map = maps_.back();
        map.start = start;
        map.end = end;
        map.flags = flags;
        map.name = name;
      });
#endif

  return true;
}

#if defined(__APPLE__)
+0 −2
Original line number Diff line number Diff line
@@ -169,8 +169,6 @@ public:

  virtual uint64_t GetLoadBias(size_t /* index */) { return 0; }

  virtual bool ParseLine(const char* line, backtrace_map_t* map);

  pid_t pid_;
  std::deque<backtrace_map_t> maps_;
  std::vector<std::string> suffixes_to_ignore_;
+1 −1
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ cc_library {
        "HeapWalker.cpp",
        "LeakFolding.cpp",
        "LeakPipe.cpp",
        "LineBuffer.cpp",
        "MemUnreachable.cpp",
        "ProcessMappings.cpp",
        "PtracerThread.cpp",
@@ -38,6 +37,7 @@ cc_library {

    static_libs: [
        "libc_malloc_debug_backtrace",
        "libprocinfo",
    ],
    // Only need this for arm since libc++ uses its own unwind code that
    // doesn't mix with the other default unwind code.

libmemunreachable/LineBuffer.cpp

deleted100644 → 0
+0 −66
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Copied from system/extras/memory_replay/LineBuffer.cpp
// TODO(ccross): find a way to share between libmemunreachable and memory_replay?

#include <errno.h>
#include <string.h>
#include <unistd.h>

#include "LineBuffer.h"

namespace android {

LineBuffer::LineBuffer(int fd, char* buffer, size_t buffer_len)
    : fd_(fd), buffer_(buffer), buffer_len_(buffer_len) {}

bool LineBuffer::GetLine(char** line, size_t* line_len) {
  while (true) {
    if (bytes_ > 0) {
      char* newline = reinterpret_cast<char*>(memchr(buffer_ + start_, '\n', bytes_));
      if (newline != nullptr) {
        *newline = '\0';
        *line = buffer_ + start_;
        start_ = newline - buffer_ + 1;
        bytes_ -= newline - *line + 1;
        *line_len = newline - *line;
        return true;
      }
    }
    if (start_ > 0) {
      // Didn't find anything, copy the current to the front of the buffer.
      memmove(buffer_, buffer_ + start_, bytes_);
      start_ = 0;
    }
    ssize_t bytes = TEMP_FAILURE_RETRY(read(fd_, buffer_ + bytes_, buffer_len_ - bytes_ - 1));
    if (bytes <= 0) {
      if (bytes_ > 0) {
        // The read data might not contain a nul terminator, so add one.
        buffer_[bytes_] = '\0';
        *line = buffer_ + start_;
        *line_len = bytes_;
        bytes_ = 0;
        start_ = 0;
        return true;
      }
      return false;
    }
    bytes_ += bytes;
  }
}

}  // namespace android
Loading