Saving/Restoring the virtual address space of a linux process

Cagri Koksal (
Wed, 28 Apr 1999 20:30:31 +0300 (EET DST)

I am working on a process migration process. Without modfying the kernel,
I want to create an environment, where a linux process may save its
virtual memory space into a file upon receiving a user signal, may be
transferred to a different linux box with its memory dump file, and
restore its state on that box by restoring its virtual address space and
values of Base Pointer, Stack Pointer and Instruction pointer.

This is not a complete save/restore of state but some of the state. Some
portions of the code I've written is below. It fails while
saving/restoring the address space of the process.

#define STACKSIZE 8192

struct MIGENV {
long FSF ; //address of first stack frame
long *TMP_STACK ; //pointer to temporary stack
jmp_buf orig_env, new_env ;
} ;

struct MIGENV migenv ;
main() {
signal(SIGUSR1,checkpoint) ;
signal(SIGUSR2,resume) ;

setjmp(migenv.orig_env) ;
migenv.FSF=*(long)*(long *)migenv.orig_env[0].__bp ;

mymain() ;
void checkpoint() {
long BP, SP, PC ;
long BSS, BSS_size, HEAP_end ;
char s[10] ;
int k ;
FILE *fd ;

if (setjmp(migenv.orig_env)==0) {

SP=(long)migenv.orig_env[0].__sp ;

fd=fopen("checkpt.dat","w+") ;
fwrite(&migenv.orig_env,1,sizeof(jmp_buf),fd) ;
fwrite(&migenv.FSF,1,sizeof(migenv.FSF),fd) ;
fwrite((long *)SP,sizeof(long),migenv.FSF-SP+8,fd) ;
fclose(fd) ;

//get BSS start address and BSS size
system("size -A | grep ^.bss > sections.dat") ;
fd=fopen("sections.dat","r+") ;
fscanf(fd,"%s %lu %lu \n",&s,&BSS_size,&BSS) ;
//find end address of heap
HEAP_end=(long)sbrk(0) ;
fprintf(fd,"%lu",HEAP_end) ;
fclose(fd) ;

//write uninitialized data and heap to data.dat file
fd=fopen("data.dat","w+") ;
k=fwrite((void *)BSS,1,(HEAP_end-BSS),fd) ;
fclose(fd) ;

} else {
//when state is restored by longjmp , program continues
//from here.
resumeOK() ;

void resume() {

//Restore Data
puts("Restoring Data Section") ;
restore_data() ;

//Now Restore Stack
puts("Restoring Stack Section") ;
migenv.TMP_STACK=(long *)malloc(STACKSIZE) ;

if (setjmp(migenv.new_env)==0) {

migenv.new_env[0].__bp=migenv.TMP_STACK+(STACKSIZE-2) ;
migenv.new_env[0].__sp=migenv.TMP_STACK+(STACKSIZE-3) ;
longjmp(migenv.new_env,1) ;
} else {
//Now Running on temporary stack
puts("Running On Temporary Stack") ;
restore_stack() ;

void restore_data() {
char s[10] ;
FILE *fd ;
long BSS,BSS_size,HEAP_end,h ;
int j,k ;

fd=fopen("sections.dat","r") ;
fscanf(fd,"%s %lu %lu \n",&s,&BSS_size,&BSS) ;
fscanf(fd,"%lu",&HEAP_end) ; //end of heap at checkpoint time
fclose(fd) ;

//Now allocate space from heap and restore heap
//Then restore uninitialized data segment
brk((void *)HEAP_end) ;

//restore bss segment
fread((void *)BSS,1,(HEAP_end-BSS),fd) ;

fclose(fd) ;
puts("BSS Section Restored") ;
} ;

void restore_stack() {
FILE *fd ;
long BP,SP,PC ;

fopen("checkpt.dat","r") ;
fread(&migenv.orig_env,1,sizeof(migenv.orig_env),fd) ; //restore
fread(&migenv.FSF,1,sizeof(migenv.FSF),fd) ;
fread((long *)SP, sizeof(long), migenv.FSF-SP+8,fd) ;//restore
fclose(fd) ;

longjmp(migenv.orig_env,0) ;


When the process receives SIGUSR1 it checkpoints, (assume it is terminated
then, and restarted). After restarting we send SIGUSR2 to it and it
resumes execution.

I get "core dumped" messages while saving/restoring bss and heap of the

Am I on the right track ? I am very new to these low level information in
Linux. Any one has an idea or suggestion ?

Thanks a lot.

Cagri Koksal
Marmara University Computer Science Dept
Finansbank Data Comm Division

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to
Please read the FAQ at