unable to elaborate cva6 (ariane) [possible UHDM issue]
When I attempt to elaborate the v5.0.1 version of cva6 (ariane followon) I get the following error (using version v1.83):
[INF:EL0526] Design Elaboration...
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string_view::substr: __pos (which is 323) > __size (which is 1)
Attached is a testcase you can run to see the issue: sc_issue_cva6_job0_import0_20240524-222628.tar.gz
tar xvf sc_issue_cva6_job0_import0_20240524-222628.tar.gz
cd sc_issue_cva6_job0_import0_20240524-222628.tar.gz
./run.sh
Let me know if you need additional information.
@alaindargelas @hzeller are there any updated on this issue?
We kinda got all busy with other things, so currently is slow progress.
@hzeller thanks for letting me know. When you have time to look at this let me know if there is anything else I can provide to help.
@hzeller @alaindargelas any updates on this?
@gadfort I myself don't have time to work on this , but I can find a developer for hire to dig into it. Do you have a $ budget for this?
Adding some notes to reproduce and run through a debugger:
Built surelog in debug mode and put in some 'installation' directory:
make clean
mkdir -p /tmp/test-surelog
make PREFIX=/tmp/test-surelog debug
PREFIX=/tmp/test-surelog cmake --install dbuild
then, in the reproduce untar directory sc_issue_cva6_job0_import0_20240524-222628/, edit
build/cva6/job0/import/0/replay.sh to invoke surelog with a debugger, so instead of simply surelog the invocation looks like something like gdb --ex=run --args /tmp/test-surelog/bin/surelog
When it crashes (call bt to get the backtrace), it is possible to see where it happens, a substr() call in UHDM::ExprEval::hierarchicalSelector()
#10 0x0000000000c6e542 in UHDM::ExprEval::hierarchicalSelector (this=0x7ffffffe8e60, select_path=std::vector of length 2, capacity 2 = {...}, level=1, object=0x14fd7ae0,
invalidValue=@0x7ffffffe96e0: false, inst=0x2125e470, pexpr=0x0, returnTypespec=false, muteError=false) at Surelog/dbuild/third_party/UHDM/generated/src/ExprEval.cpp:2530
#11 0x0000000000c6ec04 in UHDM::ExprEval::hierarchicalSelector (this=0x7ffffffe8e60, select_path=std::vector of length 2, capacity 2 = {...}, level=0, object=0x14fd7ae0,
invalidValue=@0x7ffffffe96e0: false, inst=0x2125e470, pexpr=0x0, returnTypespec=false, muteError=false) at Surelog/dbuild/third_party/UHDM/generated/src/ExprEval.cpp:2604
#12 0x0000000000c6cc43 in UHDM::ExprEval::decodeHierPath (this=0x7ffffffe8e60, path=0x14e8f570, invalidValue=@0x7ffffffe96e0: false, inst=0x2125e470, pexpr=0x0, returnTypespec=false, muteError=false)
at Surelog/dbuild/third_party/UHDM/generated/src/ExprEval.cpp:2251
#13 0x0000000000c79c17 in UHDM::ExprEval::reduceExpr (this=0x7ffffffe8e60, result=0x14e8f570, invalidValue=@0x7ffffffe96e0: false, inst=0x2125e470, pexpr=0x0, muteError=false)
at Surelog/dbuild/third_party/UHDM/generated/src/ExprEval.cpp:4276
#14 0x0000000000c70c00 in UHDM::ExprEval::reduceExpr (this=0x7ffffffe8e60, result=0x14e8f2a0, invalidValue=@0x7ffffffe96e0: false, inst=0x2125e470, pexpr=0x0, muteError=false)
at Surelog/dbuild/third_party/UHDM/generated/src/ExprEval.cpp:2972
#15 0x0000000000b62492 in SURELOG::CompileHelper::reduceExpr (this=0x38e2f318, result=0x14e8f2a0, invalidValue=@0x7ffffffe96e0: false, component=0x391786b0, compileDesign=0x39036fe0, instance=0x0,
fileId=..., lineNumber=120, pexpr=0x0, muteErrors=false) at Surelog/src/DesignCompile/CompileExpression.cpp:817
#16 0x0000000000b71343 in SURELOG::CompileHelper::compileExpression (this=0x38e2f318, component=0x391786b0, fC=0x356b45a0, parent=..., compileDesign=0x39036fe0, reduce=SURELOG::Reduce::Yes,
pexpr=0x0, instance=0x0, muteErrors=false) at Surelog/src/DesignCompile/CompileExpression.cpp:3356
#17 0x0000000000b689fb in SURELOG::CompileHelper::compileExpression (this=0x38e2f318, component=0x391786b0, fC=0x356b45a0, parent=..., compileDesign=0x39036fe0, reduce=SURELOG::Reduce::Yes,
pexpr=0x0, instance=0x0, muteErrors=false) at Surelog/src/DesignCompile/CompileExpression.cpp:1789
#18 0x0000000000b689fb in SURELOG::CompileHelper::compileExpression (this=0x38e2f318, component=0x391786b0, fC=0x356b45a0, parent=..., compileDesign=0x39036fe0, reduce=SURELOG::Reduce::Yes,
pexpr=0x0, instance=0x0, muteErrors=false) at Surelog/src/DesignCompile/CompileExpression.cpp:1789
#19 0x0000000000b69b9b in SURELOG::CompileHelper::compileExpression (this=0x38e2f318, component=0x391786b0, fC=0x356b45a0, parent=..., compileDesign=0x39036fe0, reduce=SURELOG::Reduce::Yes,
pexpr=0x0, instance=0x0, muteErrors=false) at Surelog/src/DesignCompile/CompileExpression.cpp:1990
Which is in UHDM/templates/ExprEval.cpp:2530
Snippet (with relevant comments added):
if (ttps == UHDM_OBJECT_TYPE::uhdmstruct_typespec) {
struct_typespec *stpt = (struct_typespec *)ts;
uint64_t from = 0; // <-- initialized to zero
uint64_t width = 0;
for (typespec_member *member : *stpt->Members()) {
if (member->VpiName() == elemName) {
width = size(member, invalidValue, inst, pexpr, true);
if (cons->VpiSize() <= 64) {
uint64_t iv = get_value(invalidValue, cons);
uint64_t mask = 0;
for (uint64_t i = from; i < uint64_t(from + width); i++) {
mask |= ((uint64_t)1 << i);
}
uint64_t res = iv & mask;
res = res >> (from);
cons->VpiValue("UINT:" + std::to_string(res));
cons->VpiSize(static_cast<int32_t>(width));
cons->VpiConstType(vpiUIntConst);
return cons;
} else {
std::string_view val = cons->VpiValue();
int32_t ctype = cons->VpiConstType();
if (ctype == vpiHexConst) {
std::string_view vval =
val.substr(strlen("HEX:"), std::string::npos);
std::string bin = NumUtils::hexToBin(vval);
std::string res = bin.substr(from, width);
cons->VpiValue("BIN:" + res);
cons->VpiSize(static_cast<int32_t>(width));
cons->VpiConstType(vpiBinaryConst);
return cons;
} else if (ctype == vpiBinaryConst) {
std::string_view bin =
val.substr(strlen("BIN:"), std::string::npos);
std::string_view res = bin.substr(from, width); // <-- here, from is 323 but bin.size() is only 1
cons->VpiValue("BIN:" + std::string(res));
cons->VpiSize(static_cast<int32_t>(width));
cons->VpiConstType(vpiBinaryConst);
return cons;
}
}
} else {
from += size(member, invalidValue, inst, pexpr, true); // <-- only way to get bigger.
}
}
So from the binary value, which is of size 1, we try to request a substring 323 from the beginning. from is initialized to zero in line 2497 and only getting larger values with the from += size(...) call.
So it seems like from got advanced to 323 until we then finally went into that part of the hierarchy extracting the binary value.
I don't know this part of the code, but hopefully this helps to start digging. Maybe @alaindargelas sees immediately what is going on here.
Fixed by #4045