1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-22 00:15:08 +00:00

Allow processes to go into a BeingInspected state (used by procfs.)

This ensures that the process won't get scheduled, and so inspecting
it is safe and easy without blocking interrupts.
This commit is contained in:
Andreas Kling 2018-11-01 14:21:02 +01:00
parent dfaa2b6b02
commit 52607aa086
3 changed files with 37 additions and 19 deletions

View file

@ -27,8 +27,9 @@ ProcFileSystem::~ProcFileSystem()
{ {
} }
ByteBuffer procfs$pid_fds(const Process& process) ByteBuffer procfs$pid_fds(Process& process)
{ {
ProcessInspectionScope scope(process);
char* buffer; char* buffer;
auto stringImpl = StringImpl::createUninitialized(process.number_of_open_file_descriptors() * 80, buffer); auto stringImpl = StringImpl::createUninitialized(process.number_of_open_file_descriptors() * 80, buffer);
memset(buffer, 0, stringImpl->length()); memset(buffer, 0, stringImpl->length());
@ -43,9 +44,9 @@ ByteBuffer procfs$pid_fds(const Process& process)
return ByteBuffer::copy((byte*)buffer, ptr - buffer); return ByteBuffer::copy((byte*)buffer, ptr - buffer);
} }
ByteBuffer procfs$pid_vm(const Process& process) ByteBuffer procfs$pid_vm(Process& process)
{ {
InterruptDisabler disabler; ProcessInspectionScope scope(process);
char* buffer; char* buffer;
auto stringImpl = StringImpl::createUninitialized(80 + process.regionCount() * 80 + 80 + process.subregionCount() * 80, buffer); auto stringImpl = StringImpl::createUninitialized(80 + process.regionCount() * 80 + 80 + process.subregionCount() * 80, buffer);
memset(buffer, 0, stringImpl->length()); memset(buffer, 0, stringImpl->length());
@ -76,7 +77,7 @@ ByteBuffer procfs$pid_vm(const Process& process)
ByteBuffer procfs$pid_stack(Process& process) ByteBuffer procfs$pid_stack(Process& process)
{ {
InterruptDisabler disabler; ProcessInspectionScope scope(process);
OtherProcessPagingScope pagingScope(process); OtherProcessPagingScope pagingScope(process);
struct RecognizedSymbol { struct RecognizedSymbol {
dword address; dword address;
@ -108,11 +109,8 @@ ByteBuffer procfs$pid_stack(Process& process)
ByteBuffer procfs$pid_exe(Process& process) ByteBuffer procfs$pid_exe(Process& process)
{ {
InodeIdentifier inode; ProcessInspectionScope scope(process);
{ auto inode = process.executableInode();
InterruptDisabler disabler;
inode = process.executableInode();
}
return VirtualFileSystem::the().absolutePath(inode).toByteBuffer(); return VirtualFileSystem::the().absolutePath(inode).toByteBuffer();
} }
@ -201,6 +199,7 @@ static const char* toString(Process::State state)
case Process::BlockedSleep: return "Sleep"; case Process::BlockedSleep: return "Sleep";
case Process::BlockedWait: return "Wait"; case Process::BlockedWait: return "Wait";
case Process::BlockedRead: return "Read"; case Process::BlockedRead: return "Read";
case Process::BeingInspected: return "Inspect";
} }
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
return nullptr; return nullptr;

View file

@ -533,7 +533,7 @@ void Process::sys$exit(int status)
kprintf("sys$exit: %s(%u) exit with status %d\n", name().characters(), pid(), status); kprintf("sys$exit: %s(%u) exit with status %d\n", name().characters(), pid(), status);
#endif #endif
setState(Exiting); set_state(Exiting);
s_processes->remove(this); s_processes->remove(this);
@ -553,7 +553,7 @@ void Process::murder(int signal)
{ {
ASSERT_INTERRUPTS_DISABLED(); ASSERT_INTERRUPTS_DISABLED();
bool wasCurrent = current == this; bool wasCurrent = current == this;
setState(Exiting); set_state(Exiting);
s_processes->remove(this); s_processes->remove(this);
notify_waiters(m_pid, 0, signal); notify_waiters(m_pid, 0, signal);
@ -579,7 +579,7 @@ void Process::processDidCrash(Process* crashedProcess)
HANG; HANG;
} }
crashedProcess->setState(Crashing); crashedProcess->set_state(Crashing);
crashedProcess->dumpRegions(); crashedProcess->dumpRegions();
s_processes->remove(crashedProcess); s_processes->remove(crashedProcess);
@ -741,11 +741,11 @@ static bool contextSwitch(Process* t)
// If the last process hasn't blocked (still marked as running), // If the last process hasn't blocked (still marked as running),
// mark it as runnable for the next round. // mark it as runnable for the next round.
if (current->state() == Process::Running) if (current->state() == Process::Running)
current->setState(Process::Runnable); current->set_state(Process::Runnable);
} }
current = t; current = t;
t->setState(Process::Running); t->set_state(Process::Running);
if (!t->selector()) { if (!t->selector()) {
t->setSelector(allocateGDTEntry()); t->setSelector(allocateGDTEntry());
@ -1074,7 +1074,7 @@ void Process::block(Process::State state)
{ {
ASSERT(current->state() == Process::Running); ASSERT(current->state() == Process::Running);
system.nblocked++; system.nblocked++;
current->setState(state); current->set_state(state);
} }
void block(Process::State state) void block(Process::State state)

View file

@ -30,9 +30,10 @@ public:
Terminated = 3, Terminated = 3,
Crashing = 4, Crashing = 4,
Exiting = 5, Exiting = 5,
BlockedSleep = 6, BeingInspected = 6,
BlockedWait = 7, BlockedSleep = 7,
BlockedRead = 8, BlockedWait = 8,
BlockedRead = 9,
}; };
enum RingLevel { enum RingLevel {
@ -75,7 +76,7 @@ public:
void setTicksLeft(DWORD t) { m_ticksLeft = t; } void setTicksLeft(DWORD t) { m_ticksLeft = t; }
void setSelector(WORD s) { m_farPtr.selector = s; } void setSelector(WORD s) { m_farPtr.selector = s; }
void setState(State s) { m_state = s; } void set_state(State s) { m_state = s; }
uid_t sys$getuid(); uid_t sys$getuid();
gid_t sys$getgid(); gid_t sys$getgid();
@ -203,6 +204,24 @@ private:
Vector<String> m_initialEnvironment; Vector<String> m_initialEnvironment;
}; };
class ProcessInspectionScope {
public:
ProcessInspectionScope(Process& process)
: m_process(process)
, m_original_state(process.state())
{
m_process.set_state(Process::BeingInspected);
}
~ProcessInspectionScope()
{
m_process.set_state(m_original_state);
}
private:
Process& m_process;
Process::State m_original_state { Process::Invalid };
};
extern void yield(); extern void yield();
extern bool scheduleNewProcess(); extern bool scheduleNewProcess();
extern void switchNow(); extern void switchNow();