There is a regression found when testing eppic extension on gdb-16.2
crash:
crash> cgroup
/root/.eppic/cgroup.c : line 99 : Error: undefined variable 'cgroup_roots'
The root cause is when doing gdb upgrading, the replacement of
gdb_get_datatype() is incorrect:
The original gdb-10.2 version:
long value = SYMBOL_VALUE(expr->elts[2].symbol);
The incorrect gdb-16.2 replacement:
long value = value_as_long(expr->evaluate());
According to gdb/tracepoint.c, the correct gdb-16.2 replacement should be:
symbol *sym;
expr::var_value_operation *vvop
= (gdb::checked_static_cast<expr::var_value_operation *>
(exp->op.get ()));
sym = vvop->get_symbol ();
long value = sym->value_longest ();
Otherwise, the value_as_long() will throw an exception when trying to
convert a struct into long, such as "cgroup_roots". The reason why this
issue only observed on crash extensions, is the faulty code block
triggered with "req->tcb", which is a callback for gdb_interface(), and
the callback is used by eppic extension, but the normal crash internal calls
hardly use it.
After:
crash> cgroup
0:/user.slice/user-1000.slice/session-2.scope
Signed-off-by: Tao Liu <ltao(a)redhat.com>
---
gdb-16.2.patch | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/gdb-16.2.patch b/gdb-16.2.patch
index 151e4e2..eb620f7 100644
--- a/gdb-16.2.patch
+++ b/gdb-16.2.patch
@@ -1952,3 +1952,32 @@ exit 0
}
/* Remember the bfd indexes for the .text, .data, .bss and
+--- gdb-16.2/gdb/symtab.c.orig
++++ gdb-16.2/gdb/symtab.c
+@@ -7690,7 +7690,11 @@
+ console("expr->first_opcode(): OP_VAR_VALUE\n");
+ type = expr->evaluate_type()->type();
+ if (req->tcb) {
+- long value = value_as_long(expr->evaluate());
++ expr::var_value_operation *vvop
++ = (gdb::checked_static_cast<expr::var_value_operation *>
++ (expr->op.get ()));
++ sym = vvop->get_symbol ();
++ long value = sym->value_longest ();
+ /* callback with symbol value */
+ req->typecode = TYPE_CODE(type);
+ req->tcb(EOP_VALUE, req, &value, 0, 0, 0);
+@@ -7701,8 +7705,12 @@
+ req->length = type->length();
+ }
+ if (TYPE_CODE(type) == TYPE_CODE_ENUM) {
++ expr::var_value_operation *vvop
++ = (gdb::checked_static_cast<expr::var_value_operation *>
++ (expr->op.get ()));
++ sym = vvop->get_symbol ();
+ req->typecode = TYPE_CODE(type);
+- req->value = value_as_long(expr->evaluate());
++ req->value = sym->value_longest ();
+ req->tagname = (char *)TYPE_TAG_NAME(type);
+ if (!req->tagname) {
+ val = expr->evaluate_type();
--
2.47.0