Skip to content

Concretize values based on seeds when available, remove --zero-seed-extension and improve/fix seeding code#1663

Merged
MartinNowack merged 9 commits intoklee:masterfrom
ccadar:seed_concretization
Jan 30, 2024
Merged

Concretize values based on seeds when available, remove --zero-seed-extension and improve/fix seeding code#1663
MartinNowack merged 9 commits intoklee:masterfrom
ccadar:seed_concretization

Conversation

@ccadar
Copy link
Contributor

@ccadar ccadar commented Oct 20, 2023

Summary:

Concretize values based on seeds when available. The three commits handle the cases of concretizing an expression via toConstant, performing an external call with symbolic arguments and calling malloc with a symbolic argument, respectively.
Each case is accompanied by a test.

The PR is based on #1117 by @hoangmle

Checklist:

  • The PR addresses a single issue. If it can be divided into multiple independent PRs, please do so.
  • The PR is divided into a logical sequence of commits OR a single commit is sufficient.
  • There are no unnecessary commits (e.g. commits fixing issues in a previous commit in the same PR).
  • Each commit has a meaningful message documenting what it does.
  • All messages added to the codebase, all comments, as well as commit messages are spellchecked.
  • The code is commented OR not applicable/necessary.
  • The patch is formatted via clang-format OR not applicable (if explicitly overridden leave unchecked and explain).
  • There are test cases for the code you added or modified OR no such test cases are required.

@codecov
Copy link

codecov bot commented Oct 20, 2023

Codecov Report

Merging #1663 (4ee8690) into master (9edf8e8) will increase coverage by 0.12%.
Report is 1 commits behind head on master.
The diff coverage is 61.66%.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1663      +/-   ##
==========================================
+ Coverage   70.48%   70.61%   +0.12%     
==========================================
  Files         154      154              
  Lines       18870    18875       +5     
  Branches     4424     4426       +2     
==========================================
+ Hits        13301    13328      +27     
+ Misses       3654     3630      -24     
- Partials     1915     1917       +2     
Files Coverage Δ
include/klee/Expr/Assignment.h 84.37% <100.00%> (ø)
lib/Core/Executor.h 77.27% <ø> (ø)
lib/Core/SeedInfo.cpp 11.53% <0.00%> (+0.69%) ⬆️
lib/Core/Executor.cpp 77.20% <69.23%> (+0.76%) ⬆️

... and 1 file with indirect coverage changes

Copy link
Contributor

@MartinNowack MartinNowack left a comment

Choose a reason for hiding this comment

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

@ccadar Thanks for reviving @hoangmle's PR and adding support for better seed handling.

I've added a more thorough comment to the first change.
Follow-up changes have similar issues.

In a nutshell, not every seed might lead to a constant expression, especially with changing pointers across runs plus patching up seeds.

@ccadar
Copy link
Contributor Author

ccadar commented Oct 30, 2023

@MartinNowack thanks for the thorough review. My understanding was that @hoangmle 's contribution handled the most common case of a single seed -- see also the test cases. I was fine with that, and I think it's strictly better than what we have now. But let me think if the more complex cases could be easily handled as well.

@ccadar ccadar mentioned this pull request Oct 30, 2023
8 tasks
@ccadar ccadar force-pushed the seed_concretization branch 7 times, most recently from 35b638b to 760b500 Compare November 8, 2023 19:43
@ccadar ccadar changed the title Concretize values based on seeds when available Concretize values based on seeds when available, remove --zero-seed-extension and improve/fix seeding code Nov 8, 2023
@ccadar
Copy link
Contributor Author

ccadar commented Nov 8, 2023

@MartinNowack thanks for the excellent review.
I have now extended the code to work with seed extension. In the process, I fixed a buffer overflow there and in general improved the code a bit. I have decided to remove --zero-seed-extension and merge it into --allow-seed-extension, as --zero-seed-extension, as implemented & documented, doesn't really make sense independently. Finally, I added two more test cases. Let me know if you have any other comments.

Copy link
Contributor

@danielschemmel danielschemmel left a comment

