Skip to content

Detect repeated contract enforcement in goto-instrument#8754

Open
tautschnig wants to merge 1 commit intodiffblue:developfrom
tautschnig:fix-7830-contracts-twice
Open

Detect repeated contract enforcement in goto-instrument#8754
tautschnig wants to merge 1 commit intodiffblue:developfrom
tautschnig:fix-7830-contracts-twice

Conversation

@tautschnig
Copy link
Collaborator

goto-instrument must detect when it is being invoked again when contract enforcement has already been run as only one contract can be enforced at a time.

Fixes: #7830

  • Each commit message has a non-empty body, explaining why the change was made.
  • n/a Methods or procedures I have added are documented, following the guidelines provided in CODING_STANDARD.md.
  • n/a The feature or user visible behaviour I have added or modified has been documented in the User Guide in doc/cprover-manual/
  • Regression or unit tests are included, or existing tests cover the modified code (in this case I have detailed which ones those are in the commit message).
  • n/a My commit message includes data points confirming performance improvements (if claimed).
  • My PR is restricted to a single feature or bugfix.
  • n/a White-space or formatting changes outside the feature-related changed lines are in commits of their own.

@tautschnig tautschnig self-assigned this Feb 24, 2026
When goto-instrument is invoked multiple times to enforce contracts on
the same goto binary, the semantics break: without dfcc it fails during
checking, and with dfcc it fails due to arity mismatches from prior
instrumentation.

For the non-dfcc path (contracts.cpp), check if the mangled symbol
already exists before enforcing, and throw a user-facing error.

For the dfcc path (dfcc.cpp), check if the __dfcc_instrumented_functions
symbol exists in the input goto binary before constructing the dfcct
object. This check must happen before the dfcc library is loaded, since
the library constructor creates this symbol as part of normal operation.
Use invalid_input_exceptiont for a user-friendly error message rather
than PRECONDITION which is for programming errors.

Fixes: diffblue#7830

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
@tautschnig tautschnig force-pushed the fix-7830-contracts-twice branch from 6f45e45 to e1ff67c Compare March 18, 2026 10:12
@tautschnig tautschnig marked this pull request as ready for review March 18, 2026 10:29
Copilot AI review requested due to automatic review settings March 18, 2026 10:29
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds guards to prevent re-applying contract enforcement instrumentation when goto-instrument is run multiple times on already-instrumented binaries.

Changes:

  • Detect prior DFCC instrumentation via a marker symbol and abort with an exception.
  • Detect prior per-function contract enforcement by checking for the mangled “original” symbol and abort.
  • Reorder check_frame_conditions_function to run after the new “already enforced” guard.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/goto-instrument/contracts/dynamic-frames/dfcc.cpp Adds a binary-level “already enforced” check via a marker symbol and throws invalid_input_exceptiont.
src/goto-instrument/contracts/contracts.cpp Adds an “already enforced” check in enforce_contract by detecting the pre-existing mangled original symbol.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1223 to +1230
// Check if contract enforcement has already been applied to this function
if(symbol_table.has_symbol(mangled))
{
throw invalid_input_exceptiont(
"Contract enforcement has already been applied to function '" +
id2string(function) +
"'.\nOnly one contract may be enforced at a time per function.");
}
Comment on lines +105 to +111
// Check if contract enforcement has already been applied to this binary
if(goto_model.symbol_table.has_symbol("__dfcc_instrumented_functions"))
{
throw invalid_input_exceptiont(
"Contract enforcement has already been applied to this binary.\n"
"Only one contract may be enforced at a time.");
}
Comment on lines +105 to +111
// Check if contract enforcement has already been applied to this binary
if(goto_model.symbol_table.has_symbol("__dfcc_instrumented_functions"))
{
throw invalid_input_exceptiont(
"Contract enforcement has already been applied to this binary.\n"
"Only one contract may be enforced at a time.");
}
@codecov
Copy link

codecov bot commented Mar 18, 2026

Codecov Report

❌ Patch coverage is 33.33333% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.41%. Comparing base (85c204f) to head (e1ff67c).

Files with missing lines Patch % Lines
src/goto-instrument/contracts/contracts.cpp 33.33% 4 Missing ⚠️
.../goto-instrument/contracts/dynamic-frames/dfcc.cpp 33.33% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #8754      +/-   ##
===========================================
- Coverage    80.41%   80.41%   -0.01%     
===========================================
  Files         1703     1703              
  Lines       188398   188406       +8     
  Branches        73       73              
===========================================
+ Hits        151498   151501       +3     
- Misses       36900    36905       +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Safety feature] Error when enforcing contracts twice

2 participants