Implemented thread enumeration on linux.

develop
Petr Mrázek 2011-05-09 01:55:02 +02:00
parent 04fd951e64
commit abc473db5d
3 changed files with 41 additions and 4 deletions

@ -22,8 +22,10 @@ must not be misrepresented as being the original software.
distribution. distribution.
*/ */
#include "Internal.h" #include "Internal.h"
#include "PlatformInternal.h"
#include <string> #include <string>
#include <cstring>
#include <vector> #include <vector>
#include <map> #include <map>
#include <cstdio> #include <cstdio>
@ -76,11 +78,44 @@ int LinuxProcessBase::getPID()
return my_pid; return my_pid;
} }
//FIXME: implement int getdir (string dir, vector<string> &files)
{
DIR *dp;
struct dirent *dirp;
if((dp = opendir(dir.c_str())) == NULL) {
cout << "Error(" << errno << ") opening " << dir << endl;
return errno;
}
while ((dirp = readdir(dp)) != NULL) {
files.push_back(string(dirp->d_name));
}
closedir(dp);
return 0;
}
bool LinuxProcessBase::getThreadIDs(vector<uint32_t> & threads ) bool LinuxProcessBase::getThreadIDs(vector<uint32_t> & threads )
{ {
stringstream ss;
vector<string> subdirs;
ss << "/proc/" << my_pid << "/task/";
if(getdir(ss.str(),subdirs) != 0)
{
//FIXME: needs exceptions. this is a fatal error
cerr << "unable to enumerate threads. This is BAD!" << endl;
return false; return false;
} }
threads.clear();
for(int i = 0; i < subdirs.size();i++)
{
uint32_t tid;
if(sscanf(subdirs[i].c_str(),"%d", &tid))
{
threads.push_back(tid);
}
}
return true;
}
//FIXME: cross-reference with ELF segment entries? //FIXME: cross-reference with ELF segment entries?
void LinuxProcessBase::getMemRanges( vector<t_memrange> & ranges ) void LinuxProcessBase::getMemRanges( vector<t_memrange> & ranges )

@ -45,6 +45,7 @@ namespace {
{ {
private: private:
uint8_t vector_start; uint8_t vector_start;
vector <uint32_t> thread_ids;
public: public:
NormalProcess(uint32_t pid, VersionInfoFactory * known_versions); NormalProcess(uint32_t pid, VersionInfoFactory * known_versions);
~NormalProcess() ~NormalProcess()
@ -128,7 +129,7 @@ struct _Rep_base
{ {
uint32_t _M_length; // length of text stored, not including zero termination uint32_t _M_length; // length of text stored, not including zero termination
uint32_t _M_capacity; // capacity, not including zero termination uint32_t _M_capacity; // capacity, not including zero termination
uint32_t _M_refcount; // reference count (two STL strings can share a common buffer, copy on write rules apply) int32_t _M_refcount; // reference count (two STL strings can share a common buffer, copy on write rules apply)
}; };
size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) size_t NormalProcess::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity)
@ -153,7 +154,7 @@ size_t NormalProcess::writeSTLString(const uint32_t address, const std::string w
// the buffer has actual size = 1. no space for storing anything more than a zero byte // the buffer has actual size = 1. no space for storing anything more than a zero byte
if(header._M_capacity == 0) if(header._M_capacity == 0)
return 0; return 0;
if(header._M_refcount != 0 && header._M_refcount != 0xFFFFFFFF ) // one ref or one non-shareable ref if(header._M_refcount > 0 ) // one ref or one non-shareable (-1) ref
return 0; return 0;
// get writeable length (lesser of our string length and capacity of the target) // get writeable length (lesser of our string length and capacity of the target)

@ -34,6 +34,7 @@
#include <dirent.h> #include <dirent.h>
#include <unistd.h> #include <unistd.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <syscall.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/wait.h> #include <sys/wait.h>
#else #else