Программа на C для поиска виртуальной памяти, используемой процессом в HP-UX?

#c #unix #virtual-memory

#c #unix #виртуальная память

Вопрос:

Этот вопрос был задан мне в интервью:

  • Напишите простую программу на C для поиска виртуальной памяти, используемой запущенным процессом в unix (HP-UX)

Я сказал им, что я не совсем уверен, но также выдвинул несколько идей, таких как:

  • может быть, мы можем получить идентификатор процесса с помощью getpid системного вызова и использовать его с stat и получить требуемый результат
  • или, может быть, мы можем запустить system вызов функции и внутри нее использовать команды оболочки типа ps и получить подробности.

Возможно, я не прав; кто-нибудь может мне помочь с этим?

Ответ №1:

Вы можете использовать функцию pstat_getprocvm в HP / UX, чтобы узнать о структуре виртуальной памяти процесса.

Пример взят отсюда

 #ifdef PS_RSESTACK      /* 11.22 and later */
#define LAST_VM_TYPE    PS_RSESTACK
#else               /* prior non-IPF */
#define LAST_VM_TYPE    PS_GRAPHICS_DMA
#endif              /* PS_RSESTACK */

uint32_t virt_totals[LAST_VM_TYPE   1];
uint32_t phys_totals[LAST_VM_TYPE   1];
uint32_t swap_totals[LAST_VM_TYPE   1];
uint32_t mlock_totals[LAST_VM_TYPE   1];

void print_type(int type)
{
    switch (type) {
    case PS_USER_AREA:
      printf(" UAREA ");
      return;
    case PS_TEXT:
      printf(" TEXT ");
      return;
    case PS_DATA:
      printf(" DATA/HEAP ");
      return;
    case PS_STACK:
      printf(" MAIN STACK ");
      return;
#ifdef PS_RSESTACK
      case PS_RSESTACK:
      printf(" RSE STACK ");
    return;
#endif              /* PS_RSESTACK */
    case PS_IO:
      printf(" MEM MAPPED I/O ");
    return;
      case PS_SHARED_MEMORY:
    printf(" SYSV SHMEM ");
    return;
    case PS_NULLDEREF:
    printf(" NULL DEREF ");
    return;
    case PS_MMF:
    printf(" MMAP ");
    return;
    case PS_GRAPHICS:
    case PS_GRAPHICS_DMA:
      printf(" GRAPHICS SPECIFIC ");
      return;
    default:
      printf(" UNUSED TYPE ");
    }
    return;
}

int main(int argc, char *argv[])
{
    int error;
    struct pst_vm_status pvs;
    struct pst_status ps;
    int i, j, k, verbose, get_all;
    pid_t target;
    int valid = 0;
    size_t sys_page_size;
    int done = 0;
    size_t count;
    _T_LONG_T last_pid = -1;

    verbose = 0;
    target = 0;
    get_all = 0;

    if (argc > 3) {
      printf("USAGE: %s <-v> n", argv[0]);
    }

    if (argc == 2) {
      target = atoi(argv[1]);
    } else if (argc == 3) {
      verbose = 1;
      target = atoi(argv[2]);
    } else {
      get_all = 1;
    }

    sys_page_size = sysconf(_SC_PAGE_SIZE);

    j = 0;

    printf("VIRT/PHYS/LOCKED/SWAP summaries in pages.n");
    printf("System page size is %ld or 0x%lx bytes.n",
       sys_page_size, sys_page_size);

    do {
    if (get_all) {
        target = j  ;
        count = (size_t) 1;
    } else {
        count = 0;
    }
   done = (pstat_getproc(amp;ps, sizeof(struct pst_status),
                  count, target) <= 0);
    if (done) {
        break;
    }

    if (ps.pst_pid == last_pid) {
        continue;
    }

    last_pid = ps.pst_pid;

    for (k = 0; k <= LAST_VM_TYPE; k  ) {
        virt_totals[k] = 0;
        phys_totals[k] = 0;
        swap_totals[k] = 0;
        mlock_totals[k] = 0;
    }

    i = 0;
    while (pstat_getprocvm(amp;pvs, sizeof(struct pst_vm_status),
                   (size_t) ps.pst_pid, i  ) > 0) {

        valid = 1;

        if (verbose) {
        printf("Object %d: ", i);
        print_type(pvs.pst_type);
        printf(" at VA 0x%lx to VA 0x%lx.nt",
               pvs.pst_vaddr,
               pvs.pst_vaddr  
               (pvs.pst_length * sys_page_size) - 1);
        printf("tVIRT: %ld tPHYS: %ld tLOCKED:"
               " %ldtSWAP: %ld n",
               pvs.pst_length, pvs.pst_phys_pages,
               pvs.pst_lockmem, pvs.pst_swap);
        }
        virt_totals[pvs.pst_type]  = pvs.pst_length;
        phys_totals[pvs.pst_type]  = pvs.pst_phys_pages;
        swap_totals[pvs.pst_type]  = pvs.pst_swap;
        mlock_totals[pvs.pst_type]  = pvs.pst_lockmem;
    }

    if (valid) {
        printf("PID %ld:n", ps.pst_pid);
    }
 for (k = 0; k <= LAST_VM_TYPE amp;amp; valid; k  ) {
        print_type(k);
        printf(" consumes %ld VIRT, %ld PHYS, %ld LOCKED"
           " and %ld SWAP.n",
           virt_totals[k], phys_totals[k], mlock_totals[k],
           swap_totals[k]);
        virt_totals[k] = 0;
        phys_totals[k] = 0;
        mlock_totals[k] = 0;
        swap_totals[k] = 0;
    }
    valid = 0;
    } while (get_all);

    exit(0);
  

Ответ №2:

Использование getpid() не поможет — оно сообщает вам PID текущего процесса, который, вероятно, не тот, который вас интересует.

Использование stat() не поможет — оно сообщает вам размер файла.

У вас есть два варианта one main — я не уверен, какой из них наиболее подходит для HP-UX.

  1. Используйте /proc файловую систему и информацию из нее, чтобы найти нужное вам число. На компьютере HP-UX 11.23, к которому у меня есть доступ, не было /proc , поэтому есть большая вероятность, что это не имеет отношения к делу.
  2. Запустите соответствующую ps команду через popen() и проанализируйте выходные данные. Команда может быть ps -lp PID где PID — это (я надеюсь, очевидно) PID интересующего вас процесса.

Быстрая проверка показывает:

  • AIX, Solaris, Linux имеют (три различные реализации) /proc файловой системы.
  • HP-UX и macOS X (и, следовательно, другие системы BSD) не имеют /proc файловой системы.