System::ProcessDescriptor Class Reference

Provides access to process information. More...

#include <src/Lib/ProcessDescriptor.h>

Classes

class  ProcessHandle
 

Public Member Functions

 ProcessDescriptor ()
 
virtual ~ProcessDescriptor ()
 
long query (long pid, InfoType info, PROCESS_BASIC_INFORMATION *buffer)
 
long query (long pid, InfoType info, POOLED_USAGE_AND_LIMITS *buffer)
 
long query (long pid, InfoType info, KERNEL_USER_TIMES *buffer)
 
long query (long pid, InfoType info, QUOTA_LIMITS *buffer)
 
long query (long pid, InfoType info, VM_COUNTERS *buffer)
 
long query (long pid, InfoType info, IO_COUNTERS *buffer)
 
long query (long pid, InfoType info, long *buffer)
 

Detailed Description

Provides access to process information.

Author
M.Frank
Sebastien Ponce

Definition at line 109 of file ProcessDescriptor.h.

Constructor & Destructor Documentation

System::ProcessDescriptor::ProcessDescriptor ( )

Definition at line 415 of file ProcessDescriptor.cpp.

416 {
417 #ifdef _WIN32
418  static bool first = true;
419  if ( first ) {
420  first = false;
421  void* mh = ::LoadLibrary("NTDll.dll");
422  if ( mh ) {
423  NtApi::NtQueryInformationProcess = (NtApi::__NtQueryInformationProcess)
424  ::GetProcAddress((HINSTANCE)mh, "NtQueryInformationProcess");
425  }
426  }
427 #endif
428 }
System::ProcessDescriptor::~ProcessDescriptor ( )
virtual

Definition at line 430 of file ProcessDescriptor.cpp.

430  {
431 }

Member Function Documentation

long System::ProcessDescriptor::query ( long  pid,
InfoType  info,
PROCESS_BASIC_INFORMATION buffer 
)

Definition at line 642 of file ProcessDescriptor.cpp.

644  {
645  if (info==0) return 0;
646  long status = 1;
647 
648  if ( fetch == ProcessBasics ) {
649 #if defined(_WIN32) && WINVER>=0x0400 // Windows NT
650  ProcessHandle h(pid);
651  status = NtApi::NtQueryInformationProcess(h.handle(),
653  info,
654  sizeof(PROCESS_BASIC_INFORMATION),
655  0);
656  status = (status==0) ? 1 : 0;
657 #elif defined(_WIN32) // Windows 95,98...
658 #elif defined(__linux) // Linux
659  linux_proc prc;
660  pid = processID(pid);
661  readProcStat(pid, prc);
662  info->ExitStatus = 0;
663  info->PebBaseAddress = (PPEB)prc.startcode;
664  info->BasePriority = 2*15-prc.priority;
665  // std::cout << "Base Priority=" << info->BasePriority << "|"
666  // << prc.priority << std::endl;
667  info->AffinityMask = prc.flags;
668  // std::cout << "Flags =" << info->AffinityMask << "|"
669  // << prc.flags << std::endl;
670  info->UniqueProcessId = pid;
671  info->InheritedFromUniqueProcessId = prc.ppid;
672 #else // All Other
673 #endif // End ALL OS
674  }
675  return status;
676 }
unsigned long flags
void readProcStat(long pid, linux_proc &pinfo)
unsigned long startcode
struct _PEB * PPEB
Basic Process Information NtQueryInformationProcess using ProcessBasicInfo.
void * ProcessHandle
Definition of the process handle.
Definition: ModuleInfo.h:32
long System::ProcessDescriptor::query ( long  pid,
InfoType  info,
POOLED_USAGE_AND_LIMITS buffer 
)

Definition at line 466 of file ProcessDescriptor.cpp.

