Skip to content

odb: avoid segfault in insert_buffer and makeNewName when base name is null - #12150

Open
bandhambalaji wants to merge 2 commits into
The-OpenROAD-Project:masterfrom
bandhambalaji:fix-insert-buffer-null-name
Open

bandhambalaji wants to merge 2 commits into
The-OpenROAD-Project:masterfrom
bandhambalaji:fix-insert-buffer-null-name

Conversation

@bandhambalaji

Copy link
Copy Markdown

Summary

When insert_buffer is invoked without -buffer_name or -net_name (e.g. buffering a single load pin or inferred nets), nullptr is forwarded through the Resizer layer into dbInsertBuffer. Assigning nullptr directly to new_buf_base_name_ overrides kDefaultBufBaseName and causes _dbBlock::makeNewName to execute fmt::string_view(nullptr), triggering a Segmentation Fault (Signal 11).

Solution

  1. Fall back to kDefaultBufBaseName ("buf") and kDefaultNetBaseName ("net") in dbInsertBuffer::insertBufferSimple and dbInsertBuffer::insertBufferBeforeLoads when incoming names are null or empty.
  2. Add defensive null checks in _dbBlock::makeNewName and dbBlock::getBaseName.

Fixes #12016.

@bandhambalaji
bandhambalaji requested a review from a team as a code owner November 6, 2026 18:51
@github-actions github-actions Bot added the size/S label Nov 6, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread src/odb/src/db/dbBlock.cpp Outdated
Comment on lines +3844 to +3846
const char* safe_base_name
= (base_name && base_name[0] != '\0') ? base_name : "unnamed";
buf.append(fmt::string_view(safe_base_name));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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
  1. 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 is logger_->error(...) or an assert, never a silent default. (link)

Comment thread src/odb/src/db/dbBlock.cpp Outdated
Comment on lines +3989 to +3991
if (full_name == nullptr) {
return "";
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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
  1. 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 is logger_->error(...) or an assert, never a silent default. (link)

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Welcome to OpenROAD! Thanks for opening your first PR.
Before we review:

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>
@bandhambalaji
bandhambalaji force-pushed the fix-insert-buffer-null-name branch from c10b41f to 342b714 Compare November 7, 2026 02:31
@osamahammad21
osamahammad21 requested review from a team and precisionmoon and removed request for a team November 7, 2026 14:50
@osamahammad21

Copy link
Copy Markdown
Member

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 precisionmoon left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Author

Added a regression test to src/odb/test/cpp/TestInsertBuffer.cpp exercising both single-load and multi-load buffer insertions with nullptr base names to ensure default name fallback without crashing. Ready for review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

insert_buffer segfaults naming the buffer for a single load pin without -buffer_name

3 participants