Исправление памяти процесса во время выполнения для восстановления состояния

Я ищу метод для хранения памяти процесса и восстанавливаю его позже при определенных условиях.

...

На самом деле я считал вопросы об этом... Это кажется сложной задачей!

Так, давайте проанализируем: приложение является распределенным, но много процессов являются не сохраняющими состояние (запросите их состояние к централизованному серверу). Процессы используют сетевые соединения и общую память для общения с другими процессами.

Центральный сервер должен сохранить свое состояние путем дампа его памяти процесса, которая должна быть восстановлена позже определенные условия. (1)

Я известный о функциях ReadProcessMemory и WriteProcessMemory, которые позволяют процессу считать себя и перезапись уже, выделил память, не так ли? Так, в котором я нуждаюсь, адрес, где я запускаю к чтению-записи и числу байтов к чтению-записи. Так..., что адреса? Многие кодируют, я читал, использует адрес, возвращенный VirtualAlloc, но я не делаю известный, могло ли это быть полезно для меня.

Я предполагаю, что исполнимые сегменты процесса не изменяются, таким образом, им не нужно красный/записанный. Во времени восстановления я мог также предположить, что все потоки процесса находятся в том же положении выполнения, когда память была считана основным потоком.

Это остается стековой памятью и памятью "кучи", которые являются сегментами памяти, чем я интересуюсь.

Действительно ли это возможно?

(1) Совершенно законно спросить, почему я пытаюсь сделать это. Причина является... сложной, как обычно. Однако скажите, что приложение имеет очень сложное состояние, которое требует слишком сложного алгоритма сохранения состояния. Другая альтернатива (который находится в предмете анализа) является реализацией механизма регистратора/воспроизведения, который в состоянии воспроизвести каждое событие, которое способствовало измененному состоянию.


Это прибыло по моему мнению рычаг co. и malloc. Таким образом, я могу отследить память, выделенную процессом. Но на самом деле я заметил _CrtMemState структуру, но я не делаю известный, могло ли это быть полезно для меня.

8
задан Luca 22 July 2010 в 21:43
поделиться

2 ответа

ReadProcessMemory предназначен для чтения памяти другого процесса. Внутри процесса в этом нет необходимости - вы можете просто разыменовать указатель для чтения памяти внутри того же процесса.

Чтобы найти блоки памяти в процессе, вы можете использовать VirtualQuery. Каждый блок будет помечен состоянием, типом, размером и т.д. Вот код, который я написал несколько лет назад для просмотра списка блоков для указанного процесса (используя VirtualQueryEx). Вы используете VirtualQuery практически так же, за исключением того, что вам не нужно указывать процесс, поскольку он всегда ходит по процессу, в котором запущен.

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

unsigned long usage;

void show_modules(HANDLE process) {

    unsigned char *p = NULL;
    MEMORY_BASIC_INFORMATION info;

    for ( p = NULL;
        VirtualQueryEx(process, p, &info, sizeof(info)) == sizeof(info);
        p += info.RegionSize ) 
    {
        printf("%#10.10x (%6uK)\t", info.BaseAddress, info.RegionSize/1024);

        switch (info.State) {
        case MEM_COMMIT:
            printf("Committed");
            break;
        case MEM_RESERVE:
            printf("Reserved");
            break;
        case MEM_FREE:
            printf("Free");
            break;
        }
        printf("\t");
        switch (info.Type) {
        case MEM_IMAGE:
            printf("Code Module");
            break;
        case MEM_MAPPED:
            printf("Mapped     ");
            break;
        case MEM_PRIVATE:
            printf("Private    ");
        }
        printf("\t");

        if ((info.State == MEM_COMMIT) && (info.Type == MEM_PRIVATE))
            usage +=info.RegionSize;

        int guard = 0, nocache = 0;

        if ( info.AllocationProtect & PAGE_NOCACHE)
            nocache = 1;
        if ( info.AllocationProtect & PAGE_GUARD )
            guard = 1;

        info.AllocationProtect &= ~(PAGE_GUARD | PAGE_NOCACHE);

        switch (info.AllocationProtect) {
        case PAGE_READONLY:
            printf("Read Only");
            break;
        case PAGE_READWRITE:
            printf("Read/Write");
            break;
        case PAGE_WRITECOPY:
            printf("Copy on Write");
            break;
        case PAGE_EXECUTE:
            printf("Execute only");
            break;
        case PAGE_EXECUTE_READ:
            printf("Execute/Read");
            break;
        case PAGE_EXECUTE_READWRITE:
            printf("Execute/Read/Write");
            break;
        case PAGE_EXECUTE_WRITECOPY:
            printf("COW Executable");
            break;
        }

        if (guard)
            printf("\tguard page");
        if (nocache)
            printf("\tnon-cachable");
        printf("\n");
    }
}

int main(int argc, char **argv) {

    int pid;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s <process ID>", argv[0]);
        return 1;
    }

    sscanf(argv[1], "%i", &pid);

    HANDLE process = OpenProcess( 
        PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, 
        false,
        pid);

    show_modules(process);
    printf("Total memory used: %luKB\n", usage/1024);
    return 0;
}        
8
ответ дан 5 December 2019 в 18:55
поделиться

Память процесса не отображает все состояние процесса. Операционная система будет хранить объекты от имени вашего процесса (например, дескрипторы файлов, объекты синхронизации и т. Д.) В таких местах, как невыгружаемый пул, которые выходят за рамки вашего процесса.

Я думаю, вам лучше провести рефакторинг, пока вы не сможете сериализовать и десериализовать соответствующее состояние с управляемыми усилиями.

1
ответ дан 5 December 2019 в 18:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: