Repository navigation
odb: avoid segfault in insert_buffer and makeNewName when base name is null - #12150
bandhambalaji wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Code Review
This pull request adds null and empty-string checks for base names and full names in dbBlock.cpp and dbInsertBuffer.cpp to prevent potential null pointer dereferences. However, the feedback highlights that the silent fallbacks introduced in dbBlock.cpp (defaulting to 'unnamed' or returning an empty string) violate the OpenROAD style guide against hiding impossible states. It is recommended to use assertions instead of silent defaults for these invalid states.
| const char* safe_base_name | ||
| = (base_name && base_name[0] != '\0') ? base_name : "unnamed"; | ||
| buf.append(fmt::string_view(safe_base_name)); |
There was a problem hiding this comment.
According to the OpenROAD style guide, we should avoid silent fallbacks (like defaulting to "unnamed") for impossible or invalid states. Since base_name being null is an invalid state that should be handled at the caller/API boundary (as you did in dbInsertBuffer), we should assert that base_name is not null here rather than silently falling back to "unnamed".
assert(base_name != nullptr);
buf.append(fmt::string_view(base_name));References
- Never suggest a guard that hides an impossible state: a null check, an empty, zero or negative check, or a missing-key check that returns a default, skips, clamps,
continues or logs a warning and carries on. A null dereference that is reachable is reported with its triggering input; the fix islogger_->error(...)or an assert, never a silent default. (link)
| if (full_name == nullptr) { | ||
| return ""; | ||
| } |
There was a problem hiding this comment.
According to the OpenROAD style guide, we should avoid silent fallbacks (like returning "") for impossible or invalid states. If full_name being null is an invalid state, we should assert that it is not null rather than silently returning an empty string.
assert(full_name != nullptr);References
- Never suggest a guard that hides an impossible state: a null check, an empty, zero or negative check, or a missing-key check that returns a default, skips, clamps,
continues or logs a warning and carries on. A null dereference that is reachable is reported with its triggering input; the fix islogger_->error(...)or an assert, never a silent default. (link)
There was a problem hiding this comment.
Welcome to OpenROAD! Thanks for opening your first PR.
Before we review:
- Contribution Guide: https://openroad.readthedocs.io/en/latest/contrib/GettingInvolved.html
- Build Instructions: https://openroad.readthedocs.io/en/latest/user/Build.html
Please ensure:
- CI passes
- Code is properly formatted
- Tests are included where applicable
A maintainer will review shortly!
…s null
When insert_buffer is invoked without -buffer_name or -net_name (e.g.
with a single load pin or inferred nets), nullptr is forwarded into
dbInsertBuffer::insertBufferSimple and insertBufferBeforeLoads.
Assigning nullptr directly to new_buf_base_name_ overrides the default
base name kDefaultBufBaseName and causes _dbBlock::makeNewName to
execute fmt::string_view(nullptr) / strlen(nullptr), resulting in a
Segmentation Fault (Signal 11).
- Fall back to kDefaultBufBaseName ("buf") and kDefaultNetBaseName ("net")
in dbInsertBuffer::insertBufferSimple and insertBufferBeforeLoads when
the incoming base names are null or empty.
- Add defensive null checks in _dbBlock::makeNewName and dbBlock::getBaseName
to guard against null dereference.
Fixes The-OpenROAD-Project#12016.
Signed-off-by: Bandham Balaji <bandhambalaji@gmail.com>
c10b41f to
342b714
Compare
|
I think the original issue is that rsz sends a null name to odb. I'd rather fix that behavior in rsz and throw an error in odb when the name is not given. However, this is out of my scope so a review from @The-OpenROAD-Project/openroad-rsz would be helpful. @precisionmoon |
precisionmoon
left a comment
There was a problem hiding this comment.
Thanks much for the contribution. Can you add a regression test to exercise the code fix please?
Exercise both insertBufferBeforeLoads and insertBufferBeforeLoad when base names are passed as nullptr, verifying fallback to default names without crashing in _dbBlock::makeNewName. Ref The-OpenROAD-Project#12016. Signed-off-by: Bandham Balaji <bandhambalaji@gmail.com>
|
Added a regression test to |
Summary
When
insert_bufferis invoked without-buffer_nameor-net_name(e.g. buffering a single load pin or inferred nets),nullptris forwarded through the Resizer layer intodbInsertBuffer. Assigningnullptrdirectly tonew_buf_base_name_overrideskDefaultBufBaseNameand causes_dbBlock::makeNewNameto executefmt::string_view(nullptr), triggering a Segmentation Fault (Signal 11).Solution
kDefaultBufBaseName("buf") andkDefaultNetBaseName("net") indbInsertBuffer::insertBufferSimpleanddbInsertBuffer::insertBufferBeforeLoadswhen incoming names are null or empty._dbBlock::makeNewNameanddbBlock::getBaseName.Fixes #12016.