#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.
Используйте/proc
файловую систему и информацию из нее, чтобы найти нужное вам число. На компьютере HP-UX 11.23, к которому у меня есть доступ, не было/proc
, поэтому есть большая вероятность, что это не имеет отношения к делу.- Запустите соответствующую
ps
команду черезpopen()
и проанализируйте выходные данные. Команда может бытьps -lp PID
где PID — это (я надеюсь, очевидно) PID интересующего вас процесса.
Быстрая проверка показывает:
- AIX, Solaris, Linux имеют (три различные реализации)
/proc
файловой системы. - HP-UX и macOS X (и, следовательно, другие системы BSD) не имеют
/proc
файловой системы.