Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Opportunistic state merging for Manticore #1351

Closed
wants to merge 16 commits into from

Conversation

@vaibhavbsharma
Copy link

@vaibhavbsharma vaibhavbsharma commented Jan 15, 2019

This PR is a work-in-progress as of now. The central idea is to merge states that happen to be at the same program location. This requires us to implement a is_merge_possible predicate that compares two states and a merge method that creates a merged State from two mergeable State objects.

I am still working on finishing the implementation of is_merge_possible by adding checks for the array of byte values in various Map objects that describe the state's memory. The next step is to implement the merge method by merging just the CPU and copy everything else from one of the two states.

So far, the changes affect the main loop in Executor. But, I am waiting for 3 APIs to be implemented that will allow me to move my code out of Executor and into a separate state-merging plugin. The design of the APIs is as follows:

  1. load_state loads a state given a state_id without deleting it.
  2. delete_state deletes a state given a state_id
  3. replace_state replaces the state with a value state_id in its workspace with another state given in its argument
    All three APIs return an error if the state with state_id does not exist in Executor's workspace. @feliam is currently working on implementing these APIs.

With these APIs implemented, I plan to create a state-merging plugin that adds a callback for will_load_state. The callback would merge the state that is about to be executed with other states if any happen to be at the same program location. To figure out which states are at the same program location without loading all the states into memory, the plugin would add a handler for did_enqueue_state and maintain a global dictionary that maps state_id values to that state's program counter.


This change is Reviewable

This commit introduces a new attribute -- cpu_stateid_dict -- in Executor that keeps track of the Program Counter register of each state and maps PC values to a list of state ids. States that are at the same PC are checked for mergeability.

** Warning: The is_merge_possible and merge methods in state_merging.py have not been implemented. However, this commit should not affect current exploration of Manticore
…example to test state merging

1. Building the constraint that can be used to check if the solver thinks that the buffers in input and output sockets are equal when comparing states for merging
2. Puttng the state merging example in that runs into 3 opportunities for state merging when the Random policy is seeded with the seed = 2 (not sure how to set it up from the Python script)
… it to 2 in Random policy object
**caution: I am in the process of finishing the memory maps comparison
@yan

This comment has been minimized.

Copy link
Contributor

@yan yan commented on manticore/core/state_merging.py in 317042d Jan 15, 2019

If you're okay including name in comparisons, this can just be if m1 != m2:

This comment has been minimized.

Copy link
Author

@vaibhavbsharma vaibhavbsharma replied Jan 15, 2019

Yes, I didn't realize most of this check is already implemented in Map.__eq__. I've changed my implementation to just use m1 != m2.

@yan

This comment has been minimized.

Copy link
Contributor

@yan yan commented on manticore/core/state_merging.py in 317042d Jan 15, 2019

Map.__lt__ uses start to sort by default (and then end, perms and name, in that order)

This comment has been minimized.

Copy link
Author

@vaibhavbsharma vaibhavbsharma replied Jan 15, 2019

I didn't realize that. Thanks for letting me know. I've dropped the key parameter from these sorted calls.

@disconnect3d

This comment has been minimized.

Copy link
Member

@disconnect3d disconnect3d commented on manticore/core/state_merging.py in 317042d Jan 15, 2019

Or just for i, j in zip(buffer1, buffer2):

This comment has been minimized.

Copy link
Contributor

@yan yan replied Jan 15, 2019

This also only checks the first len(buffer1) bytes (or min(len1,len2) bytes in the updated case); is that by design?

This comment has been minimized.

Copy link
Author

@vaibhavbsharma vaibhavbsharma replied Jan 15, 2019

Thanks for catching this. I was planning on adding the check for the two buffer lengths to be equal but I forgot about it when looking at other parts of the State. I've changed the implementation to check the lengths for equality and using zip.

@CLAassistant
Copy link

@CLAassistant CLAassistant commented Jan 15, 2019

CLA assistant check
All committers have signed the CLA.

vaibhavbsharma and others added 9 commits Jan 15, 2019
…hing comparison of memory in the two states
…y implementing the `merge` method that merges the CPU canonical registers between states
The merged constraint is simply a logical OR of the constraints in the states being merged.
* load/save/replace as needed by state merging

* WIP Move merging to a plugin
…ample is now using the Merge plugin

1. Using Merge plugin and the newly added APIs in Executor to load, delete, replace states
2. Completing the memory objects comparison by comparing both memory object's symbolic writes instead of only comparing the first memory object against the second
3. Adding documentation for all of the newly introduced methods in state_merging.py
…basic_statemerging.py to work + moving Merger Plugin to plugin.py

These changes now allow state merging to correctly merge two states in basic_statemerging.c
…my hack to avoid importing SMemory into state_merging.py
… example I've been using to test state merging
@ehennenfent ehennenfent added this to In progress in Manticore Releases Jan 22, 2019
@ehennenfent ehennenfent moved this from In progress to Review Needed in Manticore Releases Jan 22, 2019
print("loaded state_id = " + str(state_id) + " at cpu = " + hex(state.cpu.PC))

m.subscribe('will_load_state', will_load_state_callback)
m.subscribe('did_load_state', did_load_state_callback)

This comment has been minimized.

@disconnect3d

disconnect3d Jan 25, 2019
Member

Loud thinking: do we want users to directly subscribe for events? @feliam


@sync
def _replace_state(self, state_id, state):
# self._workspace.rm_state(state_id)

This comment has been minimized.

@disconnect3d

disconnect3d Jan 25, 2019
Member

Delete comment?

@ehennenfent ehennenfent added this to the Validate Existing issues milestone Feb 5, 2019
@ehennenfent ehennenfent removed this from the Validate Existing issues milestone Feb 26, 2019
@ehennenfent ehennenfent moved this from Review Needed to old Todo - prioritized backlog in Manticore Releases Jun 6, 2019
@ehennenfent ehennenfent moved this from old Todo - prioritized backlog to Todo in Manticore Releases Jun 24, 2019
@ehennenfent
Copy link
Contributor

@ehennenfent ehennenfent commented Jul 22, 2019

Closing this as it's now being tracked in #1482

Manticore Releases automation moved this from Todo to Included in 0.3.1! Jul 22, 2019
@ehennenfent ehennenfent deleted the dev-state-merging branch Jan 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Manticore Releases
  
Included in 0.3.1!
Linked issues

Successfully merging this pull request may close these issues.

None yet

6 participants
You can’t perform that action at this time.