Merge branch 'master' into sam460ex

This commit is contained in:
François Revol 2012-12-19 15:44:14 +01:00
commit 98191ec624
28 changed files with 682 additions and 103 deletions

View File

@ -29,7 +29,11 @@ if [ IsOptionalHaikuImagePackageAdded OpenSSL ] {
}
if $(HAIKU_GCC_VERSION[1]) >= 4 {
HAIKU_OPENSSL_PACKAGE = openssl-1.0.0j-r1a4-x86-gcc4-2012-08-29.zip ;
if $(TARGET_ARCH) = x86_64 {
HAIKU_OPENSSL_PACKAGE = openssl-1.0.0j-x86_64-2012-12-18.zip ;
} else {
HAIKU_OPENSSL_PACKAGE = openssl-1.0.0j-r1a4-x86-gcc4-2012-08-29.zip ;
}
} else {
HAIKU_OPENSSL_PACKAGE = openssl-1.0.0j-r1a4-x86-gcc2-2012-08-26.zip ;
}
@ -37,9 +41,7 @@ if $(HAIKU_GCC_VERSION[1]) >= 4 {
HAIKU_OPENSSL_URL = $(baseURL)/$(HAIKU_OPENSSL_PACKAGE) ;
if $(HAIKU_BUILD_FEATURE_SSL) {
if $(TARGET_ARCH) != x86 {
Echo "SSL build feature not available for $(TARGET_ARCH)" ;
} else {
if $(TARGET_ARCH) = x86 || $(TARGET_ARCH) = x86_64 {
# Download the zip archive.
local zipFile = [ DownloadFile $(HAIKU_OPENSSL_PACKAGE)
: $(HAIKU_OPENSSL_URL) ] ;
@ -66,6 +68,8 @@ if $(HAIKU_BUILD_FEATURE_SSL) {
= [ FDirName $(HAIKU_OPENSSL_DIR) common include ] ;
EnableBuildFeatures openssl ;
} else {
Echo "SSL build feature not available for $(TARGET_ARCH)" ;
}
}

View File

@ -119,6 +119,13 @@ AddFilesToHaikuImage system : <revisioned>kernel_$(TARGET_ARCH) ;
AddLibrariesToHaikuHybridImage system lib
: $(SYSTEM_LIBS) $(PRIVATE_SYSTEM_LIBS) ;
OPTIONAL_LIBS_ALIASES =
libfreetype.so
libjpeg.so
libpng.so
libz.so
;
# libfreetype.so links to the current freetype lib
AddSymlinkToHaikuHybridImage system lib : $(HAIKU_FREETYPE_CURRENT_LIB:BS)
: $(HAIKU_FREETYPE_CURRENT_LINK) : : true ;

View File

@ -44,8 +44,8 @@ SYSTEM_BIN = [ FFilterByBuildFeatures
SYSTEM_APPS = [ FFilterByBuildFeatures
AboutSystem ActivityMonitor BootManager@x86 CharacterMap
CodyCam DeskCalc Devices DiskProbe DiskUsage DriveSetup CDPlayer Expander
GLInfo@x86 Icon-O-Matic Installer LaunchBox Magnify Mail
CodyCam DeskCalc Devices DiskProbe DiskUsage DriveSetup CDPlayer Debugger
Expander GLInfo@x86 Icon-O-Matic Installer LaunchBox Magnify Mail
MediaConverter MediaPlayer MidiPlayer NetworkStatus PackageInstaller People
PoorMan PowerStatus ProcessController Screenshot ShowImage SoundRecorder
StyledEdit Terminal TextSearch TV WebWatch Workspaces
@ -75,7 +75,7 @@ SYSTEM_LIBS = [ FFilterByBuildFeatures
PRIVATE_SYSTEM_LIBS = [ FFilterByBuildFeatures
$(HAIKU_JPEG_CURRENT_LIB)
$(HAIKU_LIBPNG_CURRENT_LIB)
$(HAIKU_ZLIB_CURRENT_LIB)
$(HAIKU_ZLIB_CURRENT_LIB)
$(HAIKU_FREETYPE_CURRENT_LIB)
libalm.so
libfluidsynth.so

View File

@ -643,7 +643,6 @@ if [ IsOptionalHaikuImagePackageAdded DemoPackage_Video ] {
# Development
if [ IsOptionalHaikuImagePackageAdded Development ] {
if $(TARGET_ARCH) = x86 {
AddFilesToHaikuImage system apps : Debugger ;
AddSymlinkToHaikuImage home config settings deskbar Applications
: /boot/system/apps/Debugger : Debugger ;
# autotools
@ -1661,16 +1660,11 @@ if [ IsOptionalHaikuImagePackageAdded OpenSSH ] {
# OpenSSL
if [ IsOptionalHaikuImagePackageAdded OpenSSL ] {
if $(TARGET_ARCH) != x86 {
Echo "No optional package OpenSSL available for $(TARGET_ARCH)" ;
if $(TARGET_ARCH) = x86 || $(TARGET_ARCH) = x86_64 {
InstallOptionalHaikuImagePackage $(HAIKU_OPENSSL_PACKAGE)
: $(HAIKU_OPENSSL_URL) ;
} else {
if $(HAIKU_GCC_VERSION[1]) >= 4 {
InstallOptionalHaikuImagePackage $(HAIKU_OPENSSL_PACKAGE)
: $(HAIKU_OPENSSL_URL) ;
} else {
InstallOptionalHaikuImagePackage $(HAIKU_OPENSSL_PACKAGE)
: $(HAIKU_OPENSSL_URL) ;
}
Echo "No optional package OpenSSL available for $(TARGET_ARCH)" ;
}
}

View File

@ -14,8 +14,6 @@
#include <String.h>
class Tokenizer;
class ParseException {
public:
ParseException(const char* message, int32 position)
@ -35,10 +33,10 @@ class ParseException {
};
struct Function;
struct Token;
class MAPM;
class ExpressionParser {
public:
ExpressionParser();
~ExpressionParser();
@ -52,6 +50,10 @@ class ExpressionParser {
int64 EvaluateToInt64(const char* expressionString);
double EvaluateToDouble(const char* expressionString);
private:
struct Token;
class Tokenizer;
private:
MAPM _ParseBinary();
MAPM _ParseSum();

View File

@ -602,7 +602,7 @@ ActivityView::~ActivityView()
delete fSystemInfoHandler;
// replicant deleted, destroy the about window
if (fAboutWindow != NULL)
if (fAboutWindow != NULL && fAboutWindow->Lock())
fAboutWindow->Quit();
}

View File

@ -193,12 +193,14 @@ Application Debugger :
CliContext.cpp
CliContinueCommand.cpp
CliDebugReportCommand.cpp
CliDumpMemoryCommand.cpp
CliPrintVariableCommand.cpp
CliQuitCommand.cpp
CliStackFrameCommand.cpp
CliStackTraceCommand.cpp
CliStopCommand.cpp
CliThreadCommand.cpp
CliThreadsCommand.cpp
CliQuitCommand.cpp
CliVariablesCommand.cpp
CommandLineUserInterface.cpp

View File

@ -46,6 +46,7 @@ DebugReportGenerator::DebugReportGenerator(::Team* team,
fNodeManager(NULL),
fListener(listener),
fWaitingNode(NULL),
fCurrentBlock(NULL),
fTraceWaitingThread(NULL)
{
fTeam->AddListener(this);
@ -61,6 +62,9 @@ DebugReportGenerator::~DebugReportGenerator()
fNodeManager->RemoveListener(this);
fNodeManager->ReleaseReference();
}
if (fCurrentBlock != NULL)
fCurrentBlock->ReleaseReference();
}
@ -161,6 +165,19 @@ DebugReportGenerator::ThreadStackTraceChanged(const ::Team::ThreadEvent& event)
}
void
DebugReportGenerator::MemoryBlockRetrieved(TeamMemoryBlock* block)
{
if (fCurrentBlock != NULL) {
fCurrentBlock->ReleaseReference();
fCurrentBlock = NULL;
}
fCurrentBlock = block;
release_sem(fTeamDataSem);
}
void
DebugReportGenerator::ValueNodeValueChanged(ValueNode* node)
{
@ -323,6 +340,9 @@ DebugReportGenerator::_DumpDebuggedThreadInfo(BString& _output,
_output << data;
if (frame->CountParameters() == 0
&& frame->CountLocalVariables() == 0) {
// only dump the topmost frame
if (i == 0)
_DumpStackFrameMemory(_output, thread->GetCpuState());
continue;
}
@ -338,7 +358,7 @@ DebugReportGenerator::_DumpDebuggedThreadInfo(BString& _output,
containerLocker.Unlock();
_ResolveValueIfNeeded(child->Node(), frame, 1);
containerLocker.Lock();
UiUtils::PrintValueNodeGraph(_output, frame, child, 3, 1);
UiUtils::PrintValueNodeGraph(_output, child, 3, 1);
}
_output << "\n";
}
@ -362,6 +382,24 @@ DebugReportGenerator::_DumpDebuggedThreadInfo(BString& _output,
}
void
DebugReportGenerator::_DumpStackFrameMemory(BString& _output,
CpuState* state)
{
target_addr_t address = state->StackPointer();
if (fCurrentBlock == NULL || !fCurrentBlock->Contains(address)) {
fListener->InspectRequested(address, this);
status_t result = B_OK;
do {
result = acquire_sem(fTeamDataSem);
} while (result == B_INTERRUPTED);
}
_output << "\t\t\tFrame memory:\n";
UiUtils::DumpMemory(_output, 3, fCurrentBlock, address, 1, 16,
fCurrentBlock->BaseAddress() + fCurrentBlock->Size() - address);
}
status_t
DebugReportGenerator::_ResolveValueIfNeeded(ValueNode* node, StackFrame* frame,
int32 maxDepth)
@ -371,7 +409,9 @@ DebugReportGenerator::_ResolveValueIfNeeded(ValueNode* node, StackFrame* frame,
fWaitingNode = node;
fListener->ValueNodeValueRequested(frame->GetCpuState(),
fNodeManager->GetContainer(), node);
result = acquire_sem(fTeamDataSem);
do {
result = acquire_sem(fTeamDataSem);
} while (result == B_INTERRUPTED);
}
if (node->LocationAndValueResolutionState() == B_OK && maxDepth > 0) {
@ -380,10 +420,6 @@ DebugReportGenerator::_ResolveValueIfNeeded(ValueNode* node, StackFrame* frame,
for (int32 i = 0; i < node->CountChildren(); i++) {
ValueNodeChild* child = node->ChildAt(i);
containerLocker.Unlock();
result = _ResolveLocationIfNeeded(child, frame);
if (result != B_OK)
continue;
result = fNodeManager->AddChildNodes(child);
if (result != B_OK)
continue;
@ -402,18 +438,3 @@ DebugReportGenerator::_ResolveValueIfNeeded(ValueNode* node, StackFrame* frame,
return result;
}
status_t
DebugReportGenerator::_ResolveLocationIfNeeded(ValueNodeChild* child,
StackFrame* frame)
{
ValueLocation* location = NULL;
ValueLoader loader(fTeam->GetArchitecture(), fTeam->GetTeamMemory(),
fTeam->GetTeamTypeInformation(), frame->GetCpuState());
status_t result = child->ResolveLocation(&loader, location);
child->SetLocation(location, result);
if (location != NULL)
location->ReleaseReference();
return result;
}

View File

@ -9,6 +9,7 @@
#include <Looper.h>
#include "Team.h"
#include "TeamMemoryBlock.h"
#include "ValueNodeContainer.h"
@ -26,7 +27,7 @@ class ValueNodeManager;
class DebugReportGenerator : public BLooper, private Team::Listener,
private ValueNodeContainer::Listener {
private TeamMemoryBlock::Listener, private ValueNodeContainer::Listener {
public:
DebugReportGenerator(::Team* team,
UserInterfaceListener* listener);
@ -39,21 +40,28 @@ public:
virtual void MessageReceived(BMessage* message);
private:
// Team::Listener
virtual void ThreadStackTraceChanged(
const Team::ThreadEvent& event);
// TeamMemoryBlock::Listener
virtual void MemoryBlockRetrieved(TeamMemoryBlock* block);
// ValueNodeContainer::Listener
virtual void ValueNodeValueChanged(ValueNode* node);
private:
status_t _GenerateReport(const entry_ref& outputPath);
status_t _GenerateReportHeader(BString& output);
status_t _DumpLoadedImages(BString& output);
status_t _DumpRunningThreads(BString& output);
status_t _DumpDebuggedThreadInfo(BString& output,
status_t _GenerateReportHeader(BString& _output);
status_t _DumpLoadedImages(BString& _output);
status_t _DumpRunningThreads(BString& _output);
status_t _DumpDebuggedThreadInfo(BString& _output,
::Thread* thread);
void _DumpStackFrameMemory(BString& _output,
CpuState* state);
status_t _ResolveLocationIfNeeded(ValueNodeChild* child,
StackFrame* frame);
status_t _ResolveValueIfNeeded(ValueNode* node,
StackFrame* frame, int32 maxDepth);
@ -64,6 +72,7 @@ private:
ValueNodeManager* fNodeManager;
UserInterfaceListener* fListener;
ValueNode* fWaitingNode;
TeamMemoryBlock* fCurrentBlock;
::Thread* fTraceWaitingThread;
};

View File

@ -26,10 +26,11 @@ static CliContext* sCurrentContext;
struct CliContext::Event : DoublyLinkedListLinkImpl<CliContext::Event> {
Event(int type, Thread* thread = NULL)
Event(int type, Thread* thread = NULL, TeamMemoryBlock* block = NULL)
:
fType(type),
fThreadReference(thread)
fThreadReference(thread),
fMemoryBlockReference(block)
{
}
@ -43,9 +44,15 @@ struct CliContext::Event : DoublyLinkedListLinkImpl<CliContext::Event> {
return fThreadReference.Get();
}
TeamMemoryBlock* GetMemoryBlock() const
{
return fMemoryBlockReference.Get();
}
private:
int fType;
BReference<Thread> fThreadReference;
BReference<TeamMemoryBlock> fMemoryBlockReference;
};
@ -68,7 +75,8 @@ CliContext::CliContext()
fTerminating(false),
fCurrentThread(NULL),
fCurrentStackTrace(NULL),
fCurrentStackFrameIndex(-1)
fCurrentStackFrameIndex(-1),
fCurrentBlock(NULL)
{
sCurrentContext = this;
}
@ -118,6 +126,7 @@ CliContext::Init(Team* team, UserInterfaceListener* listener)
fNodeManager = new(std::nothrow) ValueNodeManager();
if (fNodeManager == NULL)
return B_NO_MEMORY;
fNodeManager->AddListener(this);
return B_OK;
}
@ -150,6 +159,11 @@ CliContext::Cleanup()
fNodeManager->ReleaseReference();
fNodeManager = NULL;
}
if (fCurrentBlock != NULL) {
fCurrentBlock->ReleaseReference();
fCurrentBlock = NULL;
}
}
@ -316,6 +330,25 @@ CliContext::WaitForThreadOrUser()
}
void
CliContext::WaitForEvents(int32 eventMask)
{
for (;;) {
_PrepareToWaitForEvents(eventMask | EVENT_USER_INTERRUPT);
uint32 events = fEventsOccurred;
if ((events & eventMask) == 0) {
events = _WaitForEvents();
}
if ((events & EVENT_QUIT) != 0 || (events & eventMask) != 0) {
_SignalInputLoop(eventMask);
ProcessPendingEvents();
return;
}
}
}
void
CliContext::ProcessPendingEvents()
{
@ -356,6 +389,13 @@ CliContext::ProcessPendingEvents()
SetCurrentStackFrameIndex(0);
}
break;
case EVENT_TEAM_MEMORY_BLOCK_RETRIEVED:
if (fCurrentBlock != NULL) {
fCurrentBlock->ReleaseReference();
fCurrentBlock = NULL;
}
fCurrentBlock = event->GetMemoryBlock();
break;
}
}
}
@ -404,6 +444,45 @@ CliContext::ThreadStackTraceChanged(const Team::ThreadEvent& threadEvent)
}
void
CliContext::MemoryBlockRetrieved(TeamMemoryBlock* block)
{
_QueueEvent(
new(std::nothrow) Event(EVENT_TEAM_MEMORY_BLOCK_RETRIEVED,
NULL, block));
_SignalInputLoop(EVENT_TEAM_MEMORY_BLOCK_RETRIEVED);
}
void
CliContext::ValueNodeChanged(ValueNodeChild* nodeChild, ValueNode* oldNode,
ValueNode* newNode)
{
_SignalInputLoop(EVENT_VALUE_NODE_CHANGED);
}
void
CliContext::ValueNodeChildrenCreated(ValueNode* node)
{
_SignalInputLoop(EVENT_VALUE_NODE_CHANGED);
}
void
CliContext::ValueNodeChildrenDeleted(ValueNode* node)
{
_SignalInputLoop(EVENT_VALUE_NODE_CHANGED);
}
void
CliContext::ValueNodeValueChanged(ValueNode* oldNode)
{
_SignalInputLoop(EVENT_VALUE_NODE_CHANGED);
}
void
CliContext::_QueueEvent(Event* event)
{

View File

@ -13,16 +13,21 @@
#include <Locker.h>
#include "Team.h"
#include "TeamMemoryBlock.h"
#include "ValueNodeContainer.h"
class StackFrame;
class StackTrace;
class Team;
class TeamMemoryBlock;
class UserInterfaceListener;
class ValueNodeManager;
class CliContext : private Team::Listener {
class CliContext : private Team::Listener,
public TeamMemoryBlock::Listener,
private ValueNodeContainer::Listener {
public:
enum {
EVENT_QUIT = 0x01,
@ -30,7 +35,9 @@ public:
EVENT_THREAD_ADDED = 0x04,
EVENT_THREAD_REMOVED = 0x08,
EVENT_THREAD_STOPPED = 0x10,
EVENT_THREAD_STACK_TRACE_CHANGED = 0x20
EVENT_THREAD_STACK_TRACE_CHANGED = 0x20,
EVENT_VALUE_NODE_CHANGED = 0x40,
EVENT_TEAM_MEMORY_BLOCK_RETRIEVED = 0x80
};
public:
@ -64,12 +71,15 @@ public:
{ return fCurrentStackFrameIndex; }
void SetCurrentStackFrameIndex(int32 index);
TeamMemoryBlock* CurrentBlock() const { return fCurrentBlock; }
const char* PromptUser(const char* prompt);
void AddLineToInputHistory(const char* line);
void QuitSession(bool killTeam);
void WaitForThreadOrUser();
void WaitForEvents(int32 eventMask);
void ProcessPendingEvents();
private:
@ -87,6 +97,16 @@ private:
virtual void ThreadStackTraceChanged(
const Team::ThreadEvent& event);
// TeamMemoryBlock::Listener
virtual void MemoryBlockRetrieved(TeamMemoryBlock* block);
// ValueNodeContainer::Listener
virtual void ValueNodeChanged(ValueNodeChild* nodeChild,
ValueNode* oldNode, ValueNode* newNode);
virtual void ValueNodeChildrenCreated(ValueNode* node);
virtual void ValueNodeChildrenDeleted(ValueNode* node);
virtual void ValueNodeValueChanged(ValueNode* node);
private:
void _QueueEvent(Event* event);
@ -113,6 +133,7 @@ private:
Thread* fCurrentThread;
StackTrace* fCurrentStackTrace;
int32 fCurrentStackFrameIndex;
TeamMemoryBlock* fCurrentBlock;
EventList fPendingEvents;
};

View File

@ -0,0 +1,127 @@
/*
* Copyright 2012, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#include "CliDumpMemoryCommand.h"
#include <ctype.h>
#include <stdio.h>
#include <AutoLocker.h>
#include <ExpressionParser.h>
#include "CliContext.h"
#include "Team.h"
#include "TeamMemoryBlock.h"
#include "UiUtils.h"
#include "UserInterface.h"
CliDumpMemoryCommand::CliDumpMemoryCommand()
:
CliCommand("dump contents of debugged team's memory",
"%s [\"]address|expression[\"] [num]\n"
"Reads and displays the contents of memory at the target address.")
{
}
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());
}
}

View File

@ -0,0 +1,22 @@
/*
* Copyright 2012, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#ifndef CLI_DUMP_MEMORY_COMMAND_H
#define CLI_DUMP_MEMORY_COMMAND_H
#include "CliCommand.h"
class CliDumpMemoryCommand : public CliCommand {
public:
CliDumpMemoryCommand();
virtual void Execute(int argc, const char* const* argv,
CliContext& context);
private:
};
#endif // CLI_DUMP_MEMORY_COMMAND_H

View File

@ -0,0 +1,151 @@
/*
* Copyright 2012, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#include "CliPrintVariableCommand.h"
#include <stdio.h>
#include <AutoLocker.h>
#include "CliContext.h"
#include "StackFrame.h"
#include "StackTrace.h"
#include "Team.h"
#include "Type.h"
#include "UiUtils.h"
#include "UserInterface.h"
#include "ValueLoader.h"
#include "ValueLocation.h"
#include "ValueNode.h"
#include "ValueNodeContainer.h"
#include "ValueNodeManager.h"
CliPrintVariableCommand::CliPrintVariableCommand()
:
CliCommand("print value(s) of a variable",
"%s [--depth n] variable [variable2 ...]\n"
"Prints the value and members of the named variable.")
{
}
void
CliPrintVariableCommand::Execute(int argc, const char* const* argv,
CliContext& context)
{
if (argc < 2) {
PrintUsage(argv[0]);
return;
}
ValueNodeManager* manager = context.GetValueNodeManager();
ValueNodeContainer* container = manager->GetContainer();
AutoLocker<ValueNodeContainer> containerLocker(container);
if (container == NULL || container->CountChildren() == 0) {
printf("No variables available.\n");
return;
}
int32 depth = 1;
int32 i = 1;
for (; i < argc; i++) {
if (strcmp(argv[i], "--depth") == 0) {
if (i == argc - 1) {
printf("Error: An argument must be supplied for depth.\n");
return;
}
char* endPointer;
depth = strtol(argv[i + 1], &endPointer, 0);
if (*endPointer != '\0' || depth < 0) {
printf("Error: Invalid parameter \"%s\"\n", argv[i + 1]);
return;
}
i++;
}
else
break;
}
if (i == argc) {
printf("Error: At least one variable name must be supplied.\n");
return;
}
bool found = false;
while (i < argc) {
// TODO: support variable expressions in addition to just names.
const char* variableName = argv[i++];
for (int32 j = 0; ValueNodeChild* child = container->ChildAt(j); j++) {
if (child->Name() == variableName) {
found = true;
containerLocker.Unlock();
_ResolveValueIfNeeded(child->Node(), context, depth);
containerLocker.Lock();
BString data;
UiUtils::PrintValueNodeGraph(data, child, 1, depth);
printf("%s", data.String());
}
}
if (!found)
printf("No such variable: %s\n", variableName);
found = false;
}
}
status_t
CliPrintVariableCommand::_ResolveValueIfNeeded(ValueNode* node,
CliContext& context, int32 maxDepth)
{
StackFrame* frame = context.GetStackTrace()->FrameAt(
context.CurrentStackFrameIndex());
if (frame == NULL)
return B_BAD_DATA;
status_t result = B_OK;
ValueNodeManager* manager = context.GetValueNodeManager();
ValueNodeContainer* container = manager->GetContainer();
AutoLocker<ValueNodeContainer> containerLocker(container);
if (node->LocationAndValueResolutionState() == VALUE_NODE_UNRESOLVED) {
context.GetUserInterfaceListener()->ValueNodeValueRequested(
context.CurrentThread()->GetCpuState(), container, node);
while (node->LocationAndValueResolutionState()
== VALUE_NODE_UNRESOLVED) {
containerLocker.Unlock();
context.WaitForEvents(CliContext::EVENT_VALUE_NODE_CHANGED);
containerLocker.Lock();
if (context.IsTerminating())
return B_ERROR;
}
}
if (node->LocationAndValueResolutionState() == B_OK && maxDepth > 0) {
for (int32 i = 0; i < node->CountChildren(); i++) {
ValueNodeChild* child = node->ChildAt(i);
containerLocker.Unlock();
result = manager->AddChildNodes(child);
if (result != B_OK)
continue;
// since in the case of a pointer to a compound we hide
// the intervening compound, don't consider the hidden node
// a level for the purposes of depth traversal
if (node->GetType()->Kind() == TYPE_ADDRESS
&& child->GetType()->Kind() == TYPE_COMPOUND) {
_ResolveValueIfNeeded(child->Node(), context, maxDepth);
} else
_ResolveValueIfNeeded(child->Node(), context, maxDepth - 1);
containerLocker.Lock();
}
}
return result;
}

View File

@ -0,0 +1,30 @@
/*
* Copyright 2012, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#ifndef CLI_PRINT_VARIABLE_COMMAND_H
#define CLI_PRINT_VARIABLE_COMMAND_H
#include "CliCommand.h"
class Team;
class StackFrame;
class ValueNode;
class ValueNodeChild;
class CliPrintVariableCommand : public CliCommand {
public:
CliPrintVariableCommand();
virtual void Execute(int argc, const char* const* argv,
CliContext& context);
private:
status_t _ResolveValueIfNeeded(ValueNode* node,
CliContext& context, int32 maxDepth);
};
#endif // CLI_PRINT_VARIABLE_COMMAND_H

View File

@ -45,11 +45,11 @@ CliStackTraceCommand::Execute(int argc, const char* const* argv,
// get its stack trace
StackTrace* stackTrace = thread->GetStackTrace();
if (stackTrace == NULL) {
// TODO: Wait for stack trace!
printf("Current thread doesn't have a stack trace. Waiting not "
"implemented yet\n");
return;
while (stackTrace == NULL) {
context.WaitForEvents(CliContext::EVENT_THREAD_STACK_TRACE_CHANGED);
if (context.IsTerminating())
return;
stackTrace = thread->GetStackTrace();
}
BReference<StackTrace> stackTraceReference(stackTrace);
// hold a reference until we're done

View File

@ -18,6 +18,8 @@
#include "CliContext.h"
#include "CliContinueCommand.h"
#include "CliDebugReportCommand.h"
#include "CliDumpMemoryCommand.h"
#include "CliPrintVariableCommand.h"
#include "CliQuitCommand.h"
#include "CliStackFrameCommand.h"
#include "CliStackTraceCommand.h"
@ -309,10 +311,29 @@ CommandLineUserInterface::_RegisterCommands()
BReference<CliCommand> stackTraceCommandReference2(
stackTraceCommandReference.Get());
BReference<CliCommand> dumpCommandReference(
new(std::nothrow) CliDumpMemoryCommand, true);
BReference<CliCommand> dumpCommandReference2(
dumpCommandReference.Get());
if (!_RegisterCommand("db", dumpCommandReference.Detach()))
return B_NO_MEMORY;
dumpCommandReference = dumpCommandReference2.Get();
if (!_RegisterCommand("ds", dumpCommandReference.Detach()))
return B_NO_MEMORY;
dumpCommandReference = dumpCommandReference2.Get();
if (!_RegisterCommand("dw", dumpCommandReference.Detach()))
return B_NO_MEMORY;
dumpCommandReference = dumpCommandReference2.Get();
if (!_RegisterCommand("dl", dumpCommandReference.Detach()))
return B_NO_MEMORY;
if (!_RegisterCommand("string", dumpCommandReference2.Detach()))
return B_NO_MEMORY;
if (_RegisterCommand("bt", stackTraceCommandReference.Detach())
&& _RegisterCommand("continue", new(std::nothrow) CliContinueCommand)
&& _RegisterCommand("frame", new(std::nothrow) CliStackFrameCommand)
&& _RegisterCommand("help", new(std::nothrow) HelpCommand(this))
&& _RegisterCommand("print", new(std::nothrow) CliPrintVariableCommand)
&& _RegisterCommand("quit", new(std::nothrow) CliQuitCommand)
&& _RegisterCommand("save-report",
new(std::nothrow) CliDebugReportCommand)

View File

@ -7,6 +7,7 @@
#include "UiUtils.h"
#include <ctype.h>
#include <stdio.h>
#include <DateTime.h>
@ -18,6 +19,7 @@
#include "Image.h"
#include "StackFrame.h"
#include "Team.h"
#include "TeamMemoryBlock.h"
#include "Thread.h"
#include "Type.h"
#include "Value.h"
@ -163,8 +165,8 @@ UiUtils::ReportNameForTeam(::Team* team, char* buffer, size_t bufferSize)
/*static*/ void
UiUtils::PrintValueNodeGraph(BString& _output, StackFrame* frame,
ValueNodeChild* child, int32 indentLevel, int32 maxDepth)
UiUtils::PrintValueNodeGraph(BString& _output, ValueNodeChild* child,
int32 indentLevel, int32 maxDepth)
{
_output.Append('\t', indentLevel);
_output << child->Name();
@ -215,13 +217,78 @@ UiUtils::PrintValueNodeGraph(BString& _output, StackFrame* frame,
// level node contains no data of intereest.
if (node->ChildAt(i)->GetType()->Kind() != TYPE_COMPOUND
|| maxDepth > 1) {
PrintValueNodeGraph(_output, frame, node->ChildAt(i),
PrintValueNodeGraph(_output, node->ChildAt(i),
indentLevel + 1, maxDepth - 1);
}
}
_output.Append('\t', indentLevel);
_output << "}\n";
}
} else
_output << "\n";
return;
}
/*static*/ void UiUtils::DumpMemory(BString& _output, int32 indentLevel,
TeamMemoryBlock* block, target_addr_t address, int32 itemSize,
int32 displayWidth, int32 count)
{
BString data;
int32 j;
_output.Append('\t', indentLevel);
for (int32 i = 0; i < count; i++) {
uint8* value;
if ((i % displayWidth) == 0) {
int32 displayed = min_c(displayWidth, (count-i)) * itemSize;
if (i != 0) {
_output.Append("\n");
_output.Append('\t', indentLevel);
}
data.SetToFormat("[%#" B_PRIx64 "] ", address + i * itemSize);
_output += data;
char c;
for (j = 0; j < displayed; j++) {
if (!block->Contains(address + displayed))
break;
c = *(block->Data() + address - block->BaseAddress()
+ (i * itemSize) + j);
if (!isprint(c))
c = '.';
_output += c;
}
if (count > displayWidth) {
// make sure the spacing in the last line is correct
for (j = displayed; j < displayWidth * itemSize; j++)
_output += ' ';
}
_output.Append(" ");
}
value = block->Data() + address - block->BaseAddress()
+ i * itemSize;
switch (itemSize) {
case 1:
data.SetToFormat(" %02" B_PRIx8, *(uint8*)value);
break;
case 2:
data.SetToFormat(" %04" B_PRIx16, *(uint16*)value);
break;
case 4:
data.SetToFormat(" %08" B_PRIx32, *(uint32*)value);
break;
case 8:
data.SetToFormat(" %016" B_PRIx64, *(uint64*)value);
break;
}
_output += data;
}
_output.Append("\n");
}

View File

@ -9,13 +9,17 @@
#include <image.h>
#include "Types.h"
class BString;
class BVariant;
class StackFrame;
class Team;
class TeamMemoryBlock;
class ValueNodeChild;
class UiUtils {
public:
static const char* ThreadStateToString(int state,
@ -34,9 +38,14 @@ public:
// this function assumes the value nodes have already been resolved
// (if possible).
static void PrintValueNodeGraph(BString& _output,
StackFrame* frame,
ValueNodeChild* child,
int32 indentLevel, int32 maxDepth);
static void DumpMemory(BString& _output,
int32 indentLevel,
TeamMemoryBlock* block,
target_addr_t address, int32 itemSize,
int32 displayWidth, int32 count);
};

View File

@ -185,7 +185,7 @@ CalcView::~CalcView()
free(fKeypadDescription);
// replicant deleted, destroy the about window
if (fAboutWindow != NULL)
if (fAboutWindow != NULL && fAboutWindow->Lock())
fAboutWindow->Quit();
}

View File

@ -139,7 +139,7 @@ NetworkStatusView::NetworkStatusView(BMessage* archive)
NetworkStatusView::~NetworkStatusView()
{
if (fAboutWindow != NULL)
if (fAboutWindow != NULL && fAboutWindow->Lock())
fAboutWindow->Quit();
}

View File

@ -206,7 +206,7 @@ ProcessController::~ProcessController()
gPCView = NULL;
// replicant deleted, destroy the about window
if (fAboutWindow != NULL)
if (fAboutWindow != NULL && fAboutWindow->Lock())
fAboutWindow->Quit();
}

View File

@ -89,7 +89,7 @@ BrowserApp::~BrowserApp()
delete fCookies;
delete fCookieJar;
if (fAboutWindow != NULL)
if (fAboutWindow != NULL && fAboutWindow->Lock())
fAboutWindow->Quit();
}

View File

@ -374,7 +374,7 @@ WorkspacesView::WorkspacesView(BMessage* archive)
WorkspacesView::~WorkspacesView()
{
if (fAboutWindow != NULL)
if (fAboutWindow != NULL && fAboutWindow->Lock())
fAboutWindow->Quit();
}

View File

@ -47,7 +47,7 @@ enum {
TOKEN_END_OF_LINE
};
struct Token {
struct ExpressionParser::Token {
Token()
: string(""),
type(TOKEN_NONE),
@ -89,7 +89,7 @@ struct Token {
};
class Tokenizer {
class ExpressionParser::Tokenizer {
public:
Tokenizer()
: fString(""),
@ -594,7 +594,7 @@ ExpressionParser::_ParseFunction(const Token& token)
if (strcmp("e", token.string.String()) == 0)
return _ParseFactorial(MAPM(MM_E));
else if (strcasecmp("pi", token.string.String()) == 0
|| ((unsigned char)token.string.String()[0] == 0xCF
|| ((unsigned char)token.string.String()[0] == 0xCF
&& (unsigned char)token.string.String()[1] == 0x80)) {
// UTF-8 small greek letter PI
return _ParseFactorial(MAPM(MM_PI));

View File

@ -41,8 +41,8 @@ enum {
};
#define HANDOVER_USE_GDB 1
//#define HANDOVER_USE_DEBUGGER 1
//#define HANDOVER_USE_GDB 1
#define HANDOVER_USE_DEBUGGER 1
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "DebugServer"
@ -555,44 +555,57 @@ TeamDebugHandler::_EnterDebugger(bool saveReport)
"terminal (debugger) for team %" B_PRId32 "...\n", fTeam));
#elif defined(HANDOVER_USE_DEBUGGER)
// prepare the argument vector
BPath debuggerPath;
if (debugInConsoled) {
error = _SetupGDBArguments(arguments, debugInConsoled);
error = find_directory(B_SYSTEM_BIN_DIRECTORY, &debuggerPath);
if (error != B_OK) {
debug_printf("debug_server: Failed to set up gdb arguments: %s\n",
debug_printf("debug_server: can't find system-bin directory: %s\n",
strerror(error));
return error;
}
} else {
// prepare the argument vector
BPath debuggerPath;
error = find_directory(B_SYSTEM_APPS_DIRECTORY, &debuggerPath);
error = debuggerPath.Append("consoled");
if (error != B_OK) {
debug_printf("debug_server: can't find system-apps directory: %s\n",
strerror(error));
return error;
}
error = debuggerPath.Append("Debugger");
if (error != B_OK) {
debug_printf("debug_server: can't append to system-apps path: %s\n",
debug_printf("debug_server: can't append to system-bin path: %s\n",
strerror(error));
return error;
}
if (!arguments.Add(debuggerPath.Path()))
return B_NO_MEMORY;
BString debuggerParam;
debuggerParam.SetToFormat("%" B_PRId32, fTeam);
if (saveReport) {
if (!arguments.Add("--save-report"))
return B_NO_MEMORY;
}
if (!arguments.Add("--team") || !arguments.Add(debuggerParam))
return B_NO_MEMORY;
// start the debugger
TRACE(("debug_server: TeamDebugHandler::_EnterDebugger(): starting "
"graphical debugger for team %" B_PRId32 "...\n", fTeam));
}
error = find_directory(B_SYSTEM_APPS_DIRECTORY, &debuggerPath);
if (error != B_OK) {
debug_printf("debug_server: can't find system-apps directory: %s\n",
strerror(error));
return error;
}
error = debuggerPath.Append("Debugger");
if (error != B_OK) {
debug_printf("debug_server: can't append to system-apps path: %s\n",
strerror(error));
return error;
}
if (!arguments.Add(debuggerPath.Path()))
return B_NO_MEMORY;
if (debugInConsoled && !arguments.Add("--cli"))
return B_NO_MEMORY;
BString debuggerParam;
debuggerParam.SetToFormat("%" B_PRId32, fTeam);
if (saveReport) {
if (!arguments.Add("--save-report"))
return B_NO_MEMORY;
}
if (!arguments.Add("--team") || !arguments.Add(debuggerParam))
return B_NO_MEMORY;
// start the debugger
TRACE(("debug_server: TeamDebugHandler::_EnterDebugger(): starting "
"%s debugger for team %" B_PRId32 "...\n",
debugInConsoled ? "command line" : "graphical", fTeam));
#endif
for (int32 i = 0; i < arguments.CountStrings(); i++)

View File

@ -891,7 +891,7 @@ dump_mutex_info(int argc, char** argv)
#if KDEBUG
kprintf(" holder: %" B_PRId32 "\n", lock->holder);
#else
kprintf(" count: %ld\n", lock->count);
kprintf(" count: %" B_PRId32 "\n", lock->count);
#endif
kprintf(" waiting threads:");

View File

@ -209,7 +209,7 @@ dump_sem(struct sem_entry* sem)
else
unset_debug_variable("_releaser");
#else
kprintf("last acquired by: %ld\n", sem->u.used.last_acquirer);
kprintf("last acquired by: %" B_PRId32 "\n", sem->u.used.last_acquirer);
#endif
if (sem->u.used.last_acquirer != 0)