Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions lldb/include/lldb/Target/StackFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,35 @@ class StackFrame : public ExecutionContextScope,
llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
uint32_t options, lldb::VariableSP &var_sp, Status &error);

/// Create a ValueObject for a variable name / pathname, possibly including
/// simple dereference/child selection syntax.
///
/// \param[in] var_expr
/// The string specifying a variable to base the VariableObject off
/// of.
///
/// \param[in] use_dynamic
/// Whether the correct dynamic type of an object pointer should be
/// determined before creating the object, or if the static type is
/// sufficient. One of the DynamicValueType enumerated values.
///
/// \param[in] options
/// An unsigned integer of flags, values from
/// StackFrame::ExpressionPathOption
/// enum.
/// \param[in] var_sp
/// A VariableSP that will be set to the variable described in the
/// var_expr path.
///
/// \param[in] error
/// Record any errors encountered while evaluating var_expr.
///
/// \return
/// A shared pointer to the ValueObject described by var_expr.
lldb::ValueObjectSP DILEvaluateVariableExpression(
llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
uint32_t options, lldb::VariableSP &var_sp, Status &error);

/// Determine whether this StackFrame has debug information available or not.
///
/// \return
Expand Down
4 changes: 4 additions & 0 deletions lldb/include/lldb/Target/Target.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,10 @@ class TargetProperties : public Properties {

bool GetInjectLocalVariables(ExecutionContext *exe_ctx) const;

bool GetUseDIL(ExecutionContext *exe_ctx) const;

void SetUseDIL(ExecutionContext *exe_ctx, bool b);

void SetRequireHardwareBreakpoints(bool b);

bool GetRequireHardwareBreakpoints() const;
Expand Down
22 changes: 17 additions & 5 deletions lldb/source/API/SBFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,18 +472,30 @@ lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path,
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
Process *process = exe_ctx.GetProcessPtr();
bool use_DIL = target->GetUseDIL(&exe_ctx);
if (target && process) {
Process::StopLocker stop_locker;
if (stop_locker.TryLock(&process->GetRunLock())) {
frame = exe_ctx.GetFramePtr();
if (frame) {
VariableSP var_sp;
Status error;
ValueObjectSP value_sp(frame->GetValueForVariableExpressionPath(
var_path, eNoDynamicValues,
StackFrame::eExpressionPathOptionCheckPtrVsMember |
StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
var_sp, error));
ValueObjectSP value_sp;
if (use_DIL) {
// Use DIL parser/evaluator.
value_sp = frame->DILEvaluateVariableExpression(
var_path, eNoDynamicValues,
StackFrame::eExpressionPathOptionCheckPtrVsMember |
StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
var_sp, error);
} else {
// Use original frame function.
value_sp = frame->GetValueForVariableExpressionPath(
var_path, eNoDynamicValues,
StackFrame::eExpressionPathOptionCheckPtrVsMember |
StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
var_sp, error);
}
sb_value.SetSP(value_sp, use_dynamic);
}
}
Expand Down
19 changes: 15 additions & 4 deletions lldb/source/Commands/CommandObjectFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,10 @@ may even involve JITing and running code in the target program.)");
result.AppendError(error.AsCString());

}
VariableSP var_sp;
ValueObjectSP valobj_sp;
TargetSP target_sp = frame->CalculateTarget();
bool use_DIL = target_sp->GetUseDIL(&m_exe_ctx);

