-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* guard waiting for watchmen via events In rare occasions, a race can occure where watchmen callbacks are running while the main-thread already consumes the update-state message. This commit guards those callback by an additional event on which target wait() is waiting for. However, there may still be a small TOCTOU-window on that event, as the waiting is using a timeout (for state-updates which are not generating watchmen callbacks). Hence, in the long run, the full code dealing with state updates could benefit from refactoring. * added smoketest for #54 (thanks @redfast00) * Remove manual keystone-library copy from CI It seems that keystone version 0.9.2 (as in pypi) has fixed the issues regarding the installation path of keystone. * Various fixes found by CI * Add processing_callbacks to dictify-ignore list Event()-Objects cannot be serialized, so it should either be private or part of the ignore list. As the watchman are independently accessing this Event, it's added to the ignore list * Fix assert statement in smoketest to be py2-compliant * Set environment variables for the smoketest
- Loading branch information
Showing
4 changed files
with
109 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import avatar2 | ||
import os | ||
import logging | ||
import sys | ||
import time | ||
import threading | ||
import subprocess | ||
|
||
from nose.tools import * | ||
|
||
|
||
# The TargetLauncher is ripped from the avatar1-example | ||
# It is used to spawn and stop a qemu instance which is independent of avatar2. | ||
class TargetLauncher(object): | ||
def __init__(self, cmd): | ||
self._cmd = cmd | ||
self._process = None | ||
self._thread = threading.Thread(target=self.run) | ||
self._thread.start() | ||
|
||
def stop(self): | ||
if self._process: | ||
print(self._process.kill()) | ||
|
||
def run(self): | ||
print("TargetLauncher is starting process %s" % | ||
" ".join(['"%s"' % x for x in self._cmd])) | ||
self._process = subprocess.Popen(self._cmd) | ||
|
||
|
||
|
||
|
||
|
||
|
||
def test_race(): | ||
|
||
def hook_callback(avatar, *args, **kwargs): | ||
gdb = avatar.targets['gdbtest'] | ||
pc = gdb.read_register("pc") | ||
assert pc is not None, "ILLEGAL STATE %s" % gdb.get_status() | ||
|
||
|
||
|
||
avatar = avatar2.Avatar(arch=avatar2.ARM) | ||
|
||
qemu = TargetLauncher([avatar.arch.get_qemu_executable(), | ||
"-machine", "virt", | ||
"-gdb", "tcp::1234", | ||
"-S", | ||
"-nographic", | ||
"-bios", "./tests/binaries/qemu_arm_test"]) | ||
|
||
gdb = avatar.add_target(avatar2.GDBTarget, | ||
name='gdbtest', | ||
gdb_port=1234, | ||
gdb_verbose_mi=False, | ||
gdb_executable='/usr/bin/gdb-multiarch' | ||
) | ||
|
||
# add breakpoint callback | ||
avatar.watchmen.add('BreakpointHit', when='after', callback=hook_callback, is_async=False) | ||
|
||
|
||
print("Init avatar targets...") | ||
avatar.init_targets() | ||
|
||
gdb.set_breakpoint(0x4) | ||
|
||
gdb.write_register('pc', 0) | ||
# Start running | ||
gdb.cont() | ||
|
||
# wait until we hit a breakpoint, once we hit the breakpoint, continue this python script | ||
print("waiting until we hit a breakpoint") | ||
gdb.wait() | ||
# add two breakpoints | ||
gdb.set_breakpoint(0x8) | ||
gdb.set_breakpoint(0xc) | ||
|
||
gdb.set_breakpoint(0x1000) | ||
|
||
# Continue executing from main | ||
gdb.cont() | ||
while True: | ||
# Wait until we hit a breakpoint | ||
gdb.wait() | ||
if gdb.regs.pc == 0x1000: | ||
break | ||
gdb.cont() | ||
|
||
|
||
qemu.stop() | ||
avatar.shutdown() | ||
|
||
if __name__ == '__main__': | ||
test_race() |