📄 fhandler_process.cc
字号:
if (p->process_state & (PID_ZOMBIE | PID_EXITED)) strcpy (cmd, "<defunct>"); else { strcpy (cmd, p->progname); char *last_slash = strrchr (cmd, '\\'); if (last_slash != NULL) strcpy (cmd, last_slash + 1); int len = strlen (cmd); if (len > 4) { char *s = cmd + len - 4; if (strcasecmp (s, ".exe") == 0) *s = 0; } } /* * Note: under Windows, a _process_ is always running - it's only _threads_ * that get suspended. Therefore the default state is R (runnable). */ if (p->process_state & PID_ZOMBIE) state = 'Z'; else if (p->process_state & PID_STOPPED) state = 'T'; else if (wincap.is_winnt ()) state = get_process_state (p->dwProcessId); if (wincap.is_winnt ()) { NTSTATUS ret; HANDLE hProcess; VM_COUNTERS vmc; KERNEL_USER_TIMES put; PROCESS_BASIC_INFORMATION pbi; QUOTA_LIMITS ql; SYSTEM_TIME_OF_DAY_INFORMATION stodi; SYSTEM_PROCESSOR_TIMES spt; hProcess = OpenProcess (PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, p->dwProcessId); if (hProcess != NULL) { ret = NtQueryInformationProcess (hProcess, ProcessVmCounters, (PVOID) &vmc, sizeof vmc, NULL); if (ret == STATUS_SUCCESS) ret = NtQueryInformationProcess (hProcess, ProcessTimes, (PVOID) &put, sizeof put, NULL); if (ret == STATUS_SUCCESS) ret = NtQueryInformationProcess (hProcess, ProcessBasicInformation, (PVOID) &pbi, sizeof pbi, NULL); if (ret == STATUS_SUCCESS) ret = NtQueryInformationProcess (hProcess, ProcessQuotaLimits, (PVOID) &ql, sizeof ql, NULL); CloseHandle (hProcess); } else { DWORD error = GetLastError (); __seterrno_from_win_error (error); debug_printf ("OpenProcess: ret = %d", error); return 0; } if (ret == STATUS_SUCCESS) ret = NtQuerySystemInformation (SystemTimeOfDayInformation, (PVOID) &stodi, sizeof stodi, NULL); if (ret == STATUS_SUCCESS) ret = NtQuerySystemInformation (SystemProcessorTimes, (PVOID) &spt, sizeof spt, NULL); if (ret != STATUS_SUCCESS) { __seterrno_from_win_error (RtlNtStatusToDosError (ret)); debug_printf ("NtQueryInformationProcess: ret = %d, " "Dos(ret) = %d", ret, RtlNtStatusToDosError (ret)); return 0; } fault_count = vmc.PageFaultCount; utime = put.UserTime.QuadPart * HZ / 10000000ULL; stime = put.KernelTime.QuadPart * HZ / 10000000ULL; if (stodi.CurrentTime.QuadPart > put.CreateTime.QuadPart) start_time = (spt.KernelTime.QuadPart + spt.UserTime.QuadPart - stodi.CurrentTime.QuadPart + put.CreateTime.QuadPart) * HZ / 10000000ULL; else /* * sometimes stodi.CurrentTime is a bit behind * Note: some older versions of procps are broken and can't cope * with process start times > time(NULL). */ start_time = (spt.KernelTime.QuadPart + spt.UserTime.QuadPart) * HZ / 10000000ULL; priority = pbi.BasePriority; unsigned page_size = getpagesize (); vmsize = vmc.VirtualSize; vmrss = vmc.WorkingSetSize / page_size; vmmaxrss = ql.MaximumWorkingSetSize / page_size; } else { start_time = (GetTickCount () / 1000 - time (NULL) + p->start_time) * HZ; } return __small_sprintf (destbuf, "%d (%s) %c " "%d %d %d %d %d " "%lu %lu %lu %lu %lu %lu %lu " "%ld %ld %ld %ld %ld %ld " "%lu %lu " "%ld " "%lu", p->pid, cmd, state, p->ppid, p->pgid, p->sid, makedev (FH_TTYS, p->ctty), -1, 0, fault_count, fault_count, 0, 0, utime, stime, utime, stime, priority, 0, 0, 0, start_time, vmsize, vmrss, vmmaxrss );}staticoff_tformat_process_status (_pinfo *p, char *destbuf, size_t maxsize){ char cmd[MAX_PATH]; int state = 'R'; const char *state_str = "unknown"; unsigned long vmsize = 0UL, vmrss = 0UL, vmdata = 0UL, vmlib = 0UL, vmtext = 0UL, vmshare = 0UL; if (p->process_state & (PID_ZOMBIE | PID_EXITED)) strcpy (cmd, "<defunct>"); else { strcpy (cmd, p->progname); char *last_slash = strrchr (cmd, '\\'); if (last_slash != NULL) strcpy (cmd, last_slash + 1); int len = strlen (cmd); if (len > 4) { char *s = cmd + len - 4; if (strcasecmp (s, ".exe") == 0) *s = 0; } } /* * Note: under Windows, a _process_ is always running - it's only _threads_ * that get suspended. Therefore the default state is R (runnable). */ if (p->process_state & PID_ZOMBIE) state = 'Z'; else if (p->process_state & PID_STOPPED) state = 'T'; else if (wincap.is_winnt ()) state = get_process_state (p->dwProcessId); switch (state) { case 'O': state_str = "running"; break; case 'D': case 'S': state_str = "sleeping"; break; case 'R': state_str = "runnable"; break; case 'Z': state_str = "zombie"; break; case 'T': state_str = "stopped"; break; } if (wincap.is_winnt ()) { if (!get_mem_values (p->dwProcessId, &vmsize, &vmrss, &vmtext, &vmdata, &vmlib, &vmshare)) return 0; unsigned page_size = getpagesize (); vmsize *= page_size; vmrss *= page_size; vmdata *= page_size; vmtext *= page_size; vmlib *= page_size; } // The real uid value for *this* process is stored at cygheap->user.real_uid // but we can't get at the real uid value for any other process, so // just fake it as p->uid. Similar for p->gid. return __small_sprintf (destbuf, "Name: %s\n" "State: %c (%s)\n" "Tgid: %d\n" "Pid: %d\n" "PPid: %d\n" "Uid: %d %d %d %d\n" "Gid: %d %d %d %d\n" "VmSize: %8d kB\n" "VmLck: %8d kB\n" "VmRSS: %8d kB\n" "VmData: %8d kB\n" "VmStk: %8d kB\n" "VmExe: %8d kB\n" "VmLib: %8d kB\n" "SigPnd: %016x\n" "SigBlk: %016x\n" "SigIgn: %016x\n", cmd, state, state_str, p->pgid, p->pid, p->ppid, p->uid, p->uid, p->uid, p->uid, p->gid, p->gid, p->gid, p->gid, vmsize >> 10, 0, vmrss >> 10, vmdata >> 10, 0, vmtext >> 10, vmlib >> 10, 0, 0, p->getsigmask () );}staticoff_tformat_process_statm (_pinfo *p, char *destbuf, size_t maxsize){ unsigned long vmsize = 0UL, vmrss = 0UL, vmtext = 0UL, vmdata = 0UL, vmlib = 0UL, vmshare = 0UL; if (wincap.is_winnt ()) { if (!get_mem_values (p->dwProcessId, &vmsize, &vmrss, &vmtext, &vmdata, &vmlib, &vmshare)) return 0; } return __small_sprintf (destbuf, "%ld %ld %ld %ld %ld %ld %ld", vmsize, vmrss, vmshare, vmtext, vmlib, vmdata, 0 );}staticintget_process_state (DWORD dwProcessId){ /* * This isn't really heavy magic - just go through the processes' * threads one by one and return a value accordingly * Errors are silently ignored. */ NTSTATUS ret; SYSTEM_PROCESSES *sp; ULONG n = 0x1000; PULONG p = new ULONG[n]; int state =' '; while (STATUS_INFO_LENGTH_MISMATCH == (ret = NtQuerySystemInformation (SystemProcessesAndThreadsInformation, (PVOID) p, n * sizeof *p, NULL))) delete [] p, p = new ULONG[n *= 2]; if (ret != STATUS_SUCCESS) { debug_printf ("NtQuerySystemInformation: ret = %d, " "Dos(ret) = %d", ret, RtlNtStatusToDosError (ret)); goto out; } state = 'Z'; sp = (SYSTEM_PROCESSES *) p; for (;;) { if (sp->ProcessId == dwProcessId) { SYSTEM_THREADS *st; if (wincap.has_process_io_counters ()) /* * Windows 2000 and XP have an extra member in SYSTEM_PROCESSES * which means the offset of the first SYSTEM_THREADS entry is * different on these operating systems compared to NT 4. */ st = &sp->Threads[0]; else /* * 136 is the offset of the first SYSTEM_THREADS entry on * Windows NT 4. */ st = (SYSTEM_THREADS *) ((char *) sp + 136); state = 'S'; for (unsigned i = 0; i < sp->ThreadCount; i++) { if (st->State == StateRunning || st->State == StateReady) { state = 'R'; goto out; } st++; } break; } if (!sp->NextEntryDelta) break; sp = (SYSTEM_PROCESSES *) ((char *) sp + sp->NextEntryDelta); }out: delete [] p; return state;}staticboolget_mem_values (DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss, unsigned long *vmtext, unsigned long *vmdata, unsigned long *vmlib, unsigned long *vmshare){ bool res = true; NTSTATUS ret; HANDLE hProcess; VM_COUNTERS vmc; MEMORY_WORKING_SET_LIST *mwsl; ULONG n = 0x1000, length; PULONG p = new ULONG[n]; unsigned page_size = getpagesize (); hProcess = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, dwProcessId); if (hProcess == NULL) { DWORD error = GetLastError (); __seterrno_from_win_error (error); debug_printf ("OpenProcess: ret = %d", error); return false; } while ((ret = NtQueryVirtualMemory (hProcess, 0, MemoryWorkingSetList, (PVOID) p, n * sizeof *p, &length)), (ret == STATUS_SUCCESS || ret == STATUS_INFO_LENGTH_MISMATCH) && length >= n * sizeof *p) delete [] p, p = new ULONG[n *= 2]; if (ret != STATUS_SUCCESS) { debug_printf ("NtQueryVirtualMemory: ret = %d, " "Dos(ret) = %d", ret, RtlNtStatusToDosError (ret)); res = false; goto out; } mwsl = (MEMORY_WORKING_SET_LIST *) p; for (unsigned long i = 0; i < mwsl->NumberOfPages; i++) { ++*vmrss; unsigned flags = mwsl->WorkingSetList[i] & 0x0FFF; if (flags & (WSLE_PAGE_EXECUTE | WSLE_PAGE_SHAREABLE) == (WSLE_PAGE_EXECUTE | WSLE_PAGE_SHAREABLE)) ++*vmlib; else if (flags & WSLE_PAGE_SHAREABLE) ++*vmshare; else if (flags & WSLE_PAGE_EXECUTE) ++*vmtext; else ++*vmdata; } ret = NtQueryInformationProcess (hProcess, ProcessVmCounters, (PVOID) &vmc, sizeof vmc, NULL); if (ret != STATUS_SUCCESS) { debug_printf ("NtQueryInformationProcess: ret = %d, " "Dos(ret) = %d", ret, RtlNtStatusToDosError (ret)); res = false; goto out; } *vmsize = vmc.VirtualSize / page_size;out: delete [] p; CloseHandle (hProcess); return res;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -