예제 #1
0
void
InspectorWindow::MessageReceived(BMessage* message)
{
	switch (message->what) {
		case MSG_INSPECT_ADDRESS:
		{
			target_addr_t address = 0;
			bool addressValid = false;
			if (message->FindUInt64("address", &address) != B_OK) {
				ExpressionParser parser;
				parser.SetSupportHexInput(true);
				const char* addressExpression = fAddressInput->Text();
				BString errorMessage;
				try {
					address = parser.EvaluateToInt64(addressExpression);
				} catch(ParseException parseError) {
					errorMessage.SetToFormat("Failed to parse address: %s",
						parseError.message.String());
				} catch(...) {
					errorMessage.SetToFormat(
						"Unknown error while parsing address");
				}

				if (errorMessage.Length() > 0) {
					BAlert* alert = new(std::nothrow) BAlert("Inspect Address",
						errorMessage.String(), "Close");
					if (alert != NULL)
						alert->Go();
				} else
					addressValid = true;
			} else {
				addressValid = true;
			}

			if (addressValid) {
				fCurrentAddress = address;
				if (fCurrentBlock == NULL
					|| !fCurrentBlock->Contains(address)) {
					fListener->InspectRequested(address, this);
				} else
					fMemoryView->SetTargetAddress(fCurrentBlock, address);
			}
			break;
		}
		case MSG_NAVIGATE_PREVIOUS_BLOCK:
		case MSG_NAVIGATE_NEXT_BLOCK:
		{
			if (fCurrentBlock != NULL) {
				target_addr_t address = fCurrentBlock->BaseAddress();
				if (message->what == MSG_NAVIGATE_PREVIOUS_BLOCK)
					address -= fCurrentBlock->Size();
				else
					address += fCurrentBlock->Size();

				BMessage setMessage(MSG_INSPECT_ADDRESS);
				setMessage.AddUInt64("address", address);
				PostMessage(&setMessage);
			}
			break;
		}
		case MSG_MEMORY_BLOCK_RETRIEVED:
		{
			TeamMemoryBlock* block = NULL;
			status_t result;
			if (message->FindPointer("block",
					reinterpret_cast<void **>(&block)) != B_OK
				|| message->FindInt32("result", &result) != B_OK) {
				break;
			}

			{
				AutoLocker< ::Team> teamLocker(fTeam);
				block->RemoveListener(this);
			}

			if (result == B_OK) {
				if (fCurrentBlock != NULL)
					fCurrentBlock->ReleaseReference();

				fCurrentBlock = block;
				fMemoryView->SetTargetAddress(block, fCurrentAddress);
				fPreviousBlockButton->SetEnabled(true);
				fNextBlockButton->SetEnabled(true);
			} else {
				BString errorMessage;
				errorMessage.SetToFormat("Unable to read address 0x%" B_PRIx64
					": %s", block->BaseAddress(), strerror(result));

				BAlert* alert = new(std::nothrow) BAlert("Inspect address",
					errorMessage.String(), "Close");
				if (alert == NULL)
					break;

				alert->Go(NULL);
				block->ReleaseReference();
			}
			break;
		}
		default:
		{
			BWindow::MessageReceived(message);
			break;
		}
	}
}
예제 #2
0
void
InspectorWindow::MessageReceived(BMessage* msg)
{
	switch (msg->what) {
		case MSG_INSPECT_ADDRESS:
		{
			target_addr_t address = 0;
			bool addressValid = false;
			if (msg->FindUInt64("address", &address) != B_OK)
			{
				ExpressionParser parser;
				parser.SetSupportHexInput(true);
				const char* addressExpression = fAddressInput->Text();
				BString errorMessage;
				try {
					address = parser.EvaluateToInt64(addressExpression);
				} catch(ParseException parseError) {
					errorMessage.SetToFormat("Failed to parse address: %s",
						parseError.message.String());
				} catch(...) {
					errorMessage.SetToFormat(
						"Unknown error while parsing address");
				}

				if (errorMessage.Length() > 0) {
					BAlert* alert = new(std::nothrow) BAlert("Inspect Address",
						errorMessage.String(), "Close");
					if (alert != NULL)
						alert->Go();
				} else
					addressValid = true;
			} else {
				addressValid = true;
			}

			if (addressValid) {
				if (fCurrentBlock != NULL
					&& !fCurrentBlock->Contains(address)) {
					fCurrentBlock->ReleaseReference();
					fCurrentBlock = NULL;
				}

				if (fCurrentBlock == NULL)
					fListener->InspectRequested(address, this);
				else
					fMemoryView->SetTargetAddress(fCurrentBlock, address);

				fCurrentAddress = address;
				BString computedAddress;
				computedAddress.SetToFormat("0x%" B_PRIx64, address);
				fAddressInput->SetText(computedAddress.String());
			}
			break;
		}
		case MSG_NAVIGATE_PREVIOUS_BLOCK:
		case MSG_NAVIGATE_NEXT_BLOCK:
		{
			if (fCurrentBlock != NULL)
			{
				target_addr_t address = fCurrentBlock->BaseAddress();
				if (msg->what == MSG_NAVIGATE_PREVIOUS_BLOCK)
					address -= fCurrentBlock->Size();
				else
					address += fCurrentBlock->Size();

				BMessage setMessage(MSG_INSPECT_ADDRESS);
				setMessage.AddUInt64("address", address);
				PostMessage(&setMessage);
			}
			break;
		}
		default:
		{
			BWindow::MessageReceived(msg);
			break;
		}
	}
}
void
CliDumpMemoryCommand::Execute(int argc, const char* const* argv,
	CliContext& context)
{
	if (argc < 2) {
		PrintUsage(argv[0]);
		return;
	}

	target_addr_t address;
	ExpressionParser parser;
	parser.SetSupportHexInput(true);

	try {
		address = parser.EvaluateToInt64(argv[1]);
	} catch(...) {
		printf("Error parsing address/expression.\n");
		return;
	}

	int32 itemSize = 0;
	int32 displayWidth = 0;

	// build the format string
	if (strcmp(argv[0], "db") == 0) {
		itemSize = 1;
		displayWidth = 16;
	} else if (strcmp(argv[0], "ds") == 0) {
		itemSize = 2;
		displayWidth = 8;
	} else if (strcmp(argv[0], "dw") == 0) {
		itemSize = 4;
		displayWidth = 4;
	} else if (strcmp(argv[0], "dl") == 0) {
		itemSize = 8;
		displayWidth = 2;
	} else if (strcmp(argv[0], "string") == 0) {
		itemSize = 1;
		displayWidth = -1;
	} else {
		printf("dump called in an invalid way!\n");
		return;
	}

	int32 num = 0;
	if (argc == 3) {
		char *remainder;
		num = strtol(argv[2], &remainder, 0);
		if (*remainder != '\0') {
			printf("Error: invalid parameter \"%s\"\n", argv[2]);
		}
	}

	if (num <= 0)
		num = displayWidth;

	TeamMemoryBlock* block = context.CurrentBlock();
	if (block == NULL || !block->Contains(address)) {
		context.GetUserInterfaceListener()->InspectRequested(address,
			&context);
		context.WaitForEvents(CliContext::EVENT_TEAM_MEMORY_BLOCK_RETRIEVED);
		if (context.IsTerminating())
			return;
		block = context.CurrentBlock();
	}

	if (!strcmp(argv[0], "string")) {
		printf("%p \"", (char*)address);

		target_addr_t offset = address;
		char c;
		while (block->Contains(offset)) {
			c = *(block->Data() + offset - block->BaseAddress());

			if (c == '\0')
				break;
			if (c == '\n')
				printf("\\n");
			else if (c == '\t')
				printf("\\t");
			else {
				if (!isprint(c))
					c = '.';

				printf("%c", c);
			}
			++offset;
		}

		printf("\"\n");
	} else {
		BString output;
		UiUtils::DumpMemory(output, 0, block, address, itemSize, displayWidth,
			num);
		printf("%s\n", output.String());
	}
}