468  {
469  if (info==0) return 0;
470  long status = 1;
471 
472  if ( fetch == Quota ) {
473 #if defined(_WIN32) && WINVER>=0x0400 // Windows NT
474  ProcessHandle h(pid);
475  status = NtApi::NtQueryInformationProcess(h.handle(),
477  info,
478  sizeof(POOLED_USAGE_AND_LIMITS),
479  0);
480  status = (status==0) ? 1 : 0;
481 #elif defined(_WIN32) // Windows 95,98...
482 #elif defined(__linux) // Linux
483  //rusage usage;
484  //getrusage(RUSAGE_SELF, &usage);
485  rlimit lim;
486 
487  getrlimit(RLIMIT_DATA, &lim);
488  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
489  info->PeakPagedPoolUsage = lim.rlim_cur;
490  info->PagedPoolUsage = lim.rlim_cur;
491  info->PagedPoolLimit = lim.rlim_max;
492 
493  getrlimit(RLIMIT_STACK, &lim);
494  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
495  info->PeakNonPagedPoolUsage = lim.rlim_cur;
496  info->NonPagedPoolUsage = lim.rlim_cur;
497  info->NonPagedPoolLimit = lim.rlim_max;
498 
499  linux_proc prc;
500  readProcStat(processID(pid), prc);
501  info->PeakPagefileUsage = prc.rss * pg_size;
502  info->PagefileUsage = prc.rss * pg_size;
503  info->PagefileLimit = 0xFFFFFFFF;
504 #elif defined(__APPLE__)
505 #else // All Other
506 #endif // End ALL OS
507  }
508 
509  return status;
510 }
void readProcStat(long pid, linux_proc &pinfo)
void * ProcessHandle
Definition of the process handle.
Definition: ModuleInfo.h:32
long System::ProcessDescriptor::query ( long  pid,
InfoType  info,
KERNEL_USER_TIMES buffer 
)

Definition at line 678 of file ProcessDescriptor.cpp.

680  {
681  if (info==0) return 0;
682  long status = 1;
683 
684  if ( fetch == Times ) {
685 #if defined(_WIN32) && WINVER>=0x0400 // Windows NT
686  ProcessHandle h(pid);
687  status = NtApi::NtQueryInformationProcess(h.handle(),
688  ProcessTimes,
689  info,
690  sizeof(KERNEL_USER_TIMES),
691  0);
692  status = (status==0) ? 1 : 0;
693 #elif defined(_WIN32) // Windows 95,98...
694 #elif defined(__linux) // Linux
695  static longlong prc_start = 0;
696  bool myself = pid<=0 || pid==::getpid(); // avoid unnecessary calls to getpid if pid<0
697  if ( myself && prc_start == 0 ) { // called only once to set prc_start
698  linux_proc prc;
699  readProcStat( processID(pid), prc);
700  // prc.startup is in ticks since system start, need to offset for absolute time
701  tms tmsb;
702  static longlong offset = 100*longlong(time(nullptr)) - longlong(times(&tmsb));
703  prc_start = (prc.starttime+offset) * TICK_TO_100NSEC;
704  }
705 
706  if ( myself ) { // myself
707  tms tmsb;
708  times(&tmsb);
709  info->UserTime = tmsb.tms_utime * TICK_TO_100NSEC;
710  info->KernelTime = tmsb.tms_stime * TICK_TO_100NSEC;
711  info->CreateTime = prc_start;
712  }
713  else { // other process
714  linux_proc prc;
715  readProcStat( processID(pid), prc );
716  tms tmsb;
717  static longlong offset = 100*longlong(time(nullptr)) - longlong(times(&tmsb));
718 
719  tms t;
720  times(&t);
721  info->UserTime = t.tms_utime * TICK_TO_100NSEC;
722  info->KernelTime = t.tms_stime * TICK_TO_100NSEC;
723  info->CreateTime = (prc.starttime+offset) * TICK_TO_100NSEC;
724  }
725  info->ExitTime = 0;
726 
727  status = 1;
728 
729 #elif defined(__APPLE__)
730  // FIXME (MCl): Make an alternative function get timing on OSX
731  // times() seems to cause a segmentation fault
732 #else // no /proc file system: assume sys_start for the first call
733  tms tmsb;
734  static clock_t sys_start = times(0);
735  static longlong offset = 100*longlong(time(0)) - sys_start;
736  clock_t now = times(&tmsb);
737  info->CreateTime = offset + now;
738  info->UserTime = tmsb.tms_utime;
739  info->KernelTime = tmsb.tms_stime;
740  info->CreateTime *= TICK_TO_100NSEC;
741  info->UserTime *= TICK_TO_100NSEC;
742  info->KernelTime *= TICK_TO_100NSEC;
743  info->ExitTime = 0;
744  status = 1;
745 #endif
746  }
747 
748  return status;
749 }
void readProcStat(long pid, linux_proc &pinfo)
unsigned long long starttime
__longlong longlong
Definition: Kernel.h:57
void * ProcessHandle
Definition of the process handle.
Definition: ModuleInfo.h:32
long System::ProcessDescriptor::query ( long  pid,
InfoType  info,
QUOTA_LIMITS buffer 
)