TypeSummaryImplSP summary_format_sp;
if (!m_option_variable.summary.IsCurrentValueEmpty())
Expand Down Expand Up @@ -600,9 +603,17 @@ may even involve JITing and running code in the target program.)");
StackFrame::eExpressionPathOptionsAllowDirectIVarAccess |
StackFrame::eExpressionPathOptionsInspectAnonymousUnions;
lldb::VariableSP var_sp;
valobj_sp = frame->GetValueForVariableExpressionPath(
entry.ref(), m_varobj_options.use_dynamic, expr_path_options,
var_sp, error);
if (use_DIL) {
// Use the DIL parser/evaluator.
valobj_sp = frame->DILEvaluateVariableExpression(
entry.ref(), m_varobj_options.use_dynamic, expr_path_options,
var_sp, error);
} else {
// Original 'frame variable' execution path
valobj_sp = frame->GetValueForVariableExpressionPath(
entry.ref(), m_varobj_options.use_dynamic, expr_path_options,
var_sp, error);
}
if (valobj_sp) {
std::string scope_string;
if (m_option_variable.show_scope)
Expand Down Expand Up @@ -641,7 +652,7 @@ may even involve JITing and running code in the target program.)");
const size_t num_variables = variable_list->GetSize();
if (num_variables > 0) {
for (size_t i = 0; i < num_variables; i++) {
VariableSP var_sp = variable_list->GetVariableAtIndex(i);
var_sp = variable_list->GetVariableAtIndex(i);
if (!ScopeRequested(var_sp->GetScope()))
continue;
std::string scope_string;
Expand Down
14 changes: 11 additions & 3 deletions lldb/source/Commands/CommandObjectWatchpoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,7 @@ corresponding to the byte size of the data type.");
void DoExecute(Args &command, CommandReturnObject &result) override {
Target &target = GetTarget();
StackFrame *frame = m_exe_ctx.GetFramePtr();
bool use_DIL = target.GetUseDIL(&m_exe_ctx);

// If no argument is present, issue an error message. There's no way to
// set a watchpoint.
Expand Down Expand Up @@ -840,9 +841,16 @@ corresponding to the byte size of the data type.");
uint32_t expr_path_options =
StackFrame::eExpressionPathOptionCheckPtrVsMember |
StackFrame::eExpressionPathOptionsAllowDirectIVarAccess;
valobj_sp = frame->GetValueForVariableExpressionPath(
command.GetArgumentAtIndex(0), eNoDynamicValues, expr_path_options,
var_sp, error);
if (use_DIL)
// Use the DIL parser/evaluator.
valobj_sp = frame->DILEvaluateVariableExpression(
command.GetArgumentAtIndex(0), eNoDynamicValues, expr_path_options,
var_sp, error);
else
// Use the original frame function.
valobj_sp = frame->GetValueForVariableExpressionPath(
command.GetArgumentAtIndex(0), eNoDynamicValues, expr_path_options,
var_sp, error);

if (!valobj_sp) {
// Not in the frame; let's check the globals.
Expand Down
29 changes: 22 additions & 7 deletions lldb/source/Expression/UserExpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,28 @@ lldb::ValueObjectSP UserExpression::GetObjectPointerValueObject(
lldb::VariableSP var_sp;
lldb::ValueObjectSP valobj_sp;

return frame_sp->GetValueForVariableExpressionPath(
object_name, lldb::eNoDynamicValues,
StackFrame::eExpressionPathOptionCheckPtrVsMember |
StackFrame::eExpressionPathOptionsNoFragileObjcIvar |
StackFrame::eExpressionPathOptionsNoSyntheticChildren |
StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
var_sp, err);
lldb::TargetSP target_sp = frame_sp->CalculateTarget();
ExecutionContext exe_ctx;
frame_sp->CalculateExecutionContext(exe_ctx);
bool use_DIL = target_sp->GetUseDIL(&exe_ctx);

if (use_DIL) {
return frame_sp->DILEvaluateVariableExpression(
object_name, lldb::eNoDynamicValues,
StackFrame::eExpressionPathOptionCheckPtrVsMember |
StackFrame::eExpressionPathOptionsNoFragileObjcIvar |
StackFrame::eExpressionPathOptionsNoSyntheticChildren |
StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
var_sp, err);
} else {
return frame_sp->GetValueForVariableExpressionPath(
object_name, lldb::eNoDynamicValues,
StackFrame::eExpressionPathOptionCheckPtrVsMember |
StackFrame::eExpressionPathOptionsNoFragileObjcIvar |
StackFrame::eExpressionPathOptionsNoSyntheticChildren |
StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
var_sp, err);
}
}

lldb::addr_t UserExpression::GetObjectPointer(lldb::StackFrameSP frame_sp,
Expand Down
15 changes: 13 additions & 2 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,19 @@ DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die,
if (auto frame = exe_ctx->GetFrameSP()) {
Status error;
lldb::VariableSP var_sp;
auto valobj_sp = frame->GetValueForVariableExpressionPath(
var_die.GetName(), eNoDynamicValues, 0, var_sp, error);
lldb::TargetSP target_sp = frame->CalculateTarget();
bool use_DIL = target_sp->GetUseDIL(
(lldb_private::ExecutionContext *)exe_ctx);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this cast wouldn't be required if you changed GetExperimentalPropertyValue to take a const execution context (all of the functions below it already take a const argument)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code & cast are gone now.

lldb::ValueObjectSP valobj_sp;
if (use_DIL) {
// Use the DIL parser/evaluator.
valobj_sp = frame->DILEvaluateVariableExpression(
var_die.GetName(), eNoDynamicValues, 0, var_sp, error);
} else {
// Use the original frame function.
valobj_sp = frame->GetValueForVariableExpressionPath(
var_die.GetName(), eNoDynamicValues, 0, var_sp, error);
}
if (valobj_sp) {
num_elements = valobj_sp->GetValueAsUnsigned(0);
break;
Expand Down
9 changes: 9 additions & 0 deletions lldb/source/Target/StackFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,15 @@ StackFrame::GetInScopeVariableList(bool get_file_globals,
return var_list_sp;
}

ValueObjectSP StackFrame::DILEvaluateVariableExpression(
llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
uint32_t options, lldb::VariableSP &var_sp, Status &error) {
// This is a place-holder for the calls into the DIL parser and
// evaluator. For now, just call the "real" frame variable implementation.
return GetValueForVariableExpressionPath(var_expr, use_dynamic, options,
var_sp, error);
}

ValueObjectSP StackFrame::GetValueForVariableExpressionPath(
llvm::StringRef var_expr, DynamicValueType use_dynamic, uint32_t options,
VariableSP &var_sp, Status &error) {
Expand Down
21 changes: 21 additions & 0 deletions lldb/source/Target/Target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4385,6 +4385,27 @@ bool TargetProperties::GetInjectLocalVariables(
.value_or(true);
}

bool TargetProperties::GetUseDIL(ExecutionContext *exe_ctx) const {
const Property *exp_property =
m_collection_sp->GetPropertyAtIndex(ePropertyExperimental, exe_ctx);
OptionValueProperties *exp_values =
exp_property->GetValue()->GetAsProperties();
if (exp_values)
return exp_values->GetPropertyAtIndexAs<bool>(ePropertyUseDIL, exe_ctx)
.value_or(false);
else
return true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be false as well? Otherwise DIL will be enabled if exp_values is not available (not sure when this happens though).

}

void TargetProperties::SetUseDIL(ExecutionContext *exe_ctx, bool b) {
const Property *exp_property =
m_collection_sp->GetPropertyAtIndex(ePropertyExperimental, exe_ctx);
OptionValueProperties *exp_values =
exp_property->GetValue()->GetAsProperties();
if (exp_values)
exp_values->SetPropertyAtIndex(ePropertyUseDIL, true, exe_ctx);
}

ArchSpec TargetProperties::GetDefaultArchitecture() const {
const uint32_t idx = ePropertyDefaultArch;
return GetPropertyAtIndexAs<ArchSpec>(idx, {});
Expand Down
3 changes: 3 additions & 0 deletions lldb/source/Target/TargetProperties.td
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ let Definition = "target_experimental" in {
def InjectLocalVars : Property<"inject-local-vars", "Boolean">,
Global, DefaultTrue,
Desc<"If true, inject local variables explicitly into the expression text. This will fix symbol resolution when there are name collisions between ivars and local variables. But it can make expressions run much more slowly.">;
def UseDIL : Property<"use-DIL", "Boolean">,
Global, DefaultFalse,
Desc<"If true, use the alternative DIL implementation for frame variable evaluation.">;
}

let Definition = "target" in {
Expand Down
Loading