libvmi 0.6 dump-memory.c segfaults

106 views
Skip to first unread message

gyre

unread,
Dec 21, 2011, 11:28:04 AM12/21/11
to vmitools
I don't see how this would work. In fact, it segfaults immediately
for me.

[code]
if (PAGE_SIZE == vmi_read_pa(vmi, address, memory, PAGE_SIZE))
{
/* memory mapped, just write to file */
size_t written = fwrite(memory, 1, PAGE_SIZE, f);
if (written != PAGE_SIZE){
printf("failed to write memory to file.\n");
goto error_exit;
}
munmap(memory, PAGE_SIZE);
}
[/code]

As far as I can tell, vmi_read_pa doesn't return a memmapped memory
pointer, it just fills up the supplied buffer with bytes.

If I re-code this segment to fill up a PAGE_SIZE'd char buffer and
remove the munmap:

[code]
char mem2[PAGE_SIZE];

/* write memory to file */
if (PAGE_SIZE == vmi_read_pa(vmi, address, &mem2, PAGE_SIZE)){
/* memory mapped, just write to file */
size_t written = fwrite(mem2, 1, PAGE_SIZE, f);
if (written != PAGE_SIZE){
printf("failed to write memory to file.\n");
goto error_exit;
}
// munmap(memory, PAGE_SIZE);
}
[/code]

the code will at least run for a while before complaining:

xc: error: xc_map_foreign_batch: mmap failed (12 = Cannot allocate
memory): Internal error

How can I unmap so this doesn't happen?

I'm looking for code that efficiently looks through a VM's "physical"
memory. Is this the best way of doing it?

Thanks!

-- gyre --

Bryan D. Payne

unread,
Dec 21, 2011, 11:06:02 PM12/21/11
to vmit...@googlegroups.com
> I don't see how this would work.  In fact, it segfaults immediately
> for me.

Sorry about that... Looks like you found some code that didn't get
properly updated in the XenAccess to LibVMI conversion.

> the code will at least run for a while before complaining:
>
> xc: error: xc_map_foreign_batch: mmap failed (12 = Cannot allocate
> memory): Internal error
>
> How can I unmap so this doesn't happen?

Your code looks right. I think the problem is with the LibVMI
page-level caching. I looked into it today and found a bug where
pages were not being released properly (thus exhausting the resources
over time). If you want to fix it yourself without waiting for the
next release, try looking towards the bottom of
libvmi/driver/memory_cache.c. In memory_cache_insert, the key needs
to be created with malloc instead of a straight assignment. So it
will look something like this:

gint64 *key = malloc(sizeof(gint64));
*key = paddr;

Then you just need to change they &key to key when it is used in the
function calls below.

> I'm looking for code that efficiently looks through a VM's "physical"
> memory.  Is this the best way of doing it?

Yep!

Cheers,
bryan

gyre

unread,
Dec 22, 2011, 4:11:50 AM12/22/11
to vmit...@googlegroups.com
Thanks for replying Brian.

> I think the problem is with the LibVMI page-level caching.

OK. Make sense, since the updated function call doesn't allow me to munmap
the page manually, libvmi will presumably be doing so itself at some time in
the near future.

> If you want to fix it yourself without waiting for the next release

I made the changes you suggested. I still see the error messages while
running the modified dump-memory.c followed by a segfault at the end.

Will enable debugging and follow the logic through today.

If it makes any difference, the VM whose memory I'm trying to dump is a HVM
not PVM.

-- gyre --

Chad

unread,
Feb 14, 2012, 2:44:00 PM2/14/12
to vmitools
I'm actually running into this same problem. Seems to still persist
even after commenting out all of of the caching stuff. Looks like
there is a memory leak elsewhere in the library. Any insight as to
where I might start looking, or has this issue been corrected in an
unpublished version of the code?

Thanks in advance!

- Chad

Chad

unread,
Feb 15, 2012, 9:39:48 AM2/15/12
to vmitools
Bryan,

You can disregard my last post. The fix mentioned here did in fact
fix it. I had introduced some additional code that was interfering.
Thanks for all of your work!

Best,
Chad

Juan F.

unread,
Mar 15, 2012, 3:30:09 PM3/15/12
to vmitools
in the dump-memory.c. Did you just changed that part of the code? Did
you just replace the memory variable for the mem2 or you created a new
one?

LIkewise, Does the memory_cache_insert function in the memory_cache.c
has to look like this?: (specially in the conversion from &key to key
in the condition area)

memory_cache_entry_t entry = NULL;
*offset = paddr & (vmi->page_size - 1);
paddr &= ~(vmi->page_size - 1);
gint64 * key = malloc(sizeof(gint64));
*key paddr;

if ((entry = g_hash_table_lookup(vmi->memory_cache, key)) != NULL)
{
dbprint("--MEMORY cache hit 0x%.8x\n", paddr);
return validate_and_return_data(vmi, entry);
}
else{
dbprint("--MEMORY cache set 0x%.8x\n", paddr);
entry = create_new_entry(vmi, paddr, vmi->page_size);
g_hash_table_insert(vmi->memory_cache, key, entry);
return entry->data;
}

Thank you guys I am just a little bit confuse with all this. If you
have a chance to add the updated driver and dump-memory example, I
would really appreciate it.

gyre

unread,
Mar 29, 2012, 10:14:54 AM3/29/12
to vmit...@googlegroups.com
Can I submit this patch to 0.9_alpha for the dump_memory.c file?  Is there an easier way I can submit patches to the codebase?

Thanks.

-- gyre --

[code]
diff --git a/examples/dump-memory.c b/examples/dump-memory.c
index fbef451..a6b5ccc 100644
--- a/examples/dump-memory.c
+++ b/examples/dump-memory.c
@@ -38,7 +38,6 @@ int main (int argc, char **argv)
     vmi_instance_t vmi;
     char *filename = NULL;
     FILE *f = NULL;
-    unsigned char *memory = NULL;
     uint32_t offset = 0;
     addr_t address = 0;
 
@@ -61,16 +60,16 @@ int main (int argc, char **argv)
     }
 
     while (address < vmi_get_memsize(vmi)){
+        unsigned char memory [PAGE_SIZE];

 
         /* write memory to file */
         if (PAGE_SIZE == vmi_read_pa(vmi, address, memory, PAGE_SIZE)){
-            /* memory mapped, just write to file */

             size_t written = fwrite(memory, 1, PAGE_SIZE, f);
+       
             if (written != PAGE_SIZE){
                 printf("failed to write memory to file.\n");
                 goto error_exit;
             }
-            munmap(memory, PAGE_SIZE);
         }
         else{
             /* memory not mapped, write zeros to maintain offset */
@@ -89,7 +88,6 @@ int main (int argc, char **argv)
     }
 
 error_exit:
-    if (memory) free(memory);
     if (f) fclose(f);
 
     /* cleanup any memory associated with the libvmi instance */

[/code]

Bryan D. Payne

unread,
Mar 29, 2012, 11:24:55 AM3/29/12
to vmit...@googlegroups.com
Patches are always appreciated. Please submit the patch as an
attachment. Also, please state the problem that you are fixing /
reason for the patch.

Thanks,
bryan

> --
> You received this message because you are subscribed to the Google Groups
> "vmitools" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/vmitools/-/4T5WgEBX8mcJ.
>
> To post to this group, send email to vmit...@googlegroups.com.
> To unsubscribe from this group, send email to
> vmitools+u...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/vmitools?hl=en.

Reply all
Reply to author
Forward
0 new messages