Definition at line 592 of file ProcessDescriptor.cpp.

594  {
595  if (info==0) return 0;
596  long status = 1;
597 
598  if ( fetch == Quota ) {
599 #if defined(_WIN32) && WINVER>=0x0400 // Windows NT
600  ProcessHandle h(pid);
601  status = NtApi::NtQueryInformationProcess(h.handle(),
603  info,
604  sizeof(QUOTA_LIMITS),
605  0);
606  status = (status==0) ? 1 : 0;
607 #elif defined(_WIN32) // Windows 95,98...
608 #elif defined(__linux) // Linux
609  // On linux all this stuff typically is not set
610  // (ie. rlim_max=RLIM_INFINITY...)
611 
612  if (pid>0 && pid!=::getpid()) return 0; // only possible for myself
613 
614  rlimit lim;
615  getrlimit(RLIMIT_DATA, &lim);
616  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
617  info->PagedPoolLimit = lim.rlim_max;
618 
619  getrlimit(RLIMIT_STACK, &lim);
620  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
621  info->NonPagedPoolLimit = lim.rlim_max;
622  info->MinimumWorkingSetSize = 0;
623 
624  getrlimit(RLIMIT_RSS, &lim);
625  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
626  info->MaximumWorkingSetSize = lim.rlim_max;
627 
628  getrlimit(RLIMIT_AS, &lim);
629  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
630  info->PagefileLimit = lim.rlim_max;
631 
632  getrlimit(RLIMIT_CPU, &lim);
633  if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
634  info->TimeLimit = lim.rlim_max;
635 #elif defined(__APPLE__)
636 #else // All Other
637 #endif // End ALL OS
638  }
639  return status;
640 }
void * ProcessHandle
Definition of the process handle.
Definition: ModuleInfo.h:32
long System::ProcessDescriptor::query ( long  pid,
InfoType  info,
VM_COUNTERS buffer 
)

Definition at line 543 of file ProcessDescriptor.cpp.

