Skip to content

Crash during disconnect_pin on a pin w/ SDC #327

@jhkim-pii

Description

@jhkim-pii

Crash happens when disconnect_pin is called to a pin with SDC.

Crash test case

disconnect_pin_with_sdc.tcl.zip

How to run:

  • Copy the crash.tcl into OpenSTA/test.
  • OpenSTA/test$ sta disconnect_pin_with_sdc.tcl

Crash stack trace

disconnect_pin the bus pin w/ SDC

Program received signal SIGSEGV, Segmentation fault.
0x000055555589da13 in sta::Sdc::disconnectPinBefore (this=0x5555560a5a60, pin=0x55555773ae60) at /workspace/OpenSTA/sdc/Sdc.cc:5636
5636            to->disconnectPinBefore(pin, network_);
(gdb) bt
#0  0x000055555589da13 in sta::Sdc::disconnectPinBefore (this=0x5555560a5a60, pin=0x55555773ae60) at /workspace/OpenSTA/sdc/Sdc.cc:5636
#1  0x00005555559c2653 in sta::Sta::disconnectPinBefore (this=0x5555560a4f80, pin=0x55555773ae60) at /workspace/OpenSTA/search/Sta.cc:4511
#2  0x00005555559c0e88 in sta::Sta::disconnectPin (this=0x5555560a4f80, pin=0x55555773ae60) at /workspace/OpenSTA/search/Sta.cc:4216
#3  0x00005555555a3f9d in disconnect_pin_cmd (pin=0x55555773ae60) at /workspace/OpenSTA/build/CMakeFiles/sta_swig.dir/StaAppTCL_wrap.cxx:3792
#4  0x00005555555e4db3 in _wrap_disconnect_pin_cmd (clientData=0x0, interp=0x55555600af40, objc=2, objv=0x555556018e68)
    at /workspace/OpenSTA/build/CMakeFiles/sta_swig.dir/StaAppTCL_wrap.cxx:21234
#5  0x00007ffff7e392f9 in TclNRRunCallbacks () from /lib/x86_64-linux-gnu/libtcl8.6.so
#6  0x00007ffff7e3a6bc in ?? () from /lib/x86_64-linux-gnu/libtcl8.6.so
#7  0x00007ffff7e3a10b in Tcl_EvalEx () from /lib/x86_64-linux-gnu/libtcl8.6.so
#8  0x00007ffff7e3b42a in Tcl_Eval () from /lib/x86_64-linux-gnu/libtcl8.6.so
#9  0x000055555566ed07 in sta::sourceTclFile (filename=0x7fffffffd8fd "disconnect_pin_with_sdc.tcl", echo=false, verbose=false, interp=0x55555600af40)
    at /workspace/OpenSTA/app/StaMain.cc:105
#10 0x0000555555599c8e in staTclAppInit (argc=2, argv=0x7fffffffd4d8, init_filename=0x555555c0b074 ".sta", interp=0x55555600af40) at /workspace/OpenSTA/app/Main.cc:160
#11 0x00005555555999e0 in tclAppInit (interp=0x55555600af40) at /workspace/OpenSTA/app/Main.cc:111
#12 0x00007ffff7ef0eea in Tcl_MainEx () from /lib/x86_64-linux-gnu/libtcl8.6.so
#13 0x00005555555999aa in main (argc=2, argv=0x7fffffffd4d8) at /workspace/OpenSTA/app/Main.cc:102

Command sequence

puts "set_multicycle_path on bus pins"
set_multicycle_path -end   -setup 1 -to [get_pins {u0/buf0/A}]
set_multicycle_path -end   -setup 1 -to [get_pins {u0/buf1/A}]
set_multicycle_path -end   -setup 1 -to [get_pins {u0/buf2/A}]
set_multicycle_path -end   -setup 1 -to [get_pins {u0/buf3/A}]

puts "disconnect_pin the bus pin w/ SDC"
set in_pin [get_pins u0/buf2/A]
set in_net [get_net -of $in_pin]
disconnect_pin $in_net $in_pin
### CRASH!!

puts "Done"

Suspect

  • In 5b312ee, pin_exceptions_ map is newly introduced.
  • Sdc::recordException(ExceptionPath*) inserts an element in pin_exceptions_ map.
  • But Sdc::unrecordException(ExceptionPath*) does not remove the inserted element in pin_exceptions_ map, which made stale pointers.

sdc/Sdc.cc

void
Sdc::recordException(ExceptionPath *exception)
{
  exceptions_.insert(exception);
  exception->setId(++exception_id_);
  recordMergeHashes(exception);
  recordExceptionFirstPts(exception);
  recordExceptionPins(exception);            // INSERT INTO pin_exceptions_ map
  checkForThruHpins(exception);
}
void
Sdc::unrecordException(ExceptionPath *exception)
{
  unrecordMergeHashes(exception);
  unrecordExceptionFirstPts(exception);
  exceptions_.erase(exception);
                                           // unrecordExceptionPins(exception) IS MISSING
}

Possible solution

Implement and call unrecordExceptionpins(ExceptionPath*).
No crash with this code change.

void
Sdc::unrecordException(ExceptionPath *exception)
{
  unrecordMergeHashes(exception);
  unrecordExceptionFirstPts(exception);
  unrecordExceptionPins(exception);       // FIX
  exceptions_.erase(exception);
}

void
Sdc::unrecordExceptionPins(ExceptionPath *exception)           // NEW API
{
  ExceptionFrom *from = exception->from();
  if (from)
    unrecordExceptionPins(exception, from->pins(), pin_exceptions_);
  ExceptionThruSeq *thrus = exception->thrus();
  if (thrus) {
    for (ExceptionThru *thru : *thrus)
      unrecordExceptionPins(exception, thru->pins(), pin_exceptions_);
  }
  ExceptionTo *to = exception->to();
  if (to)
    unrecordExceptionPins(exception, to->pins(), pin_exceptions_);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions