Example #1
0
void
TeamDebugger::_HandleInspectAddress(target_addr_t address,
	TeamMemoryBlock::Listener* listener)
{
	TRACE_CONTROL("TeamDebugger::_HandleInspectAddress(%" B_PRIx64 ", %p)\n",
		address, listener);

	TeamMemoryBlock* memoryBlock = fMemoryBlockManager
		->GetMemoryBlock(address);

	if (memoryBlock == NULL) {
		_NotifyUser("Inspect Address", "Failed to allocate memory block");
		return;
	}

	if (!memoryBlock->HasListener(listener))
		memoryBlock->AddListener(listener);

	if (!memoryBlock->IsValid()) {
		AutoLocker< ::Team> teamLocker(fTeam);

		TeamMemory* memory = fTeam->GetTeamMemory();
		// schedule the job
		status_t result;
		if ((result = fWorker->ScheduleJob(
			new(std::nothrow) RetrieveMemoryBlockJob(fTeam, memory,
				memoryBlock),
			this)) != B_OK) {
			memoryBlock->ReleaseReference();
			_NotifyUser("Inspect Address", "Failed to retrieve memory data: %s",
				strerror(result));
		}
	} else
		memoryBlock->NotifyDataRetrieved();

}
Example #2
0
void
InspectorWindow::MessageReceived(BMessage* message)
{
	switch (message->what) {
		case MSG_THREAD_STATE_CHANGED:
		{
			::Thread* thread;
			if (message->FindPointer("thread",
					reinterpret_cast<void**>(&thread)) != B_OK) {
				break;
			}

			BReference< ::Thread> threadReference(thread, true);
			if (thread->State() == THREAD_STATE_STOPPED) {
				if (fCurrentBlock != NULL) {
					_SetCurrentBlock(NULL);
					_SetToAddress(fCurrentAddress);
				}
			}
			break;
		}
		case MSG_INSPECT_ADDRESS:
		{
			target_addr_t address = 0;
			if (message->FindUInt64("address", &address) != B_OK) {
				if (fAddressInput->TextView()->TextLength() == 0)
					break;

				fExpressionInfo->SetTo(fAddressInput->Text());

				fListener->ExpressionEvaluationRequested(fLanguage,
					fExpressionInfo);
			} else
				_SetToAddress(address);
			break;
		}
		case MSG_EXPRESSION_EVALUATED:
		{
			BString errorMessage;
			BReference<ExpressionResult> reference;
			ExpressionResult* value = NULL;
			if (message->FindPointer("value",
					reinterpret_cast<void**>(&value)) == B_OK) {
				reference.SetTo(value, true);
				if (value->Kind() == EXPRESSION_RESULT_KIND_PRIMITIVE) {
					Value* primitive = value->PrimitiveValue();
					BVariant variantValue;
					primitive->ToVariant(variantValue);
					if (variantValue.Type() == B_STRING_TYPE) {
						errorMessage.SetTo(variantValue.ToString());
					} else {
						_SetToAddress(variantValue.ToUInt64());
						break;
					}
				}
			} else {
				status_t result = message->FindInt32("result");
				errorMessage.SetToFormat("Failed to evaluate expression: %s",
					strerror(result));
			}

			BAlert* alert = new(std::nothrow) BAlert("Inspect Address",
				errorMessage.String(), "Close");
			if (alert != NULL)
				alert->Go();
			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;
			}

			if (result == B_OK) {
				_SetCurrentBlock(block);
				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;
		}
		case MSG_EDIT_CURRENT_BLOCK:
		{
			_SetEditMode(true);
			break;
		}
		case MSG_MEMORY_DATA_CHANGED:
		{
			if (fCurrentBlock == NULL)
				break;

			target_addr_t address;
			if (message->FindUInt64("address", &address) == B_OK
				&& address >= fCurrentBlock->BaseAddress()
				&& address < fCurrentBlock->BaseAddress()
					+ fCurrentBlock->Size()) {
				fCurrentBlock->Invalidate();
				_SetEditMode(false);
				fListener->InspectRequested(address, this);
			}
			break;
		}
		case MSG_COMMIT_MODIFIED_BLOCK:
		{
			// TODO: this could conceivably be extended to detect the
			// individual modified regions and only write those back.
			// That would require potentially submitting multiple separate
			// write requests, and thus require tracking all the writes being
			// waited upon for completion.
			fListener->MemoryWriteRequested(fCurrentBlock->BaseAddress(),
				fMemoryView->GetEditedData(), fCurrentBlock->Size());
			break;
		}
		case MSG_REVERT_MODIFIED_BLOCK:
		{
			_SetEditMode(false);
			break;
		}
		default:
		{
			BWindow::MessageReceived(message);
			break;
		}
	}
}
Example #3
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;
		}
	}
}
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());
	}
}