545  {
546  if (info==0) return 0;
547  long status = 1;
548 
549  if ( fetch == Memory ) {
550 #if defined(_WIN32) && WINVER>=0x0400 // Windows NT
551  ProcessHandle h(pid);
552  status = NtApi::NtQueryInformationProcess(h.handle(),
554  info,
555  sizeof(VM_COUNTERS),
556  0);
557  status = (status==0) ? 1 : 0;
558 #elif defined(_WIN32) // Windows 95,98...
559 #elif defined(__linux) // Linux
560  const ssize_t bufsize = 1024;
561  char buf[bufsize];
562  pid = processID(pid);
563  sprintf(buf,"/proc/%ld/statm", pid);
564  long size, resident, share, trs, lrs, drs, dt;
565  int fd = open(buf,O_RDONLY);
566  ssize_t nread = read(fd, buf, bufsize);
567  close(fd);
568  if ( nread < bufsize && nread >= 0 )
569  buf[nread]='\0';
570  fd = sscanf(buf, "%ld %ld %ld %ld %ld %ld %ld",
571  &size, &resident, &share, &trs, &drs, &lrs, &dt);
572  linux_proc prc;
573  readProcStat( pid, prc);
574  info->PeakVirtualSize = prc.vsize;
575  info->VirtualSize = prc.vsize;
576  info->PeakWorkingSetSize = resident * pg_size;
577  info->WorkingSetSize = resident * pg_size;
578  info->QuotaPeakPagedPoolUsage = share * pg_size;
579  info->QuotaPagedPoolUsage = share * pg_size;
580  info->QuotaNonPagedPoolUsage = (trs+drs)* pg_size;// drs = data/stack size
581  info->QuotaPeakNonPagedPoolUsage = (trs+drs)* pg_size;// trs = VmExe size
582  info->PageFaultCount = prc.majflt + prc.minflt;
583  info->PagefileUsage = prc.vsize-resident*pg_size;
584  info->PeakPagefileUsage = prc.vsize-resident*pg_size;
585 #elif defined(__APPLE__)
586 #else // All Other
587 #endif // End ALL OS
588  }
589  return status;
590 }
unsigned long minflt
T sscanf(T...args)
void readProcStat(long pid, linux_proc &pinfo)
unsigned long vsize
unsigned long majflt
T sprintf(T...args)
void * ProcessHandle
Definition of the process handle.
Definition: ModuleInfo.h:32
long System::ProcessDescriptor::query ( long  pid,
InfoType  info,
IO_COUNTERS buffer 
)

Definition at line 433 of file ProcessDescriptor.cpp.

435  {
436  if (info==0) return 0;
437  long status = 1;
438 
439  if ( fetch == IO ) {
440 #if defined(_WIN32) && WINVER>=0x0400 // Windows NT
441  ProcessHandle h(pid);
442  status = NtApi::NtQueryInformationProcess(h.handle(),
444  info,
445  sizeof(IO_COUNTERS),
446  0);
447  status = (status==0) ? 1 : 0;
448 #elif defined(_WIN32) // Windows 95,98...
449 #elif defined(__linux)
450  linux_proc prc;
451  readProcStat(processID(pid), prc);
452  rusage usage;
453  getrusage(RUSAGE_SELF, &usage);
454  info->ReadOperationCount = usage.ru_inblock;
455  info->WriteOperationCount = usage.ru_oublock;
456  info->OtherOperationCount = 0;
457  info->ReadTransferCount = usage.ru_inblock;
458  info->WriteTransferCount = usage.ru_oublock;
459  info->OtherTransferCount = 0;
460 #else // All Other
461 #endif // End ALL OS
462  }
463  return status;
464 }
void usage(std::string argv0)
void readProcStat(long pid, linux_proc &pinfo)
void * ProcessHandle
Definition of the process handle.
Definition: ModuleInfo.h:32
long System::ProcessDescriptor::query ( long  pid,
InfoType  info,
long *  buffer 
)

Definition at line 512 of file ProcessDescriptor.cpp.

512  {
513 
514  if (info==0) return 0;
515  long status = 1;
516 
517  switch ( fetch ) {
518  case PriorityBoost:
519 #if defined(_WIN32) && WINVER>=0x0400 // Windows NT
520  ProcessHandle h(pid);
521  status = NtApi::NtQueryInformationProcess(h.handle(),
523  info,
524  sizeof(long),
525  0);
526 #elif defined(_WIN32) // Windows 95,98...
527 #else
528  // Not applicable
529  if (pid>0) status = 0; // to avoid compiler warning
530  status = 0;
531  *info = 0;
532 #endif // End ALL OS
533  status = (status==0) ? 1 : 0;
534  break;
535  default:
536  status = -1;
537  info = &status;
538  break;
539  }
540  return status;
541 }
void * ProcessHandle
Definition of the process handle.
Definition: ModuleInfo.h:32

The documentation for this class was generated from the following files: