mirror of
https://git.freebsd.org/ports.git
synced 2025-07-05 11:29:15 -04:00
141 lines
4.5 KiB
C++
141 lines
4.5 KiB
C++
--- base/debug/proc_maps_linux.cc.orig 2021-04-14 01:08:36 UTC
|
|
+++ base/debug/proc_maps_linux.cc
|
|
@@ -13,13 +13,18 @@
|
|
#include "base/strings/string_split.h"
|
|
#include "build/build_config.h"
|
|
|
|
-#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID)
|
|
+#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) || defined(OS_BSD)
|
|
#include <inttypes.h>
|
|
#endif
|
|
|
|
namespace base {
|
|
namespace debug {
|
|
|
|
+#if defined(OS_BSD)
|
|
+const char kProcSelfMapsPath[] = "/proc/curproc/map";
|
|
+#else
|
|
+const char kProcSelfMapsPath[] = "/proc/self/maps";
|
|
+
|
|
// Scans |proc_maps| starting from |pos| returning true if the gate VMA was
|
|
// found, otherwise returns false.
|
|
static bool ContainsGateVMA(std::string* proc_maps, size_t pos) {
|
|
@@ -35,15 +40,16 @@ static bool ContainsGateVMA(std::string* proc_maps, si
|
|
return false;
|
|
#endif
|
|
}
|
|
+#endif
|
|
|
|
bool ReadProcMaps(std::string* proc_maps) {
|
|
// seq_file only writes out a page-sized amount on each call. Refer to header
|
|
// file for details.
|
|
const long kReadSize = sysconf(_SC_PAGESIZE);
|
|
|
|
- base::ScopedFD fd(HANDLE_EINTR(open("/proc/self/maps", O_RDONLY)));
|
|
+ base::ScopedFD fd(HANDLE_EINTR(open(kProcSelfMapsPath, O_RDONLY)));
|
|
if (!fd.is_valid()) {
|
|
- DPLOG(ERROR) << "Couldn't open /proc/self/maps";
|
|
+ DPLOG(ERROR) << "Couldn't open " << kProcSelfMapsPath;
|
|
return false;
|
|
}
|
|
proc_maps->clear();
|
|
@@ -57,7 +63,7 @@ bool ReadProcMaps(std::string* proc_maps) {
|
|
|
|
ssize_t bytes_read = HANDLE_EINTR(read(fd.get(), buffer, kReadSize));
|
|
if (bytes_read < 0) {
|
|
- DPLOG(ERROR) << "Couldn't read /proc/self/maps";
|
|
+ DPLOG(ERROR) << "Couldn't read " << kProcSelfMapsPath;
|
|
proc_maps->clear();
|
|
return false;
|
|
}
|
|
@@ -68,6 +74,7 @@ bool ReadProcMaps(std::string* proc_maps) {
|
|
if (bytes_read == 0)
|
|
break;
|
|
|
|
+#if !defined(OS_BSD)
|
|
// The gate VMA is handled as a special case after seq_file has finished
|
|
// iterating through all entries in the virtual memory table.
|
|
//
|
|
@@ -78,6 +85,7 @@ bool ReadProcMaps(std::string* proc_maps) {
|
|
// Avoid this by searching for the gate VMA and breaking early.
|
|
if (ContainsGateVMA(proc_maps, pos))
|
|
break;
|
|
+#endif
|
|
}
|
|
|
|
return true;
|
|
@@ -105,11 +113,32 @@ bool ParseProcMaps(const std::string& input,
|
|
|
|
MappedMemoryRegion region;
|
|
const char* line = lines[i].c_str();
|
|
- char permissions[5] = {'\0'}; // Ensure NUL-terminated string.
|
|
+ char permissions[6] = {'\0'}; // Ensure NUL-terminated string.
|
|
+ int path_index = 0;
|
|
+
|
|
+#if defined(OS_BSD)
|
|
+ if (lines[i].empty())
|
|
+ continue;
|
|
+
|
|
+ char cow;
|
|
+
|
|
+ // Format:
|
|
+ //
|
|
+ // start end resident private_resident obj perms ref_count shadow_count flags cow needs_copy type fullpath cred ruid
|
|
+ // 0x200000 0x202000 2 6 0xfffff80005be9000 r-- 3 1 0x1000 COW NC vnode /bin/cat NCH -1
|
|
+ //
|
|
+ if (sscanf(line, "%" SCNxPTR " %" SCNxPTR " %*ld %*ld %*[^ ] %5[^ ] %*d %*d %*x %c%*s %*s %*s %n",
|
|
+ ®ion.start, ®ion.end, permissions, &cow, &path_index) < 4) {
|
|
+ DPLOG(WARNING) << "sscanf failed for line: " << line;
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ const char* fullpath = line + path_index;
|
|
+ const char* cred = strchr(fullpath, ' ');
|
|
+#else
|
|
uint8_t dev_major = 0;
|
|
uint8_t dev_minor = 0;
|
|
long inode = 0;
|
|
- int path_index = 0;
|
|
|
|
// Sample format from man 5 proc:
|
|
//
|
|
@@ -125,6 +154,7 @@ bool ParseProcMaps(const std::string& input,
|
|
DPLOG(WARNING) << "sscanf failed for line: " << line;
|
|
return false;
|
|
}
|
|
+#endif
|
|
|
|
region.permissions = 0;
|
|
|
|
@@ -143,14 +173,31 @@ bool ParseProcMaps(const std::string& input,
|
|
else if (permissions[2] != '-')
|
|
return false;
|
|
|
|
+#if defined(OS_BSD)
|
|
+ if (cow == 'C') {
|
|
+ region.permissions |= MappedMemoryRegion::PRIVATE;
|
|
+ } else if (cow != 'N') {
|
|
+ DPLOG(WARNING) << "unknown value for COW in line " << line << ": " << cow;
|
|
+ return false;
|
|
+ }
|
|
+#else
|
|
if (permissions[3] == 'p')
|
|
region.permissions |= MappedMemoryRegion::PRIVATE;
|
|
else if (permissions[3] != 's' && permissions[3] != 'S') // Shared memory.
|
|
return false;
|
|
+#endif
|
|
|
|
// Pushing then assigning saves us a string copy.
|
|
regions.push_back(region);
|
|
+#if defined(OS_BSD)
|
|
+ if (cred != nullptr) {
|
|
+ regions.back().path.assign(line + path_index, cred - fullpath);
|
|
+ } else {
|
|
+ regions.back().path.assign(line + path_index);
|
|
+ }
|
|
+#else
|
|
regions.back().path.assign(line + path_index);
|
|
+#endif
|
|
}
|
|
|
|
regions_out->swap(regions);
|