From c3f81329bb1bfcb22b0b59c3a7f66667c6f0c04b Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Wed, 29 Oct 2014 17:32:14 -0400 Subject: [PATCH] Debugger: Implement expression variable value resolution. General: - Resolving variable values requires both a stack frame and a CPU state. Adjust all interfaces and callers accordingly. ExpressionEvaluationJob: - Pass additional parameters needed for variable value resolution. - If variable resolution is desired, ExpressionEvaluationJob now creates a temporary ValueNodeManager for that purpose. - If the expression parser returns a value node pointer that needs to be resolved, schedule a corresponding job and wait. CLanguageExpressionEvaluator: - Clean up some leftovers that were preventing variable names from being handled properly in some cases. - Implement handling of identifier names. These are now looked up against the value node graph of the active node manager, and if found, corresponding values are retrieved. If the value has not yet been resolved, an exception is thrown to ask that to be done. This gets value resolution working for basic local variables and function parameters, and consequently, #9712. Structure/class members and/or pointer indirection aren't yet handled. --- .../debugger/controllers/TeamDebugger.cpp | 23 ++++- src/apps/debugger/controllers/TeamDebugger.h | 7 +- .../debugger/jobs/ExpressionEvaluationJob.cpp | 95 +++++++++++++++++-- src/apps/debugger/jobs/Jobs.h | 13 ++- .../source_language/CLanguageFamily.cpp | 9 +- .../source_language/CLanguageFamily.h | 3 +- .../source_language/SourceLanguage.cpp | 3 +- .../debugger/source_language/SourceLanguage.h | 5 +- .../CLanguageExpressionEvaluator.cpp | 93 ++++++++++++------ .../CLanguageExpressionEvaluator.h | 23 ++++- .../debugger/user_interface/UserInterface.h | 3 +- .../ExpressionEvaluationWindow.cpp | 28 +++++- .../team_window/ExpressionEvaluationWindow.h | 8 ++ .../gui/team_window/TeamWindow.cpp | 3 +- 14 files changed, 256 insertions(+), 60 deletions(-) diff --git a/src/apps/debugger/controllers/TeamDebugger.cpp b/src/apps/debugger/controllers/TeamDebugger.cpp index 5485e67ef6..133a3955b8 100644 --- a/src/apps/debugger/controllers/TeamDebugger.cpp +++ b/src/apps/debugger/controllers/TeamDebugger.cpp @@ -732,7 +732,16 @@ TeamDebugger::MessageReceived(BMessage* message) frame = NULL; } - _HandleEvaluateExpression(language, expression, resultType, frame); + ::Thread* thread; + if (message->FindPointer("thread", + reinterpret_cast(&thread)) != B_OK) { + // the thread isn't needed, unless variable + // evaluation is desired. + thread = NULL; + } + + _HandleEvaluateExpression(language, expression, resultType, + frame, thread); break; } @@ -1087,7 +1096,8 @@ TeamDebugger::InspectRequested(target_addr_t address, void TeamDebugger::ExpressionEvaluationRequested(SourceLanguage* language, - const char* expression, type_code resultType, StackFrame* frame) + const char* expression, type_code resultType, StackFrame* frame, + ::Thread* thread) { BMessage message(MSG_EVALUATE_EXPRESSION); message.AddPointer("language", language); @@ -1095,6 +1105,8 @@ TeamDebugger::ExpressionEvaluationRequested(SourceLanguage* language, message.AddInt32("type", resultType); if (frame != NULL) message.AddPointer("frame", frame); + if (thread != NULL) + message.AddPointer("thread", thread); BReference reference(language); if (PostMessage(&message) == B_OK) @@ -1982,11 +1994,12 @@ TeamDebugger::_HandleInspectAddress(target_addr_t address, void TeamDebugger::_HandleEvaluateExpression(SourceLanguage* language, - const char* expression, type_code resultType, StackFrame* frame) + const char* expression, type_code resultType, StackFrame* frame, + ::Thread* thread) { status_t result = fWorker->ScheduleJob( - new(std::nothrow) ExpressionEvaluationJob(fTeam, language, - expression, resultType, frame)); + new(std::nothrow) ExpressionEvaluationJob(fTeam, fDebuggerInterface, + language, expression, resultType, frame, thread)); if (result != B_OK) { _NotifyUser("Evaluate Expression", "Failed to evaluate expression: %s", strerror(result)); diff --git a/src/apps/debugger/controllers/TeamDebugger.h b/src/apps/debugger/controllers/TeamDebugger.h index 4ef9cba66f..ef5a9f2345 100644 --- a/src/apps/debugger/controllers/TeamDebugger.h +++ b/src/apps/debugger/controllers/TeamDebugger.h @@ -27,6 +27,7 @@ class FileManager; class SettingsManager; class TeamDebugInfo; class TeamMemoryBlockManager; +class Thread; class WatchpointManager; @@ -106,7 +107,8 @@ private: SourceLanguage* language, const char* expression, type_code resultType, - StackFrame* frame = NULL); + StackFrame* frame = NULL, + ::Thread* thread = NULL); virtual void DebugReportRequested(entry_ref* targetPath); @@ -193,7 +195,8 @@ private: SourceLanguage* language, const char* expression, type_code resultType, - StackFrame* frame); + StackFrame* frame, + ::Thread* thread); status_t _HandleSetArguments(int argc, const char* const* argv); diff --git a/src/apps/debugger/jobs/ExpressionEvaluationJob.cpp b/src/apps/debugger/jobs/ExpressionEvaluationJob.cpp index ea42f19a6c..b98f783a84 100644 --- a/src/apps/debugger/jobs/ExpressionEvaluationJob.cpp +++ b/src/apps/debugger/jobs/ExpressionEvaluationJob.cpp @@ -9,26 +9,38 @@ #include +#include "DebuggerInterface.h" #include "SourceLanguage.h" #include "StackFrame.h" #include "Team.h" +#include "Thread.h" #include "Value.h" +#include "ValueNode.h" +#include "ValueNodeManager.h" ExpressionEvaluationJob::ExpressionEvaluationJob(Team* team, - SourceLanguage* language, const char* expression, type_code resultType, - StackFrame* frame) + DebuggerInterface* debuggerInterface, SourceLanguage* language, + const char* expression, type_code resultType, StackFrame* frame, + Thread* thread) : fKey(expression, JOB_TYPE_EVALUATE_EXPRESSION), fTeam(team), + fDebuggerInterface(debuggerInterface), + fArchitecture(debuggerInterface->GetArchitecture()), + fTypeInformation(team->GetTeamTypeInformation()), fLanguage(language), fExpression(expression), fResultType(resultType), - fFrame(frame) + fFrame(frame), + fThread(thread), + fManager(NULL) { fLanguage->AcquireReference(); if (fFrame != NULL) fFrame->AcquireReference(); + if (fThread != NULL) + fThread->AcquireReference(); } @@ -37,6 +49,10 @@ ExpressionEvaluationJob::~ExpressionEvaluationJob() fLanguage->ReleaseReference(); if (fFrame != NULL) fFrame->ReleaseReference(); + if (fThread != NULL) + fThread->ReleaseReference(); + if (fManager != NULL) + fManager->ReleaseReference(); } @@ -50,15 +66,80 @@ ExpressionEvaluationJob::Key() const status_t ExpressionEvaluationJob::Do() { + Value* value = NULL; - status_t result = fLanguage->EvaluateExpression(fExpression, fResultType, - value); BReference reference; - if (value != NULL) - reference.SetTo(value, true); + status_t result = B_OK; + if (fFrame != NULL && fManager == NULL) { + fManager = new(std::nothrow) ValueNodeManager(); + if (fManager == NULL) + result = B_NO_MEMORY; + else + result = fManager->SetStackFrame(fThread, fFrame); + } + + if (result != B_OK) { + fTeam->NotifyExpressionEvaluated(fExpression.String(), result, NULL); + return result; + } + + ValueNode* neededNode = NULL; + result = fLanguage->EvaluateExpression(fExpression, + fResultType, fManager, value, neededNode); + if (neededNode != NULL) { + result = ResolveNodeValue(neededNode); + if (State() == JOB_STATE_WAITING) + return B_OK; + else if (value != NULL) + reference.SetTo(value, true); + // if result != B_OK, fall through + } AutoLocker teamLocker(fTeam); fTeam->NotifyExpressionEvaluated(fExpression.String(), result, value); return B_OK; } + + +status_t +ExpressionEvaluationJob::ResolveNodeValue(ValueNode* node) +{ + AutoLocker workerLocker(GetWorker()); + SimpleJobKey jobKey(node, JOB_TYPE_RESOLVE_VALUE_NODE_VALUE); + + status_t error = B_OK; + if (GetWorker()->GetJob(jobKey) == NULL) { + workerLocker.Unlock(); + + // schedule the job + error = GetWorker()->ScheduleJob( + new(std::nothrow) ResolveValueNodeValueJob(fDebuggerInterface, + fArchitecture, fThread->GetCpuState(), fTypeInformation, + fManager->GetContainer(), node)); + if (error != B_OK) { + // scheduling failed -- set the value to invalid + node->SetLocationAndValue(NULL, NULL, error); + return error; + } + } + + // wait for the job to finish + workerLocker.Unlock(); + + + switch (WaitFor(jobKey)) { + case JOB_DEPENDENCY_SUCCEEDED: + case JOB_DEPENDENCY_NOT_FOUND: + case JOB_DEPENDENCY_ACTIVE: + error = B_OK; + break; + case JOB_DEPENDENCY_FAILED: + case JOB_DEPENDENCY_ABORTED: + default: + error = B_ERROR; + break; + } + + return error; +} diff --git a/src/apps/debugger/jobs/Jobs.h b/src/apps/debugger/jobs/Jobs.h index 7a01f870e0..6ae378e5a8 100644 --- a/src/apps/debugger/jobs/Jobs.h +++ b/src/apps/debugger/jobs/Jobs.h @@ -36,6 +36,7 @@ class ValueLocation; class ValueNode; class ValueNodeChild; class ValueNodeContainer; +class ValueNodeManager; class Variable; @@ -233,22 +234,32 @@ private: class ExpressionEvaluationJob : public Job { public: ExpressionEvaluationJob(Team* team, + DebuggerInterface* debuggerInterface, SourceLanguage* language, const char* expression, type_code resultType, - StackFrame* frame); + StackFrame* frame, + Thread* thread); virtual ~ExpressionEvaluationJob(); virtual const JobKey& Key() const; virtual status_t Do(); +private: + status_t ResolveNodeValue(ValueNode* node); + private: SimpleJobKey fKey; Team* fTeam; + DebuggerInterface* fDebuggerInterface; + Architecture* fArchitecture; + TeamTypeInformation* fTypeInformation; SourceLanguage* fLanguage; BString fExpression; type_code fResultType; StackFrame* fFrame; + Thread* fThread; + ValueNodeManager* fManager; }; diff --git a/src/apps/debugger/source_language/CLanguageFamily.cpp b/src/apps/debugger/source_language/CLanguageFamily.cpp index eb4884cf7a..88c6be77c3 100644 --- a/src/apps/debugger/source_language/CLanguageFamily.cpp +++ b/src/apps/debugger/source_language/CLanguageFamily.cpp @@ -167,14 +167,15 @@ CLanguageFamily::ParseTypeExpression(const BString& expression, status_t -CLanguageFamily::EvaluateExpression(const BString& expression, - type_code type, Value*& _output) +CLanguageFamily::EvaluateExpression(const BString& expression, type_code type, + ValueNodeManager* manager, Value*& _output, ValueNode*& _neededNode) { _output = NULL; + _neededNode = NULL; CLanguageExpressionEvaluator evaluator; Number result; try { - result = evaluator.Evaluate(expression, type); + result = evaluator.Evaluate(expression, type, manager); BVariant resultValue = result.GetValue(); switch (type) { case B_INT8_TYPE: @@ -207,6 +208,8 @@ CLanguageFamily::EvaluateExpression(const BString& expression, ex.position, ex.message.String()); _output = new(std::nothrow) StringValue(stringValue); return B_BAD_DATA; + } catch (ValueNeededException ex) { + _neededNode = ex.value; } return B_OK; diff --git a/src/apps/debugger/source_language/CLanguageFamily.h b/src/apps/debugger/source_language/CLanguageFamily.h index a5e74306ac..7159df0d07 100644 --- a/src/apps/debugger/source_language/CLanguageFamily.h +++ b/src/apps/debugger/source_language/CLanguageFamily.h @@ -22,7 +22,8 @@ public: Type*& _resultType) const; virtual status_t EvaluateExpression(const BString& expression, - type_code type, Value*& _output); + type_code type, ValueNodeManager* manager, + Value*& _output, ValueNode*& _neededNode); protected: virtual bool IsModifierValid(char modifier) const = 0; diff --git a/src/apps/debugger/source_language/SourceLanguage.cpp b/src/apps/debugger/source_language/SourceLanguage.cpp index da77ea7136..7f16327765 100644 --- a/src/apps/debugger/source_language/SourceLanguage.cpp +++ b/src/apps/debugger/source_language/SourceLanguage.cpp @@ -30,7 +30,8 @@ SourceLanguage::ParseTypeExpression(const BString& expression, status_t SourceLanguage::EvaluateExpression(const BString& expression, - type_code type, Value*& _resultValue) + type_code type, ValueNodeManager* manager, Value*& _resultValue, + ValueNode*& _neededNode) { return B_NOT_SUPPORTED; } diff --git a/src/apps/debugger/source_language/SourceLanguage.h b/src/apps/debugger/source_language/SourceLanguage.h index f609f0f512..c732b3b66f 100644 --- a/src/apps/debugger/source_language/SourceLanguage.h +++ b/src/apps/debugger/source_language/SourceLanguage.h @@ -15,6 +15,8 @@ class SyntaxHighlighter; class TeamTypeInformation; class Type; class Value; +class ValueNode; +class ValueNodeManager; class SourceLanguage : public BReferenceable { @@ -32,7 +34,8 @@ public: Type*& _resultType) const; virtual status_t EvaluateExpression(const BString& expression, - type_code type, Value*& _output); + type_code type, ValueNodeManager* manager, + Value*& _output, ValueNode*& _neededNode); }; diff --git a/src/apps/debugger/source_language/expression_evaluators/CLanguageExpressionEvaluator.cpp b/src/apps/debugger/source_language/expression_evaluators/CLanguageExpressionEvaluator.cpp index dfaf727aff..1575364f17 100644 --- a/src/apps/debugger/source_language/expression_evaluators/CLanguageExpressionEvaluator.cpp +++ b/src/apps/debugger/source_language/expression_evaluators/CLanguageExpressionEvaluator.cpp @@ -11,13 +11,21 @@ #include "CLanguageExpressionEvaluator.h" -#include "Number.h" - #include #include #include #include +#include "AutoLocker.h" + +#include "Number.h" +#include "StackFrame.h" +#include "Thread.h" +#include "Value.h" +#include "ValueNode.h" +#include "ValueNodeManager.h" +#include "Variable.h" + enum { TOKEN_NONE = 0, @@ -299,7 +307,7 @@ class CLanguageExpressionEvaluator::Tokenizer { fCurrentToken = Token(begin, length, _CurrentPos() - length, TOKEN_CONSTANT); fCurrentToken.value.SetTo(fType, temp.String()); - } else if (isalpha(*fCurrentChar) && *fCurrentChar != 'x') { + } else if (isalpha(*fCurrentChar)) { const char* begin = fCurrentChar; while (*fCurrentChar != 0 && (isalpha(*fCurrentChar) || isdigit(*fCurrentChar))) { @@ -308,10 +316,6 @@ class CLanguageExpressionEvaluator::Tokenizer { int32 length = fCurrentChar - begin; fCurrentToken = Token(begin, length, _CurrentPos() - length, TOKEN_IDENTIFIER); - } else if (strncmp(fCurrentChar, "π", 2) == 0) { - fCurrentToken = Token(fCurrentChar, 2, _CurrentPos() - 1, - TOKEN_IDENTIFIER); - fCurrentChar += 2; } else { if (!_ParseOperator()) { int32 type = TOKEN_NONE; @@ -517,7 +521,8 @@ class CLanguageExpressionEvaluator::Tokenizer { CLanguageExpressionEvaluator::CLanguageExpressionEvaluator() : fTokenizer(new Tokenizer()), - fCurrentType(B_INT64_TYPE) + fCurrentType(B_INT64_TYPE), + fNodeManager(NULL) { } @@ -530,10 +535,10 @@ CLanguageExpressionEvaluator::~CLanguageExpressionEvaluator() Number CLanguageExpressionEvaluator::Evaluate(const char* expressionString, - type_code type) + type_code type, ValueNodeManager* manager) { fCurrentType = type; - + fNodeManager = manager; fTokenizer->SetType(type); fTokenizer->SetTo(expressionString); @@ -745,6 +750,7 @@ CLanguageExpressionEvaluator::_ParseUnary() return Number((int32)(_ParseUnary() == Number(BVariant(0L)))); case TOKEN_IDENTIFIER: + fTokenizer->RewindToken(); return _ParseIdentifier(); default: @@ -756,32 +762,63 @@ CLanguageExpressionEvaluator::_ParseUnary() } -struct Function { - const char* name; - int argumentCount; - void* function; - Number value; -}; - - Number CLanguageExpressionEvaluator::_ParseIdentifier() { - throw ParseException("Identifiers not implemented", 0); + Token token = fTokenizer->NextToken(); + Number value; - return Number(); -} + if (fNodeManager == NULL) { + throw ParseException("Identifiers not resolvable without manager.", + token.position); + } + const BString& identifierName = token.string; -void -CLanguageExpressionEvaluator::_InitArguments(Number values[], int32 argumentCount) -{ - _EatToken(TOKEN_OPENING_BRACKET); + ValueNodeContainer* container = fNodeManager->GetContainer(); + AutoLocker containerLocker(container); - for (int32 i = 0; i < argumentCount; i++) - values[i] = _ParseBinary(); + ValueNodeChild* child = NULL; + for (int32 i = 0; i < container->CountChildren(); i++) { + ValueNodeChild* current = container->ChildAt(i); + if (current->Name() == identifierName) { + child = current; + break; + } + } - _EatToken(TOKEN_CLOSING_BRACKET); + BString errorMessage; + if (child == NULL) { + errorMessage.SetToFormat("Unable to resolve variable name: '%s'", + identifierName.String()); + throw ParseException(errorMessage, token.position); + } + + status_t state = child->LocationResolutionState(); + if (state != B_OK) { + errorMessage.SetToFormat("Unable to resolve variable value for '%s': " + "%s", identifierName.String(), + strerror(state)); + throw ParseException(errorMessage, token.position); + } + + ValueNode* node = child->Node(); + state = node->LocationAndValueResolutionState(); + if (state == VALUE_NODE_UNRESOLVED) { + throw ValueNeededException(node); + } else if (state != B_OK) { + errorMessage.SetToFormat("Unable to resolve variable value for '%s': " + "%s", identifierName.String(), + strerror(state)); + throw ParseException(errorMessage, token.position); + } + + BVariant variant; + Value* nodeValue = node->GetValue(); + nodeValue->ToVariant(variant); + value.SetTo(variant); + + return value; } diff --git a/src/apps/debugger/source_language/expression_evaluators/CLanguageExpressionEvaluator.h b/src/apps/debugger/source_language/expression_evaluators/CLanguageExpressionEvaluator.h index d0161788aa..4e56b5ea92 100644 --- a/src/apps/debugger/source_language/expression_evaluators/CLanguageExpressionEvaluator.h +++ b/src/apps/debugger/source_language/expression_evaluators/CLanguageExpressionEvaluator.h @@ -15,6 +15,10 @@ #include +class ValueNode; +class ValueNodeManager; + + class ParseException { public: ParseException(const char* message, int32 position) @@ -33,9 +37,21 @@ class ParseException { int32 position; }; -struct Function; +class ValueNeededException { +public: + ValueNeededException(ValueNode* node) + : + value(node) + { + } + + ValueNode* value; +}; + + class Number; + class CLanguageExpressionEvaluator { public: @@ -43,7 +59,7 @@ class CLanguageExpressionEvaluator { ~CLanguageExpressionEvaluator(); Number Evaluate(const char* expressionString, - type_code type); + type_code type, ValueNodeManager* manager); private: struct Token; @@ -56,14 +72,13 @@ class CLanguageExpressionEvaluator { Number _ParsePower(); Number _ParseUnary(); Number _ParseIdentifier(); - void _InitArguments(Number values[], - int32 argumentCount); Number _ParseAtom(); void _EatToken(int32 type); Tokenizer* fTokenizer; type_code fCurrentType; + ValueNodeManager* fNodeManager; }; #endif // C_LANGUAGE_EXPRESSION_EVALUATOR_H diff --git a/src/apps/debugger/user_interface/UserInterface.h b/src/apps/debugger/user_interface/UserInterface.h index 748b6a8625..565f0b9edb 100644 --- a/src/apps/debugger/user_interface/UserInterface.h +++ b/src/apps/debugger/user_interface/UserInterface.h @@ -141,7 +141,8 @@ public: SourceLanguage* language, const char* expression, type_code resultType, - StackFrame* frame = NULL) = 0; + StackFrame* frame = NULL, + Thread* thread = NULL) = 0; virtual void DebugReportRequested(entry_ref* path) = 0; diff --git a/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.cpp index 350cce4381..8236450293 100644 --- a/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.cpp @@ -16,6 +16,8 @@ #include "MessageCodes.h" #include "SourceLanguage.h" +#include "StackFrame.h" +#include "Thread.h" #include "UserInterface.h" #include "Value.h" @@ -26,8 +28,8 @@ enum { ExpressionEvaluationWindow::ExpressionEvaluationWindow( - ::Team* team, SourceLanguage* language, UserInterfaceListener* listener, - BHandler* target) + ::Team* team, SourceLanguage* language, StackFrame* frame, + ::Thread* thread, UserInterfaceListener* listener, BHandler* target) : BWindow(BRect(), "Evaluate Expression", B_FLOATING_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE), @@ -37,11 +39,19 @@ ExpressionEvaluationWindow::ExpressionEvaluationWindow( fExpressionOutput(NULL), fEvaluateButton(NULL), fListener(listener), + fStackFrame(frame), + fThread(thread), fCloseTarget(target), fCurrentEvaluationType(B_INT64_TYPE) { fLanguage->AcquireReference(); + if (fStackFrame != NULL) + fStackFrame->AcquireReference(); + + if (fThread != NULL) + fThread->AcquireReference(); + AutoLocker< ::Team> teamLocker(fTeam); fTeam->AddListener(this); } @@ -51,6 +61,12 @@ ExpressionEvaluationWindow::~ExpressionEvaluationWindow() { fLanguage->ReleaseReference(); + if (fStackFrame != NULL) + fStackFrame->ReleaseReference(); + + if (fThread != NULL) + fThread->ReleaseReference(); + AutoLocker< ::Team> teamLocker(fTeam); fTeam->RemoveListener(this); } @@ -58,10 +74,11 @@ ExpressionEvaluationWindow::~ExpressionEvaluationWindow() ExpressionEvaluationWindow* ExpressionEvaluationWindow::Create(::Team* team, SourceLanguage* language, - UserInterfaceListener* listener, BHandler* target) + StackFrame* frame, ::Thread* thread, UserInterfaceListener* listener, + BHandler* target) { ExpressionEvaluationWindow* self = new ExpressionEvaluationWindow(team, - language, listener, target); + language, frame, thread, listener, target); try { self->_Init(); @@ -216,7 +233,8 @@ ExpressionEvaluationWindow::MessageReceived(BMessage* message) break; fListener->ExpressionEvaluationRequested(fLanguage, - fExpressionInput->Text(), fCurrentEvaluationType); + fExpressionInput->Text(), fCurrentEvaluationType, fStackFrame, + fThread); break; } diff --git a/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.h b/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.h index 4740132537..d256b77e94 100644 --- a/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.h +++ b/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.h @@ -16,7 +16,9 @@ class BButton; class BStringView; class BTextControl; class Team; +class Thread; class SourceLanguage; +class StackFrame; class UserInterfaceListener; @@ -26,6 +28,8 @@ public: ExpressionEvaluationWindow( ::Team* team, SourceLanguage* language, + StackFrame* frame, + ::Thread* thread, UserInterfaceListener* listener, BHandler* target); @@ -34,6 +38,8 @@ public: static ExpressionEvaluationWindow* Create( ::Team* team, SourceLanguage* language, + StackFrame* frame, + ::Thread* thread, UserInterfaceListener* listener, BHandler* target); // throws @@ -60,6 +66,8 @@ private: BStringView* fExpressionOutput; BButton* fEvaluateButton; UserInterfaceListener* fListener; + StackFrame* fStackFrame; + ::Thread* fThread; BHandler* fCloseTarget; type_code fCurrentEvaluationType; }; diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp index b962600ba6..32c1543e09 100644 --- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp @@ -356,7 +356,8 @@ TeamWindow::MessageReceived(BMessage* message) BReference languageReference(language, true); fExpressionWindow = ExpressionEvaluationWindow::Create( - fTeam, language, fListener, this); + fTeam, language, fActiveStackFrame, fActiveThread, + fListener, this); if (fExpressionWindow != NULL) fExpressionWindow->Show(); } catch (...) {