Subversion Repositories HelenOS

Rev

Rev 4613 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include <stdlib.h>
  2. #include <sysinfo.h>
  3. #include <stdio.h>
  4. #include <errno.h>
  5. #include <sys/stat.h>
  6. #include <vfs/vfs.h>
  7. #include <unistd.h>
  8. #include <fcntl.h>
  9. #include <ipc/ipc.h>
  10. #include <sys/types.h>
  11. #include <malloc.h>
  12.  
  13. #include <udebug.h>
  14.  
  15. #define THBUF_SIZE 64
  16. #define FILE_CHUNK_SIZE 250
  17.  
  18. int spawn_task(char* task, char *argv[]);
  19. int write_to_disk(void *buffer, size_t n, char *filename);
  20. int init_disk();
  21. int connect_kbox(int task_id, int *kbox_phone_id);
  22. int store_kstack(int kbox_phone_id, thash_t tid);
  23. int store_thread_struct(int kbox_phone_id, thash_t tid);
  24. int checkpoint(unsigned int kbox_phone_id_arg);
  25. int write_uspace_mem_to_disk(unsigned *buffer, size_t n, uintptr_t start_addr, char *filename);
  26. int store_uspace_memory_areas_to_disk(int kbox_phone_id);
  27.  
  28.  
  29. int main(int argc, char **argv)
  30. {
  31.     char *task = "/app/tetris";
  32.     char *argv_spawn[2];
  33.    
  34.     argv_spawn[0] = task;
  35.     argv_spawn[1] = NULL;
  36.  
  37.     int task_id = spawn_task(task, argv_spawn);
  38.  
  39.     checkpoint(task_id);
  40.  
  41.     return (0);
  42. }
  43.  
  44. int checkpoint(unsigned int task_id)
  45. {
  46.     /* Create the directories. */
  47.     init_disk();
  48.  
  49.     int kbox_phone_id;
  50.     connect_kbox(task_id, &kbox_phone_id);
  51.  
  52.     int dbg_ret;
  53.     dbg_ret = udebug_begin(kbox_phone_id);
  54.  
  55.     uintptr_t thread_hash_buf[THBUF_SIZE];
  56.     size_t copied, needed;
  57.     udebug_thread_read(kbox_phone_id, thread_hash_buf, sizeof(thread_hash_buf), &copied, &needed);
  58.  
  59.     printf("Press a key to store kstack contents...\n");
  60.     getchar();
  61.     store_kstack(kbox_phone_id, thread_hash_buf[0]);
  62.  
  63.     printf("Press a key to store thread structure...\n");
  64.     getchar();
  65.     store_thread_struct(kbox_phone_id, thread_hash_buf[0]);
  66.  
  67.     printf("Press a key to read and write uspace memory contents...\n");
  68.     getchar();
  69.     store_uspace_memory_areas_to_disk(kbox_phone_id);
  70.  
  71.    
  72.     printf("Press key to FINISH checkpointing...\n");
  73.     getchar();
  74.  
  75.     int rc_end = udebug_end(kbox_phone_id);
  76.     printf("rc end: %i\n", rc_end);
  77.  
  78. }
  79.  
  80. int spawn_task(char* task, char *argv[])
  81. {
  82.     int task_id = task_spawn(task, argv);
  83.     if (task_id <= 0)
  84.         printf("error spawning\n");
  85.  
  86.     printf("spawned task %s with id: %i\n", task, task_id);
  87.  
  88.     return (task_id);
  89. }
  90.  
  91. int init_disk()
  92. {
  93.     int rc;
  94.     if ((rc = mkdir("/mydir", 0)) != 0)
  95.         printf("mkdir() failed.\n");
  96.  
  97.     return (rc);
  98. }
  99.  
  100. int connect_kbox(int task_id, int *kbox_phone_id)
  101. {
  102.     *kbox_phone_id = ipc_connect_kbox(task_id);
  103.     if (*kbox_phone_id == ENOTSUP)
  104.         printf("not suppported\n");
  105.  
  106.     if (*kbox_phone_id < 0) {
  107.         printf("Error connecting\n");
  108.         printf("ipc_connect_task(%lld) -> %d ", task_id, *kbox_phone_id);
  109.         return (-1);
  110.     }
  111.  
  112.     return (0);
  113. }
  114.  
  115. int store_kstack(int kbox_phone_id, thash_t tid)
  116. {
  117.     size_t copied, needed;
  118.     unsigned tmp[1];
  119.     udebug_thread_copy_kstack(kbox_phone_id, tid, tmp, sizeof(tmp), &copied, &needed);
  120.  
  121.     void *kstack_buffer = malloc(needed);
  122.     udebug_thread_copy_kstack(kbox_phone_id, tid, kstack_buffer, needed, &copied, &needed);
  123.  
  124.     write_to_disk(kstack_buffer, needed, "/mydir/kstack");
  125.  
  126.     printf("size of kstack: %p\n", needed);
  127.  
  128.     free(kstack_buffer);
  129.  
  130.     return (0);
  131. }
  132.  
  133. int store_thread_struct(int kbox_phone_id, thash_t tid)
  134. {
  135.     size_t ts_copied, ts_needed, ts_needed_old;
  136.  
  137.     udebug_thread_get_thread_struct(kbox_phone_id, tid, NULL, 0, &ts_copied, &ts_needed);
  138.     ts_needed_old = ts_needed;
  139.    
  140.     void *thread_struct_buffer = malloc(ts_needed);
  141.     udebug_thread_get_thread_struct(kbox_phone_id, tid, thread_struct_buffer, ts_needed, &ts_copied, &ts_needed);
  142.  
  143.     write_to_disk(thread_struct_buffer, ts_copied, "/mydir/ts");
  144.  
  145.     free(thread_struct_buffer);
  146.  
  147.     return (0);
  148. }
  149.  
  150. int store_uspace_memory_areas_to_disk(int kbox_phone_id)
  151. {
  152.     size_t mem_copied, mem_needed;
  153.  
  154.     unsigned *mem_areas_buf = (unsigned *)malloc(sizeof(unsigned *) * THBUF_SIZE);
  155.     udebug_task_memory_areas_read(kbox_phone_id, mem_areas_buf, THBUF_SIZE*sizeof(unsigned), &mem_copied, &mem_needed);
  156.     int areas = mem_copied / sizeof(unsigned);
  157.  
  158.     int i;
  159.     for (i=0; i<areas; i+=2)
  160.     {
  161.         size_t size = mem_areas_buf[i+1] - mem_areas_buf[i];
  162.         unsigned *mem_read_out = malloc(size);
  163.        
  164.         udebug_mem_read(kbox_phone_id, mem_read_out, mem_areas_buf[i], size);
  165.  
  166.         char file_name_buf[25];
  167.         snprintf(file_name_buf, 25, "/mydir/%i.mem", i);
  168.  
  169.         printf("Writing area at %p to disk, size: %p.\n", mem_areas_buf[i], size);
  170.         write_uspace_mem_to_disk(mem_read_out, size, mem_areas_buf[i], file_name_buf);
  171.  
  172.         free(mem_read_out);
  173.     }
  174.  
  175.     return (0);
  176. }
  177.  
  178. int write_uspace_mem_to_disk(unsigned *buffer, size_t n, uintptr_t start_addr, char *filename)
  179. {
  180.     size_t chunk_size = FILE_CHUNK_SIZE*sizeof(unsigned);
  181.     unsigned written = 0;
  182.     int fd0 = open(filename, O_CREAT);
  183.     int cnt;
  184.     uintptr_t tmp[1];
  185.     tmp[0] = start_addr;
  186.  
  187.     cnt = write(fd0, tmp, sizeof(tmp));
  188.  
  189.     while (written < n)
  190.     {
  191.         if (n - written < chunk_size)
  192.             chunk_size = n - written;
  193.         cnt = write(fd0, buffer, chunk_size);
  194.         if (cnt < 0)
  195.         {
  196.             printf("Writing to uspace memory failed! Written %p bytes. Code: %i\n", written, cnt);
  197.             break;
  198.         }
  199.         buffer += (cnt / sizeof(unsigned));
  200.         written += cnt;
  201.     }
  202.  
  203.     printf("Written %p bytes. End address: %p\n", written, (unsigned*)((unsigned)start_addr + written));
  204.     close(fd0);
  205.  
  206.     return (0);
  207. }
  208.  
  209. int write_to_disk(void *buffer, size_t n, char *filename)
  210. {
  211.     size_t chunk_size = FILE_CHUNK_SIZE * sizeof(unsigned);
  212.     printf("Writing to disk, size: %p, filename: %s.\n", n, filename);
  213.     int fd0 = open(filename, O_CREAT);
  214.     size_t written = 0;
  215.  
  216.     size_t tmp[1];
  217.     tmp[0] = n;
  218.     write(fd0, tmp, sizeof(tmp));
  219.  
  220.     while (written < n)
  221.     {
  222.         if (n - written < chunk_size)
  223.         {
  224.             chunk_size = n - written;
  225.         }
  226.         int cnt = write(fd0, buffer, chunk_size);
  227.         if (cnt < 0)
  228.         {
  229.             printf("Write failed! Code: %i\n", cnt);
  230.             break;
  231.         }
  232.         buffer += cnt;
  233.         written += cnt;
  234.     }
  235.  
  236.     printf("Written %p bytes.\n", written);
  237.     close(fd0);
  238.  
  239.     return (0);
  240. }
  241.  
  242.