[Lldb-commits] [lldb] r212015 - Factored out Linux proc file reading into separate class.
Todd Fiala
todd.fiala at gmail.com
Sun Jun 29 21:14:13 PDT 2014
Author: tfiala
Date: Sun Jun 29 23:14:13 2014
New Revision: 212015
URL: http://llvm.org/viewvc/llvm-project?rev=212015&view=rev
Log:
Factored out Linux proc file reading into separate class.
Both NativeProcessLinux (in llgs branch) and Linux Host.cpp had similar code to handle /proc
file reading. I factored that out into a new Linux-specific ProcFileReader class and added a method
that the llgs branch will use for line-by-line parsing.
This change also adds numerous Linux-specific files to Xcode that were missing from the Xcode
project files.
Related to https://github.com/tfiala/lldb/issues/27
Added:
lldb/trunk/source/Plugins/Process/Linux/ProcFileReader.cpp
lldb/trunk/source/Plugins/Process/Linux/ProcFileReader.h
Modified:
lldb/trunk/lldb.xcodeproj/project.pbxproj
lldb/trunk/source/Host/linux/Host.cpp
lldb/trunk/source/Plugins/Process/Linux/CMakeLists.txt
Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=212015&r1=212014&r2=212015&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Sun Jun 29 23:14:13 2014
@@ -55,6 +55,14 @@
23059A121958B3B2007B8189 /* SBUnixSignals.h in Headers */ = {isa = PBXBuildFile; fileRef = 23059A111958B37B007B8189 /* SBUnixSignals.h */; settings = {ATTRIBUTES = (Public, ); }; };
233B007D1960C9F90090E598 /* ProcessInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B007B1960C9E60090E598 /* ProcessInfo.cpp */; };
233B007F1960CB280090E598 /* ProcessLaunchInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B007E1960CB280090E598 /* ProcessLaunchInfo.cpp */; };
+ 233B009419610B1F0090E598 /* LinuxSignals.cpp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 233B008C19610B1F0090E598 /* LinuxSignals.cpp */; };
+ 233B009519610B1F0090E598 /* LinuxSignals.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 233B008D19610B1F0090E598 /* LinuxSignals.h */; };
+ 233B009619610B1F0090E598 /* LinuxThread.cpp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 233B008E19610B1F0090E598 /* LinuxThread.cpp */; };
+ 233B009719610B1F0090E598 /* LinuxThread.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 233B008F19610B1F0090E598 /* LinuxThread.h */; };
+ 233B009819610B1F0090E598 /* ProcessLinux.cpp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 233B009019610B1F0090E598 /* ProcessLinux.cpp */; };
+ 233B009919610B1F0090E598 /* ProcessLinux.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 233B009119610B1F0090E598 /* ProcessLinux.h */; };
+ 233B009A19610B1F0090E598 /* ProcessMonitor.cpp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 233B009219610B1F0090E598 /* ProcessMonitor.cpp */; };
+ 233B009B19610B1F0090E598 /* ProcessMonitor.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 233B009319610B1F0090E598 /* ProcessMonitor.h */; };
23EFE389193D1ABC00E54E54 /* SBTypeEnumMember.h in Headers */ = {isa = PBXBuildFile; fileRef = 23EFE388193D1ABC00E54E54 /* SBTypeEnumMember.h */; settings = {ATTRIBUTES = (Public, ); }; };
23EFE38B193D1AEC00E54E54 /* SBTypeEnumMember.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23EFE38A193D1AEC00E54E54 /* SBTypeEnumMember.cpp */; };
260157C61885F51C00F875CF /* libpanel.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 260157C41885F4FF00F875CF /* libpanel.dylib */; };
@@ -853,6 +861,14 @@
dstPath = "$(DEVELOPER_DIR)/usr/share/man/man1/";
dstSubfolderSpec = 0;
files = (
+ 233B009819610B1F0090E598 /* ProcessLinux.cpp in CopyFiles */,
+ 233B009619610B1F0090E598 /* LinuxThread.cpp in CopyFiles */,
+ 233B009A19610B1F0090E598 /* ProcessMonitor.cpp in CopyFiles */,
+ 233B009719610B1F0090E598 /* LinuxThread.h in CopyFiles */,
+ 233B009919610B1F0090E598 /* ProcessLinux.h in CopyFiles */,
+ 233B009B19610B1F0090E598 /* ProcessMonitor.h in CopyFiles */,
+ 233B009419610B1F0090E598 /* LinuxSignals.cpp in CopyFiles */,
+ 233B009519610B1F0090E598 /* LinuxSignals.h in CopyFiles */,
AF90106515AB7D3600FF120D /* lldb.1 in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 1;
@@ -881,6 +897,17 @@
233B007A1960A0440090E598 /* ProcessInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ProcessInfo.h; path = include/lldb/Target/ProcessInfo.h; sourceTree = "<group>"; };
233B007B1960C9E60090E598 /* ProcessInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProcessInfo.cpp; path = source/Target/ProcessInfo.cpp; sourceTree = "<group>"; };
233B007E1960CB280090E598 /* ProcessLaunchInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProcessLaunchInfo.cpp; path = source/Target/ProcessLaunchInfo.cpp; sourceTree = "<group>"; };
+ 233B008C19610B1F0090E598 /* LinuxSignals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LinuxSignals.cpp; sourceTree = "<group>"; };
+ 233B008D19610B1F0090E598 /* LinuxSignals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinuxSignals.h; sourceTree = "<group>"; };
+ 233B008E19610B1F0090E598 /* LinuxThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LinuxThread.cpp; sourceTree = "<group>"; };
+ 233B008F19610B1F0090E598 /* LinuxThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinuxThread.h; sourceTree = "<group>"; };
+ 233B009019610B1F0090E598 /* ProcessLinux.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessLinux.cpp; sourceTree = "<group>"; };
+ 233B009119610B1F0090E598 /* ProcessLinux.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProcessLinux.h; sourceTree = "<group>"; };
+ 233B009219610B1F0090E598 /* ProcessMonitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessMonitor.cpp; sourceTree = "<group>"; };
+ 233B009319610B1F0090E598 /* ProcessMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProcessMonitor.h; sourceTree = "<group>"; };
+ 233B009D19610D6B0090E598 /* Host.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Host.cpp; sourceTree = "<group>"; };
+ 233B00A1196113730090E598 /* ProcFileReader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ProcFileReader.cpp; sourceTree = "<group>"; };
+ 233B00A2196113730090E598 /* ProcFileReader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ProcFileReader.h; sourceTree = "<group>"; };
2360092C193FB21500189DB1 /* MemoryRegionInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MemoryRegionInfo.h; path = include/lldb/Target/MemoryRegionInfo.h; sourceTree = "<group>"; };
23EDE3371926AAD500F6A132 /* RegisterInfoInterface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RegisterInfoInterface.h; path = Utility/RegisterInfoInterface.h; sourceTree = "<group>"; };
23EFE388193D1ABC00E54E54 /* SBTypeEnumMember.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBTypeEnumMember.h; path = include/lldb/API/SBTypeEnumMember.h; sourceTree = "<group>"; };
@@ -2156,6 +2183,32 @@
sourceTree = "<group>";
usesTabs = 0;
};
+ 233B008B196106E90090E598 /* Linux */ = {
+ isa = PBXGroup;
+ children = (
+ 233B008C19610B1F0090E598 /* LinuxSignals.cpp */,
+ 233B008D19610B1F0090E598 /* LinuxSignals.h */,
+ 233B008E19610B1F0090E598 /* LinuxThread.cpp */,
+ 233B008F19610B1F0090E598 /* LinuxThread.h */,
+ 233B009019610B1F0090E598 /* ProcessLinux.cpp */,
+ 233B009119610B1F0090E598 /* ProcessLinux.h */,
+ 233B009219610B1F0090E598 /* ProcessMonitor.cpp */,
+ 233B009319610B1F0090E598 /* ProcessMonitor.h */,
+ 233B00A2196113730090E598 /* ProcFileReader.h */,
+ 233B00A1196113730090E598 /* ProcFileReader.cpp */,
+ );
+ path = Linux;
+ sourceTree = "<group>";
+ };
+ 233B009C19610D130090E598 /* linux */ = {
+ isa = PBXGroup;
+ children = (
+ 233B009D19610D6B0090E598 /* Host.cpp */,
+ );
+ name = linux;
+ path = source/Host/linux;
+ sourceTree = "<group>";
+ };
260C897110F57C5600BB2B04 /* Plugins */ = {
isa = PBXGroup;
children = (
@@ -2270,6 +2323,7 @@
children = (
26BC179F18C7F4CB00D2196D /* elf-core */,
4CEE62F71145F1C70064CF93 /* GDB Remote */,
+ 233B008B196106E90090E598 /* Linux */,
2642FBA713D003B400ED6808 /* MacOSX-Kernel */,
26A527BC14E24F5F00F3A14A /* mach-core */,
26BC17B318C7F4FA00D2196D /* POSIX */,
@@ -3311,6 +3365,7 @@
isa = PBXGroup;
children = (
69A01E1A1236C5D400C660B5 /* common */,
+ 233B009C19610D130090E598 /* linux */,
26BC7EE510F1B88100F91463 /* MacOSX */,
26BC7DD210F1B7D500F91463 /* Condition.h */,
266F5CBB12FC846200DFCE33 /* Config.h */,
Modified: lldb/trunk/source/Host/linux/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/linux/Host.cpp?rev=212015&r1=212014&r2=212015&view=diff
==============================================================================
--- lldb/trunk/source/Host/linux/Host.cpp (original)
+++ lldb/trunk/source/Host/linux/Host.cpp Sun Jun 29 23:14:13 2014
@@ -29,6 +29,7 @@
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "Plugins/Process/Linux/ProcFileReader.h"
using namespace lldb;
using namespace lldb_private;
@@ -52,67 +53,11 @@ typedef struct ProcessStatInfo
// Get the process info with additional information from /proc/$PID/stat (like process state, and tracer pid).
static bool GetProcessAndStatInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info, ProcessStatInfo &stat_info, lldb::pid_t &tracerpid);
-
-namespace
-{
-
-lldb::DataBufferSP
-ReadProcPseudoFile (lldb::pid_t pid, const char *name)
-{
- int fd;
- char path[PATH_MAX];
-
- // Make sure we've got a nil terminated buffer for all the folks calling
- // GetBytes() directly off our returned DataBufferSP if we hit an error.
- lldb::DataBufferSP buf_sp (new DataBufferHeap(1, 0));
-
- // Ideally, we would simply create a FileSpec and call ReadFileContents.
- // However, files in procfs have zero size (since they are, in general,
- // dynamically generated by the kernel) which is incompatible with the
- // current ReadFileContents implementation. Therefore we simply stream the
- // data into a DataBuffer ourselves.
- if (snprintf (path, PATH_MAX, "/proc/%" PRIu64 "/%s", pid, name) > 0)
- {
- if ((fd = open (path, O_RDONLY, 0)) >= 0)
- {
- size_t bytes_read = 0;
- std::unique_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));
-
- for (;;)
- {
- size_t avail = buf_ap->GetByteSize() - bytes_read;
- ssize_t status = read (fd, buf_ap->GetBytes() + bytes_read, avail);
-
- if (status < 0)
- break;
-
- if (status == 0)
- {
- buf_ap->SetByteSize (bytes_read);
- buf_sp.reset (buf_ap.release());
- break;
- }
-
- bytes_read += status;
-
- if (avail - status == 0)
- buf_ap->SetByteSize (2 * buf_ap->GetByteSize());
- }
-
- close (fd);
- }
- }
-
- return buf_sp;
-}
-
-} // anonymous namespace
-
static bool
ReadProcPseudoFileStat (lldb::pid_t pid, ProcessStatInfo& stat_info)
{
// Read the /proc/$PID/stat file.
- lldb::DataBufferSP buf_sp = ReadProcPseudoFile (pid, "stat");
+ lldb::DataBufferSP buf_sp = ProcFileReader::ReadIntoDataBuffer (pid, "stat");
// The filename of the executable is stored in parenthesis right after the pid. We look for the closing
// parenthesis for the filename and work from there in case the name has something funky like ')' in it.
@@ -165,7 +110,7 @@ GetLinuxProcessUserAndGroup (lldb::pid_t
uint32_t eGid = UINT32_MAX; // Effective Group ID
// Read the /proc/$PID/status file and parse the Uid:, Gid:, and TracerPid: fields.
- lldb::DataBufferSP buf_sp = ReadProcPseudoFile (pid, "status");
+ lldb::DataBufferSP buf_sp = ProcFileReader::ReadIntoDataBuffer (pid, "status");
static const char uid_token[] = "Uid:";
char *buf_uid = strstr ((char *)buf_sp->GetBytes(), uid_token);
@@ -227,7 +172,7 @@ Host::GetOSVersion(uint32_t &major,
lldb::DataBufferSP
Host::GetAuxvData(lldb_private::Process *process)
{
- return ReadProcPseudoFile(process->GetID(), "auxv");
+ return ProcFileReader::ReadIntoDataBuffer (process->GetID(), "auxv");
}
static bool
@@ -391,7 +336,7 @@ GetProcessAndStatInfo (lldb::pid_t pid,
lldb::DataBufferSP buf_sp;
// Get the process environment.
- buf_sp = ReadProcPseudoFile(pid, "environ");
+ buf_sp = ProcFileReader::ReadIntoDataBuffer(pid, "environ");
Args &info_env = process_info.GetEnvironmentEntries();
char *next_var = (char *)buf_sp->GetBytes();
char *end_buf = next_var + buf_sp->GetByteSize();
@@ -402,7 +347,7 @@ GetProcessAndStatInfo (lldb::pid_t pid,
}
// Get the commond line used to start the process.
- buf_sp = ReadProcPseudoFile(pid, "cmdline");
+ buf_sp = ProcFileReader::ReadIntoDataBuffer(pid, "cmdline");
// Grab Arg0 first, if there is one.
char *cmd = (char *)buf_sp->GetBytes();
@@ -458,7 +403,7 @@ Host::GetThreadName (lldb::pid_t pid, ll
assert(tid != LLDB_INVALID_THREAD_ID);
// Read /proc/$TID/comm file.
- lldb::DataBufferSP buf_sp = ReadProcPseudoFile (tid, "comm");
+ lldb::DataBufferSP buf_sp = ProcFileReader::ReadIntoDataBuffer (tid, "comm");
const char *comm_str = (const char *)buf_sp->GetBytes();
const char *cr_str = ::strchr(comm_str, '\n');
size_t length = cr_str ? (cr_str - comm_str) : strlen(comm_str);
Modified: lldb/trunk/source/Plugins/Process/Linux/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/CMakeLists.txt?rev=212015&r1=212014&r2=212015&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/Process/Linux/CMakeLists.txt Sun Jun 29 23:14:13 2014
@@ -7,6 +7,7 @@ include_directories(../Utility)
add_lldb_library(lldbPluginProcessLinux
ProcessLinux.cpp
ProcessMonitor.cpp
+ ProcFileReader.cpp
LinuxSignals.cpp
LinuxThread.cpp
)
Added: lldb/trunk/source/Plugins/Process/Linux/ProcFileReader.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/ProcFileReader.cpp?rev=212015&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ProcFileReader.cpp (added)
+++ lldb/trunk/source/Plugins/Process/Linux/ProcFileReader.cpp Sun Jun 29 23:14:13 2014
@@ -0,0 +1,105 @@
+//===-- ProcFileReader.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/Process/Linux/ProcFileReader.h"
+
+// C Headers
+#include <fcntl.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdio.h>
+#include <sys/stat.h>
+
+// C++ Headers
+#include <fstream>
+
+// LLDB Headers
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+
+lldb::DataBufferSP
+lldb_private::ProcFileReader::ReadIntoDataBuffer (lldb::pid_t pid, const char *name)
+{
+ int fd;
+ char path[PATH_MAX];
+
+ // Make sure we've got a nil terminated buffer for all the folks calling
+ // GetBytes() directly off our returned DataBufferSP if we hit an error.
+ lldb::DataBufferSP buf_sp (new DataBufferHeap(1, 0));
+
+ // Ideally, we would simply create a FileSpec and call ReadFileContents.
+ // However, files in procfs have zero size (since they are, in general,
+ // dynamically generated by the kernel) which is incompatible with the
+ // current ReadFileContents implementation. Therefore we simply stream the
+ // data into a DataBuffer ourselves.
+ if (snprintf (path, PATH_MAX, "/proc/%" PRIu64 "/%s", pid, name) > 0)
+ {
+ if ((fd = open (path, O_RDONLY, 0)) >= 0)
+ {
+ size_t bytes_read = 0;
+ std::unique_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(1024, 0));
+
+ for (;;)
+ {
+ size_t avail = buf_ap->GetByteSize() - bytes_read;
+ ssize_t status = read (fd, buf_ap->GetBytes() + bytes_read, avail);
+
+ if (status < 0)
+ break;
+
+ if (status == 0)
+ {
+ buf_ap->SetByteSize (bytes_read);
+ buf_sp.reset (buf_ap.release());
+ break;
+ }
+
+ bytes_read += status;
+
+ if (avail - status == 0)
+ buf_ap->SetByteSize (2 * buf_ap->GetByteSize());
+ }
+
+ close (fd);
+ }
+ }
+
+ return buf_sp;
+}
+
+lldb_private::Error
+lldb_private::ProcFileReader::ProcessLineByLine (lldb::pid_t pid, const char *name, std::function<bool (const std::string &line)> line_parser)
+{
+ lldb_private::Error error;
+
+ // Try to open the /proc/{pid}/maps entry.
+ char filename [PATH_MAX];
+ snprintf (filename, sizeof(filename), "/proc/%" PRIu64 "/%s", pid, name);
+ filename[sizeof (filename) - 1] = '\0';
+
+ std::ifstream proc_file (filename);
+ if (proc_file.fail ())
+ {
+ error.SetErrorStringWithFormat ("failed to open file '%s'", filename);
+ return error;
+ }
+
+ // Read the file line by line, processing until either end of file or when the line_parser returns false.
+ std::string line;
+ bool should_continue = true;
+
+ while (should_continue && std::getline (proc_file, line))
+ {
+ // Pass the line over to the line_parser for processing. If the line_parser returns false, we
+ // stop processing.
+ should_continue = line_parser (line);
+ }
+
+ return error;
+}
Added: lldb/trunk/source/Plugins/Process/Linux/ProcFileReader.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/ProcFileReader.h?rev=212015&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ProcFileReader.h (added)
+++ lldb/trunk/source/Plugins/Process/Linux/ProcFileReader.h Sun Jun 29 23:14:13 2014
@@ -0,0 +1,34 @@
+//===-- ProcFileReader.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ProcFileReader_h_
+#define liblldb_ProcFileReader_h_
+
+#include <functional>
+
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
+
+namespace lldb_private
+{
+ class ProcFileReader
+ {
+ public:
+
+ static lldb::DataBufferSP
+ ReadIntoDataBuffer (lldb::pid_t pid, const char *name);
+
+ /// Parse the /proc/{@a pid}/{@a name} file line by line, passing each line to line_parser, until
+ /// either end of file or until line_parser returns false.
+ static lldb_private::Error
+ ProcessLineByLine (lldb::pid_t pid, const char *name, std::function<bool (const std::string &line)> line_parser);
+ };
+}
+
+#endif // #ifndef liblldb_ProcFileReader_h_
More information about the lldb-commits
mailing list