Choose a reason for hiding this comment

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

I only went over the code, but did not try to semantically review the PR.

While some of the comments are stylistic choices, I also found a few instances of objects being copied as the loop variables of range-based for loops.

Comment on lines +4475 to +4472
auto found = seedMap.find(&state);
if (found != seedMap.end()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
auto found = seedMap.find(&state);
if (found != seedMap.end()) {
if (auto found = seedMap.find(&state); found != seedMap.end()) {

Comment on lines +91 to +90
auto a = assignment.bindings.find(array);
if (a != assignment.bindings.end()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
auto a = assignment.bindings.find(array);
if (a != assignment.bindings.end()) {
if (auto a = assignment.bindings.find(array); a != assignment.bindings.end()) {

@ccadar ccadar force-pushed the seed_concretization branch from f5e6cc2 to dde390b Compare November 22, 2023 22:18
@ccadar ccadar force-pushed the seed_concretization branch from dde390b to 345d4b1 Compare November 22, 2023 22:59
@ccadar ccadar force-pushed the seed_concretization branch from 345d4b1 to 1f9944b Compare November 22, 2023 23:00
@ccadar
Copy link
Contributor Author

ccadar commented Nov 23, 2023

@danielschemmel thanks for the additional suggestions; I have applied most of them.

@MartinNowack can you merge this, unless you have additional concerns?

ref<Expr> value;
if (auto found = seedMap.find(&state); found != seedMap.end())
value = getValueFromSeeds(found->second, e);
/* If no seed evaluation results in a constant, call the solver */
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there are reason for using C-style comments? It makes it harder to comment out blocks (due to nesting) and is not recommended by the LLVM coding standard:

https://llvm.org/docs/CodingStandards.html#comment-formatting

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No particular reason, and I think we can live with both. I guess I could change it, but I'm not convinced it matters. And looking at the code, we seem to use both types of comments.
To comment out code, I recommend #if 0 / #endif which should work with both types of comments.

Copy link
Contributor

Choose a reason for hiding this comment

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

To comment out code, I recommend #if 0 / #endif which should work with both types of comments.

Common IDEs only support the traditional line/block comment via shortcuts but ok.

Copy link
Contributor

@MartinNowack MartinNowack left a comment

Choose a reason for hiding this comment

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

@ccadar Thanks a lot for the changes. I'm mostly happy with it.

The only major issue I found is the newly introduced function getValueFromSeeds.
I would recommend changing it to simplify the code on the call side.

/// first one that results in a constant, if such a seed exist. Otherwise,
/// return the non-constant evaluation of the expression under one of the
/// seeds.
ref<klee::Expr> getValueFromSeeds(std::vector<SeedInfo> &seeds,
Copy link
Contributor

Choose a reason for hiding this comment

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

I would suggest to change the API of this call to use the current state as an argument and return a constant expression.

ref<klee::ConstantExpr> getValueFromSeeds(ExecutionState& state, const ref<Expr> &e);

As it stands now, all of the calls togetValueFromSeeds are guarded by a look-up of the seed vector with a subsequent check if the returned value is a constant expr.
Moving that lookup into the function itself makes that function easier to use.

This would simplify the code around quite a lot.

assert(success && "FIXME: Unhandled solver failure");
(void) success;
ce->toMemory(&args[wordIndex]);
ref<ConstantExpr> cvalue;
Copy link
Contributor

Choose a reason for hiding this comment

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

This would become

ref<ConstantExpr> value = getValueFromSeeds(state, *ai);
if (!value) {
// do solver call
}

@ccadar
Copy link
Contributor Author

ccadar commented Dec 4, 2023

Thanks for the extra feedback, @MartinNowack , I have refactored that function now.

Copy link
Contributor

@MartinNowack MartinNowack left a comment

Choose a reason for hiding this comment

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

@ccadar Thanks a lot for the changes. Let's go for this one.
And also big thanks @hoangmle for the initial PR - highly appreciated.

@MartinNowack MartinNowack merged commit cb5e898 into klee:master Jan 30, 2024
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.

4 participants