Surelog icon indicating copy to clipboard operation
Surelog copied to clipboard

unable to elaborate cva6 (ariane) [possible UHDM issue]

Open gadfort opened this issue 1 year ago • 6 comments

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.

gadfort avatar May 25 '24 02:05 gadfort

@alaindargelas @hzeller are there any updated on this issue?

gadfort avatar Jun 29 '24 00:06 gadfort

We kinda got all busy with other things, so currently is slow progress.

hzeller avatar Jun 29 '24 00:06 hzeller

@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.

gadfort avatar Jun 29 '24 00:06 gadfort

@hzeller @alaindargelas any updates on this?

gadfort avatar Oct 18 '24 00:10 gadfort

@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?

alaindargelas avatar Oct 18 '24 01:10 alaindargelas

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.

hzeller avatar Nov 10 '24 17:11 hzeller

Fixed by #4045

alaindargelas avatar Jul 22 '25 04:07 alaindargelas