Skip to content

[lldb] Support true/false in ValueObject::SetValueFromCString #115780

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 3 additions & 1 deletion lldb/include/lldb/Target/Language.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ class Language : public PluginInterface {
// a match. But we wouldn't want this to match AnotherA::my_function. The
// user is specifying a truncated path, not a truncated set of characters.
// This function does a language-aware comparison for those purposes.
virtual bool DemangledNameContainsPath(llvm::StringRef path,
virtual bool DemangledNameContainsPath(llvm::StringRef path,
ConstString demangled) const;

// if a language has a custom format for printing variable declarations that
Expand Down Expand Up @@ -372,6 +372,8 @@ class Language : public PluginInterface {
return {};
}

virtual std::optional<bool> GetBooleanFromString(llvm::StringRef str) const;

/// Returns true if this Language supports exception breakpoints on throw via
/// a corresponding LanguageRuntime plugin.
virtual bool SupportsExceptionBreakpointsOnThrow() const { return false; }
Expand Down
8 changes: 8 additions & 0 deletions lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1040,3 +1040,11 @@ bool ObjCLanguage::IsSourceFile(llvm::StringRef file_path) const {
}
return false;
}

std::optional<bool>
ObjCLanguage::GetBooleanFromString(llvm::StringRef str) const {
return llvm::StringSwitch<std::optional<bool>>(str)
.Case("YES", {true})
.Case("NO", {false})
.Default({});
}
3 changes: 3 additions & 0 deletions lldb/source/Plugins/Language/ObjC/ObjCLanguage.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ class ObjCLanguage : public Language {

llvm::StringRef GetInstanceVariableName() override { return "self"; }

virtual std::optional<bool>
GetBooleanFromString(llvm::StringRef str) const override;

bool SupportsExceptionBreakpointsOnThrow() const override { return true; }

// PluginInterface protocol
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,11 @@ Language *ObjCPlusPlusLanguage::CreateInstance(lldb::LanguageType language) {
return nullptr;
}
}

std::optional<bool>
ObjCPlusPlusLanguage::GetBooleanFromString(llvm::StringRef str) const {
return llvm::StringSwitch<std::optional<bool>>(str)
.Cases("true", "YES", {true})
.Cases("false", "NO", {false})
.Default({});
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ class ObjCPlusPlusLanguage : public Language {

llvm::StringRef GetInstanceVariableName() override { return "self"; }

virtual std::optional<bool>
GetBooleanFromString(llvm::StringRef str) const override;

static llvm::StringRef GetPluginNameStatic() { return "objcplusplus"; }

// PluginInterface protocol
Expand Down
8 changes: 8 additions & 0 deletions lldb/source/Target/Language.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,14 @@ void Language::GetDefaultExceptionResolverDescription(bool catch_on,
s.Printf("Exception breakpoint (catch: %s throw: %s)",
catch_on ? "on" : "off", throw_on ? "on" : "off");
}

std::optional<bool> Language::GetBooleanFromString(llvm::StringRef str) const {
return llvm::StringSwitch<std::optional<bool>>(str)
.Case("true", {true})
.Case("false", {false})
.Default({});
}

// Constructor
Language::Language() = default;

Expand Down
15 changes: 15 additions & 0 deletions lldb/source/ValueObject/ValueObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1639,6 +1639,18 @@ addr_t ValueObject::GetPointerValue(AddressType *address_type) {
return address;
}

static const char *ConvertBoolean(lldb::LanguageType language_type,
const char *value_str) {
if (Language *language = Language::FindPlugin(language_type))
if (auto boolean = language->GetBooleanFromString(value_str))
return *boolean ? "1" : "0";

return llvm::StringSwitch<const char *>(value_str)
.Case("true", "1")
.Case("false", "0")
.Default(value_str);
}

bool ValueObject::SetValueFromCString(const char *value_str, Status &error) {
error.Clear();
// Make sure our value is up to date first so that our location and location
Expand All @@ -1659,6 +1671,9 @@ bool ValueObject::SetValueFromCString(const char *value_str, Status &error) {
// If the value is already a scalar, then let the scalar change itself:
m_value.GetScalar().SetValueFromCString(value_str, encoding, byte_size);
} else if (byte_size <= 16) {
if (GetCompilerType().IsBoolean())
value_str = ConvertBoolean(GetObjectRuntimeLanguage(), value_str);

// If the value fits in a scalar, then make a new scalar and again let the
// scalar code do the conversion, then figure out where to put the new
// value.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

int main() {
NSDictionary* dic = @{@1 : @2};
BOOL b = NO;
NSLog(@"hello world"); //% dic = self.frame().FindVariable("dic")
//% dic.SetPreferSyntheticValue(True)
//% dic.SetPreferDynamicValue(lldb.eDynamicCanRunTarget)
//% dic.SetValueFromCString("12")
//% b = self.frame().FindVariable("b")
//% b.SetValueFromCString("YES")
return 0; //% dic = self.frame().FindVariable("dic")
//% self.assertTrue(dic.GetValueAsUnsigned() == 0xC, "failed to read what I wrote")
//% b = self.frame().FindVariable("b")
//% self.assertTrue(b.GetValueAsUnsigned() == 0x0, "failed to update b")
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
Test some SBValue APIs.
"""


import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
Expand Down Expand Up @@ -111,6 +110,30 @@ def test_change_value(self):
actual_value, 98765, "Got the right changed value from ptr->second_val"
)

ptr_fourth_value = ptr_value.GetChildMemberWithName("fourth_val")
self.assertTrue(ptr_fourth_value.IsValid(), "Got fourth_val from ptr")
fourth_actual_value = ptr_fourth_value.GetValueAsUnsigned(error, 1)
self.assertTrue(error.Success(), "Got an unsigned value for ptr->fourth_val")
self.assertEqual(fourth_actual_value, 0)

result = ptr_fourth_value.SetValueFromCString("true")
self.assertTrue(result, "Success setting ptr->fourth_val.")
fourth_actual_value = ptr_fourth_value.GetValueAsSigned(error, 0)
self.assertTrue(error.Success(), "Got a changed value from ptr->fourth_val")
self.assertEqual(
fourth_actual_value, 1, "Got the right changed value from ptr->fourth_val"
)

result = ptr_fourth_value.SetValueFromCString("NO")
self.assertFalse(result, "Failed setting ptr->fourth_val.")
fourth_actual_value = ptr_fourth_value.GetValueAsSigned(error, 0)
self.assertTrue(error.Success(), "Got the original value from ptr->fourth_val")
self.assertEqual(
fourth_actual_value,
1,
"Got the original changed value from ptr->fourth_val",
)

# gcc may set multiple locations for breakpoint
breakpoint.SetEnabled(False)

Expand All @@ -125,7 +148,7 @@ def test_change_value(self):
)

expected_value = (
"Val - 12345 Mine - 55, 98765, 55555555. Ptr - 66, 98765, 66666666"
"Val - 12345 Mine - 55, 98765, 55555555, 0. Ptr - 66, 98765, 66666666, 1"
)
stdout = process.GetSTDOUT(1000)
self.assertIn(expected_value, stdout, "STDOUT showed changed values.")
Expand Down
15 changes: 9 additions & 6 deletions lldb/test/API/python_api/value/change_values/main.c
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

struct foo
{
uint8_t first_val;
uint32_t second_val;
uint64_t third_val;
bool fourth_val;
};

int main ()
{
int val = 100;
struct foo mine = {55, 5555, 55555555};
struct foo mine = {55, 5555, 55555555, false};
struct foo *ptr = (struct foo *) malloc (sizeof (struct foo));
ptr->first_val = 66;
ptr->second_val = 6666;
ptr->third_val = 66666666;
ptr->fourth_val = false;

// Stop here and set values
printf ("Val - %d Mine - %d, %d, %llu. Ptr - %d, %d, %llu\n", val,
mine.first_val, mine.second_val, mine.third_val,
ptr->first_val, ptr->second_val, ptr->third_val);
printf("Val - %d Mine - %d, %d, %llu, %d. Ptr - %d, %d, %llu, %d\n", val,
mine.first_val, mine.second_val, mine.third_val, mine.fourth_val,
ptr->first_val, ptr->second_val, ptr->third_val, ptr->fourth_val);

// Stop here and check values
printf ("This is just another call which we won't make it over %d.", val);
Expand Down
Loading