"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:
parent
509f1174ce
commit
4aedc06701
|
@ -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");
|
||||||
|
|
Loading…
Reference in New Issue