Skip to content
This repository has been archived by the owner on Feb 1, 2020. It is now read-only.

Support read-only hardware watchpoints on x86 #510

Closed
wants to merge 6 commits into from

Conversation

AndrewSB
Copy link
Contributor

No description provided.

});
if (loc == _locations.end()) {
// exception. It isn't possible to hit at an address that isn't enabled
return kErrorInvalidAddress;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

not sure if this is the right error to return

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm fine with a DS2ASSERT(loc != _locations.end());

@AndrewSB AndrewSB changed the title [WIP] Support read-only hardware watchpoints on x86 Support read-only hardware watchpoints on x86 Aug 18, 2017
@fjricci fjricci self-requested a review August 18, 2017 20:22
std::vector<uint64_t> _locations;
struct Location {
Location()
:address(0), value(0){}
Copy link
Contributor

Choose a reason for hiding this comment

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

You'll need to run clang-format on this. You can either:

  1. Install and run clang-format manually (I don't think this works on devservers)
  2. Look at the Travis "STYLE" failures and manually apply
  3. install clang-format and run: TARGET=Style ./Support/Testing/Travis/script.sh (see previous comment about no devservers, this will probably require temporarily changing script.sh to use an unversioned clang-format)

auto loc = std::find_if(_locations.begin(), _locations.end(),
[address](const Location &l){
return l.address == address;
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Please factor out the comparator and pass around as a function pointer.

Copy link
Contributor Author

@AndrewSB AndrewSB Aug 19, 2017

Choose a reason for hiding this comment

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

you mean define a function like

inline bool addressInMap(const HardwareBreakpointManager::Location &location,
                         const u_int64_t address)
                         __attribute__((always_inline)) {
  return location.address == address;
}

and use it everywhere like

std::find_if(_locations.begin(), _locations.end(),
    [address](const Location &location) { return addressInMap(location, address); });

?

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually, I have a different idea. We could just use a std::map for _locations, and remove the DS2ASSERT(_locations.size() == maxWatchpoints()); (since you can't fix the size of a map). we already check _sites.size() >= maxWatchpoints() in HardwareBreakpointManager::add, so there's really no reason to also restrict the size of _locations. If you use <address, value> as <key, value> in a map, you don't need the find_if's anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thats great, I'll do that in a commit in the next hour or so :)

bool HardwareBreakpointManager::checkIfWrittenTo(Address const &address) {
bool implemented = false;
DS2ASSERT(implemented);
return implemented;
Copy link
Contributor

Choose a reason for hiding this comment

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

You can just put a DS2BUG("not implemented") instead

@@ -35,6 +35,12 @@ size_t HardwareBreakpointManager::maxWatchpoints() {
return _process->getMaxWatchpoints();
}

bool HardwareBreakpointManager::checkIfWrittenTo(Address const &address) {
Copy link
Contributor

Choose a reason for hiding this comment

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

wasWritten()

@@ -102,6 +104,44 @@ ErrorCode HardwareBreakpointManager::disableLocation(Site const &site,
return error;
}

// workaround for hardware readonly watchpoints not being implememted in
// hardware ¯\_(ツ)_/¯ https://github.com/facebook/ds2/issues/257
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this really qualifies as a workaround, since the lack of hardware implementation is an intentional feature. You could just say that this is a software implementation of read-only watchpoints or something.

@@ -102,6 +104,44 @@ ErrorCode HardwareBreakpointManager::disableLocation(Site const &site,
return error;
}

// workaround for hardware readonly watchpoints not being implememted in
// hardware ¯\_(ツ)_/¯ https://github.com/facebook/ds2/issues/257
bool HardwareBreakpointManager::hardwareReadonlyWorkaround(
Copy link
Contributor

Choose a reason for hiding this comment

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

You can probably just inline this function.

auto loc = std::find_if(_locations.begin(), _locations.end(),
[address](const Location &l){
return l.address == address;
});
Copy link
Contributor

Choose a reason for hiding this comment

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

see previous comment about factoring this out.

@@ -113,7 +153,7 @@ int HardwareBreakpointManager::getAvailableLocation() {
return l.address == 0;
});
DS2ASSERT(it != _locations.end());

Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: remove accidental whitespace change

@@ -32,6 +32,27 @@ size_t HardwareBreakpointManager::maxWatchpoints() {
return 4; // dr0, dr1, dr2, dr3
}

bool HardwareBreakpointManager::checkIfWrittenTo(Address const &address) {
Copy link
Contributor

Choose a reason for hiding this comment

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

wasWritten()

});
if (loc == _locations.end()) {
// exception. It isn't possible to hit at an address that isn't enabled
return kErrorInvalidAddress;
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm fine with a DS2ASSERT(loc != _locations.end());

@fjricci fjricci requested a review from sas August 18, 2017 20:43
@AndrewSB
Copy link
Contributor Author

@fjricci should I squash all/some of my commits?

@fjricci
Copy link
Contributor

fjricci commented Aug 21, 2017

Stacked commits are good (much easier to review and understand than one big blob), but they should be stacked by functionality and not by time (so a commit like fix style or address comments should be squashed). Each point in the stack should have correct style and be a logical step toward the end result. For example, we don't want a commit to add value to _locations and then another commit to remove it, but it's fine/good to add one level of functionality at a time.

@AndrewSB
Copy link
Contributor Author

sounds good! I'll rebase functionally 😄

@AndrewSB AndrewSB force-pushed the master branch 2 times, most recently from 5d04c9c to 72c604c Compare August 22, 2017 03:18
@fjricci
Copy link
Contributor

fjricci commented Aug 22, 2017

Pro tip: use git rebase --ignore-date on your local branch to make the commits show up in the correct order here after squashing.

@AndrewSB
Copy link
Contributor Author

@fjricci I'm currently failing on Travis for 2 reasons. One is related to STYLE, I'm using clang-format v5 on my machine, would it make sense to update Travis' version of clang format from 4 to 5 as well?

For the second failure, I'll look at it closer once I fix the style issue.

@fjricci
Copy link
Contributor

fjricci commented Aug 23, 2017

We like to keep our llvm tools all on the same version, and the stable version of llvm 5 hasn't been released yet (slated for next month I think). We should wait until then to update our clang-format. Do you have access to clang-format-4?

@AndrewSB
Copy link
Contributor Author

I can build it 😄

@fjricci
Copy link
Contributor

fjricci commented Aug 23, 2017

Yeah, I mean, that's what I do. (I even have it as a command in my bashrc, which I find helpful: https://github.com/fjricci/configfiles/blob/1be83f5e813612d382c3c47d734d68efcc3c5d58/bash/bashrc#L28-L37) If you're going to be doing more toolchain work, you'll end up needing llvm builds anyway.

Copy link
Contributor

@sas sas left a comment

Choose a reason for hiding this comment

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

Couple of general comments on this PR before I do a real review:

  • Please try to respect the commit message format of git as much as possible: https://chris.beams.io/posts/git-commit/#seven-rules
  • Please make sure that each commit you submit is atomic and can be merged as-is when we're done with the review. For instance, the commit titled "address @fjricci's review comments" should be split squashed with previous commits in the branch where applicable.

@AndrewSB
Copy link
Contributor Author

@sas I'll try to clean up my commits & their messages today

@AndrewSB AndrewSB force-pushed the master branch 4 times, most recently from cf4001a to 7bf2e61 Compare August 29, 2017 23:21
@fjricci
Copy link
Contributor

fjricci commented Sep 18, 2017

What's the status of this?

@sas
Copy link
Contributor

sas commented Sep 28, 2017

Bump.

@AndrewSB
Copy link
Contributor Author

AndrewSB commented Oct 3, 2017

This flew under my radar. Checking this out now!

TODO

@fjricci
Copy link
Contributor

fjricci commented Oct 3, 2017

😮 TIL about TODO lists on github 😮

AndrewSB and others added 6 commits May 21, 2018 15:19
For the software implementation of readonly hardware breakpoints, we
need to keep an up-to-date map of the values at memory addresses. That
way when our read|write breakpoint is triggered, we can check to see if
the value at that memory address has changed before deciding whether or
not to halt at that watchpoint

The downside with this approach is if one re-writes the existing value
at one of these hardware readonly watchpoints, this implementation will
halt there, thinking the value was read from (since the address was
halted by our read|write breakpoint and the value is unchanged), instead
of correctly ignoring that halt as a write.
So one can still run the travis script targeting STYlE even without
having "clang-format-4.0" in one's PATH
Summary:

Test Plan:

Reviewers:

Subscribers:

Tasks:

Tags:

Blame Revision:
@lanza
Copy link
Contributor

lanza commented Jun 27, 2018

no say bone

@lanza lanza closed this Jun 27, 2018
@AndrewSB
Copy link
Contributor Author

😱😥

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants