"page" debugger command:

* Various smaller fixes.
* Used add_debugger_command_etc() and added more verbose usage message.
* Added option "-m" which iterates through all address spaces and finds out
  which virtual pages are mapped to the page.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34979 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2010-01-09 20:27:11 +00:00
parent 509f1174ce
commit 4aedc06701
1 changed files with 88 additions and 28 deletions

View File

@ -339,50 +339,69 @@ page_state_to_string(int state)
static int static int
dump_page(int argc, char **argv) dump_page(int argc, char **argv)
{ {
struct vm_page *page; bool addressIsPointer = true;
addr_t address;
bool physical = false; bool physical = false;
bool searchMappings = false;
int32 index = 1; int32 index = 1;
if (argc > 2) { while (index < argc) {
if (!strcmp(argv[1], "-p")) { if (argv[index][0] != '-')
break;
if (!strcmp(argv[index], "-p")) {
addressIsPointer = false;
physical = true; physical = true;
index++; } else if (!strcmp(argv[index], "-v")) {
} else if (!strcmp(argv[1], "-v")) addressIsPointer = false;
index++; } else if (!strcmp(argv[index], "-m")) {
searchMappings = true;
} else {
print_debugger_command_usage(argv[0]);
return 0;
}
index++;
} }
if (argc < 2 if (index + 1 != argc) {
|| strlen(argv[index]) <= 2 print_debugger_command_usage(argv[0]);
|| argv[index][0] != '0'
|| argv[index][1] != 'x') {
kprintf("usage: page [-p|-v] <address>\n"
" -v looks up a virtual address for the page, -p a physical address.\n"
" Default is to look for the page structure address directly.\n");
return 0; return 0;
} }
address = strtoul(argv[index], NULL, 0); uint64 value;
if (!evaluate_debug_expression(argv[index], &value, false))
return 0;
if (index == 2) { addr_t pageAddress = (addr_t)value;
struct vm_page* page;
if (addressIsPointer) {
page = (struct vm_page *)pageAddress;
} else {
if (!physical) { if (!physical) {
VMAddressSpace *addressSpace = VMAddressSpace::Kernel(); VMAddressSpace *addressSpace = VMAddressSpace::Kernel();
uint32 flags;
if (thread_get_current_thread()->team->address_space != NULL) if (debug_get_debugged_thread()->team->address_space != NULL)
addressSpace = thread_get_current_thread()->team->address_space; addressSpace = debug_get_debugged_thread()->team->address_space;
addressSpace->TranslationMap().ops->query_interrupt( uint32 flags = 0;
&addressSpace->TranslationMap(), address, &address, &flags); if (addressSpace->TranslationMap().ops->query_interrupt(
&addressSpace->TranslationMap(), pageAddress, &pageAddress,
&flags) != B_OK
|| (flags & PAGE_PRESENT) == 0) {
kprintf("Virtual address not mapped to a physical page in this "
"address space.\n");
return 0;
}
} }
page = vm_lookup_page(address / B_PAGE_SIZE);
} else page = vm_lookup_page(pageAddress / B_PAGE_SIZE);
page = (struct vm_page *)address; }
kprintf("PAGE: %p\n", page); kprintf("PAGE: %p\n", page);
kprintf("queue_next,prev: %p, %p\n", page->queue_link.next, kprintf("queue_next,prev: %p, %p\n", page->queue_link.next,
page->queue_link.previous); page->queue_link.previous);
kprintf("physical_number: %lx\n", page->physical_page_number); kprintf("physical_number: %#lx\n", page->physical_page_number);
kprintf("cache: %p\n", page->cache); kprintf("cache: %p\n", page->cache);
kprintf("cache_offset: %ld\n", page->cache_offset); kprintf("cache_offset: %ld\n", page->cache_offset);
kprintf("cache_next: %p\n", page->cache_next); kprintf("cache_next: %p\n", page->cache_next);
@ -402,10 +421,39 @@ dump_page(int argc, char **argv)
vm_page_mappings::Iterator iterator = page->mappings.GetIterator(); vm_page_mappings::Iterator iterator = page->mappings.GetIterator();
vm_page_mapping *mapping; vm_page_mapping *mapping;
while ((mapping = iterator.Next()) != NULL) { while ((mapping = iterator.Next()) != NULL) {
kprintf(" %p (%#lx)\n", mapping->area, mapping->area->id); kprintf(" %p (%" B_PRId32 ")\n", mapping->area, mapping->area->id);
mapping = mapping->page_link.next; mapping = mapping->page_link.next;
} }
if (searchMappings) {
kprintf("all mappings:\n");
VMAddressSpace* addressSpace = VMAddressSpace::DebugFirst();
while (addressSpace != NULL) {
size_t pageCount = addressSpace->Size() / B_PAGE_SIZE;
for (addr_t address = addressSpace->Base(); pageCount != 0;
address += B_PAGE_SIZE, pageCount--) {
addr_t physicalAddress;
uint32 flags = 0;
if (addressSpace->TranslationMap().ops->query_interrupt(
&addressSpace->TranslationMap(), address,
&physicalAddress, &flags) == B_OK
&& (flags & PAGE_PRESENT) != 0
&& physicalAddress / B_PAGE_SIZE
== page->physical_page_number) {
VMArea* area = addressSpace->LookupArea(address);
kprintf(" aspace %ld, area %ld: %#" B_PRIxADDR
" (%c%c%s%s)\n", addressSpace->ID(),
area != NULL ? area->id : -1, address,
(flags & B_KERNEL_READ_AREA) != 0 ? 'r' : '-',
(flags & B_KERNEL_WRITE_AREA) != 0 ? 'w' : '-',
(flags & PAGE_MODIFIED) != 0 ? " modified" : "",
(flags & PAGE_ACCESSED) != 0 ? " accessed" : "");
}
}
addressSpace = VMAddressSpace::DebugNext(addressSpace);
}
}
return 0; return 0;
} }
@ -1870,8 +1918,20 @@ vm_page_init_post_area(kernel_args *args)
PAGE_ALIGN(sNumPages * sizeof(vm_page)), B_ALREADY_WIRED, PAGE_ALIGN(sNumPages * sizeof(vm_page)), B_ALREADY_WIRED,
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA); B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
add_debugger_command("page_stats", &dump_page_stats, "Dump statistics about page usage"); add_debugger_command("page_stats", &dump_page_stats,
add_debugger_command("page", &dump_page, "Dump page info"); "Dump statistics about page usage");
add_debugger_command_etc("page", &dump_page,
"Dump page info",
"[ \"-p\" | \"-v\" ] [ \"-m\" ] <address>\n"
"Prints information for the physical page. If neither \"-p\" nor\n"
"\"-v\" are given, the provided address is interpreted as address of\n"
"the vm_page data structure for the page in question. If \"-p\" is\n"
"given, the address is the physical address of the page. If \"-v\" is\n"
"given, the address is interpreted as virtual address in the current\n"
"thread's address space and for the page it is mapped to (if any)\n"
"information are printed. If \"-m\" is specified, the command will\n"
"search all known address spaces for mappings to that page and print\n"
"them.\n", 0);
add_debugger_command("page_queue", &dump_page_queue, "Dump page queue"); add_debugger_command("page_queue", &dump_page_queue, "Dump page queue");
add_debugger_command("find_page", &find_page, add_debugger_command("find_page", &find_page,
"Find out which queue a page is actually in"); "Find out which queue a page is actually in");