[Lldb-commits] [lldb] [lldb] fix a problem in the ValueObject::GetExpressionPath method (PR #171521)
Matej Košík via lldb-commits
lldb-commits at lists.llvm.org
Sun Dec 14 12:41:14 PST 2025
https://github.com/sedymrak updated https://github.com/llvm/llvm-project/pull/171521
>From 13c06e2b4100ba8999d11ec0d2dc0c0038b6d402 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matej=20Ko=C5=A1=C3=ADk?= <matej.kosik at codasip.com>
Date: Tue, 9 Dec 2025 23:12:51 +0100
Subject: [PATCH 1/7] [lldb] add a test that demonstrates the problem with the
"ValueObject::GetExpressionPath" method
---
.../python_api/value/get_expr_path/Makefile | 3 ++
.../TestValueAPIGetExpressionPath.py | 50 +++++++++++++++++++
.../API/python_api/value/get_expr_path/main.c | 5 ++
3 files changed, 58 insertions(+)
create mode 100644 lldb/test/API/python_api/value/get_expr_path/Makefile
create mode 100644 lldb/test/API/python_api/value/get_expr_path/TestValueAPIGetExpressionPath.py
create mode 100644 lldb/test/API/python_api/value/get_expr_path/main.c
diff --git a/lldb/test/API/python_api/value/get_expr_path/Makefile b/lldb/test/API/python_api/value/get_expr_path/Makefile
new file mode 100644
index 0000000000000..10495940055b6
--- /dev/null
+++ b/lldb/test/API/python_api/value/get_expr_path/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/python_api/value/get_expr_path/TestValueAPIGetExpressionPath.py b/lldb/test/API/python_api/value/get_expr_path/TestValueAPIGetExpressionPath.py
new file mode 100644
index 0000000000000..227588c412587
--- /dev/null
+++ b/lldb/test/API/python_api/value/get_expr_path/TestValueAPIGetExpressionPath.py
@@ -0,0 +1,50 @@
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class ValueAPIGetExpressionPath(TestBase):
+ def test(self):
+ self.build()
+
+ _, _, thread, _ = lldbutil.run_to_source_breakpoint(
+ self, "Break at this line", lldb.SBFileSpec("main.c")
+ )
+ frame = thread.GetFrameAtIndex(0)
+
+ self.assertEqual(frame.FindVariable("foo").get_expr_path(), "foo")
+ for i in range(2):
+ self.assertEqual(
+ frame.FindVariable("foo").GetChildAtIndex(i).get_expr_path(),
+ f"foo[{i}]",
+ )
+ for j in range(3):
+ self.assertEqual(
+ frame.FindVariable("foo")
+ .GetChildAtIndex(i)
+ .GetChildAtIndex(j)
+ .get_expr_path(),
+ f"foo[{i}][{j}]",
+ )
+ for k in range(4):
+ self.assertEqual(
+ frame.FindVariable("foo")
+ .GetChildAtIndex(i)
+ .GetChildAtIndex(j)
+ .GetChildAtIndex(k)
+ .get_expr_path(),
+ f"foo[{i}][{j}][{k}]",
+ )
+ self.assertEqual(frame.FindVariable("bar").get_expr_path(), "bar")
+ for j in range(3):
+ self.assertEqual(
+ frame.FindVariable("bar").GetChildAtIndex(j).get_expr_path(), f"(*bar)[{j}]"
+ )
+ for k in range(4):
+ self.assertEqual(
+ frame.FindVariable("bar")
+ .GetChildAtIndex(j)
+ .GetChildAtIndex(k)
+ .get_expr_path(),
+ f"(*bar)[{j}][{k}]",
+ )
diff --git a/lldb/test/API/python_api/value/get_expr_path/main.c b/lldb/test/API/python_api/value/get_expr_path/main.c
new file mode 100644
index 0000000000000..f6fcb11e36835
--- /dev/null
+++ b/lldb/test/API/python_api/value/get_expr_path/main.c
@@ -0,0 +1,5 @@
+int main() {
+ int foo[2][3][4];
+ int (*bar)[3][4] = foo;
+ return 0; // Break at this line
+}
>From 3b3c3048172d095246efd11bd11ad1b4dc2ce6ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matej=20Ko=C5=A1=C3=ADk?= <matej.kosik at codasip.com>
Date: Tue, 9 Dec 2025 16:35:49 +0100
Subject: [PATCH 2/7] [lldb] fix the "ValueObject::GetExpressionPath" method
---
lldb/source/ValueObject/ValueObject.cpp | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/lldb/source/ValueObject/ValueObject.cpp b/lldb/source/ValueObject/ValueObject.cpp
index aeea32f19ee2c..3bbb917e51976 100644
--- a/lldb/source/ValueObject/ValueObject.cpp
+++ b/lldb/source/ValueObject/ValueObject.cpp
@@ -2138,6 +2138,20 @@ void ValueObject::GetExpressionPath(Stream &s,
ValueObject *parent = GetParent();
+ if (parent) {
+ lldb_private::CompilerType parentType = parent->GetCompilerType();
+ const bool parentTypeIsPointer = parentType.IsPointerType();
+ const bool pointeeOfParentTypeIsArray =
+ parentType.GetPointeeType().IsArrayType(nullptr, nullptr, nullptr);
+ if (parentTypeIsPointer && pointeeOfParentTypeIsArray) {
+ s.PutCString("(*");
+ parent->GetExpressionPath(s, epformat);
+ s.PutCString(")");
+ s.PutCString(GetName().GetCString());
+ return;
+ }
+ }
+
if (parent)
parent->GetExpressionPath(s, epformat);
>From e9b6b21de1a948a46ca038c97e9e407be5887266 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matej=20Ko=C5=A1=C3=ADk?= <matej.kosik at codasip.com>
Date: Tue, 9 Dec 2025 23:54:28 +0100
Subject: [PATCH 3/7] formatting
---
.../value/get_expr_path/TestValueAPIGetExpressionPath.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lldb/test/API/python_api/value/get_expr_path/TestValueAPIGetExpressionPath.py b/lldb/test/API/python_api/value/get_expr_path/TestValueAPIGetExpressionPath.py
index 227588c412587..a2de8df9cc170 100644
--- a/lldb/test/API/python_api/value/get_expr_path/TestValueAPIGetExpressionPath.py
+++ b/lldb/test/API/python_api/value/get_expr_path/TestValueAPIGetExpressionPath.py
@@ -38,7 +38,8 @@ def test(self):
self.assertEqual(frame.FindVariable("bar").get_expr_path(), "bar")
for j in range(3):
self.assertEqual(
- frame.FindVariable("bar").GetChildAtIndex(j).get_expr_path(), f"(*bar)[{j}]"
+ frame.FindVariable("bar").GetChildAtIndex(j).get_expr_path(),
+ f"(*bar)[{j}]",
)
for k in range(4):
self.assertEqual(
>From 0d2b6bf47ca0b72c68cd498d0a86db91cdf7f8a6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matej=20Ko=C5=A1=C3=ADk?= <matej.kosik at codasip.com>
Date: Wed, 10 Dec 2025 09:26:27 +0100
Subject: [PATCH 4/7] [lldb] update the proposed solution with respect to the
feedback provided for my pull-request
---
lldb/source/ValueObject/ValueObject.cpp | 3 +--
.../value/get_expr_path/TestValueAPIGetExpressionPath.py | 4 ++--
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/lldb/source/ValueObject/ValueObject.cpp b/lldb/source/ValueObject/ValueObject.cpp
index 3bbb917e51976..23dee9763bda8 100644
--- a/lldb/source/ValueObject/ValueObject.cpp
+++ b/lldb/source/ValueObject/ValueObject.cpp
@@ -2144,9 +2144,8 @@ void ValueObject::GetExpressionPath(Stream &s,
const bool pointeeOfParentTypeIsArray =
parentType.GetPointeeType().IsArrayType(nullptr, nullptr, nullptr);
if (parentTypeIsPointer && pointeeOfParentTypeIsArray) {
- s.PutCString("(*");
parent->GetExpressionPath(s, epformat);
- s.PutCString(")");
+ s.PutCString("[0]");
s.PutCString(GetName().GetCString());
return;
}
diff --git a/lldb/test/API/python_api/value/get_expr_path/TestValueAPIGetExpressionPath.py b/lldb/test/API/python_api/value/get_expr_path/TestValueAPIGetExpressionPath.py
index a2de8df9cc170..96eb0dfa2ebc8 100644
--- a/lldb/test/API/python_api/value/get_expr_path/TestValueAPIGetExpressionPath.py
+++ b/lldb/test/API/python_api/value/get_expr_path/TestValueAPIGetExpressionPath.py
@@ -39,7 +39,7 @@ def test(self):
for j in range(3):
self.assertEqual(
frame.FindVariable("bar").GetChildAtIndex(j).get_expr_path(),
- f"(*bar)[{j}]",
+ f"bar[0][{j}]",
)
for k in range(4):
self.assertEqual(
@@ -47,5 +47,5 @@ def test(self):
.GetChildAtIndex(j)
.GetChildAtIndex(k)
.get_expr_path(),
- f"(*bar)[{j}][{k}]",
+ f"bar[0][{j}][{k}]",
)
>From 94286d9b7fde09e5a7ec8dde2d2987f9e36a3410 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matej=20Ko=C5=A1=C3=ADk?= <matej.kosik at codasip.com>
Date: Wed, 10 Dec 2025 23:13:47 +0100
Subject: [PATCH 5/7] add a "const" qualifier
---
lldb/source/ValueObject/ValueObject.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lldb/source/ValueObject/ValueObject.cpp b/lldb/source/ValueObject/ValueObject.cpp
index 23dee9763bda8..4e70c4befb77f 100644
--- a/lldb/source/ValueObject/ValueObject.cpp
+++ b/lldb/source/ValueObject/ValueObject.cpp
@@ -2139,7 +2139,7 @@ void ValueObject::GetExpressionPath(Stream &s,
ValueObject *parent = GetParent();
if (parent) {
- lldb_private::CompilerType parentType = parent->GetCompilerType();
+ const lldb_private::CompilerType parentType = parent->GetCompilerType();
const bool parentTypeIsPointer = parentType.IsPointerType();
const bool pointeeOfParentTypeIsArray =
parentType.GetPointeeType().IsArrayType(nullptr, nullptr, nullptr);
>From ff7ee2cf32ef0f1257c61578ab40ed4bba588b9f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matej=20Ko=C5=A1=C3=ADk?= <matej.kosik at codasip.com>
Date: Sun, 14 Dec 2025 20:27:33 +0100
Subject: [PATCH 6/7] [lldb] further simplify the proposed solution
---
lldb/source/ValueObject/ValueObject.cpp | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/lldb/source/ValueObject/ValueObject.cpp b/lldb/source/ValueObject/ValueObject.cpp
index 4e70c4befb77f..d1ba08b7e5159 100644
--- a/lldb/source/ValueObject/ValueObject.cpp
+++ b/lldb/source/ValueObject/ValueObject.cpp
@@ -2139,21 +2139,16 @@ void ValueObject::GetExpressionPath(Stream &s,
ValueObject *parent = GetParent();
if (parent) {
- const lldb_private::CompilerType parentType = parent->GetCompilerType();
- const bool parentTypeIsPointer = parentType.IsPointerType();
- const bool pointeeOfParentTypeIsArray =
- parentType.GetPointeeType().IsArrayType(nullptr, nullptr, nullptr);
- if (parentTypeIsPointer && pointeeOfParentTypeIsArray) {
- parent->GetExpressionPath(s, epformat);
+ parent->GetExpressionPath(s, epformat);
+ const CompilerType parentType = parent->GetCompilerType();
+ if (parentType.IsPointerType() &&
+ parentType.GetPointeeType().IsArrayType(nullptr, nullptr, nullptr)) {
s.PutCString("[0]");
s.PutCString(GetName().GetCString());
return;
}
}
- if (parent)
- parent->GetExpressionPath(s, epformat);
-
// if we are a deref_of_parent just because we are synthetic array members
// made up to allow ptr[%d] syntax to work in variable printing, then add our
// name ([%d]) to the expression path
>From 92852f0cca5e57904e24d794359e63f5b196219a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matej=20Ko=C5=A1=C3=ADk?= <matej.kosik at codasip.com>
Date: Sun, 14 Dec 2025 21:35:45 +0100
Subject: [PATCH 7/7] [lldb] add a comment explaining what is being done and
why
---
lldb/source/ValueObject/ValueObject.cpp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lldb/source/ValueObject/ValueObject.cpp b/lldb/source/ValueObject/ValueObject.cpp
index d1ba08b7e5159..121054e3e92ed 100644
--- a/lldb/source/ValueObject/ValueObject.cpp
+++ b/lldb/source/ValueObject/ValueObject.cpp
@@ -2143,6 +2143,12 @@ void ValueObject::GetExpressionPath(Stream &s,
const CompilerType parentType = parent->GetCompilerType();
if (parentType.IsPointerType() &&
parentType.GetPointeeType().IsArrayType(nullptr, nullptr, nullptr)) {
+ // When the parent is a pointer to an array, then we have to:
+ // - follow the expression path of the parent with "[0]"
+ // (that will indicate dereferencing the pointer to the array)
+ // - and then follow that with this ValueObject's name
+ // (which will be something like "[i]" to indicate
+ // the i-th element of the array)
s.PutCString("[0]");
s.PutCString(GetName().GetCString());
return;
More information about the lldb-commits
mailing list