def add_breakpoint(self, address, breakpoint):
        assert not self.running

        breakpoint.old_value = debug.vm_read_wrapper(self.task, address, 1)
        if breakpoint.old_value != '\xCC':
            self.breakpoints[address] = breakpoint
            debug.vm_write_wrapper(self.task, address, '\xCC')
    def run(self):
        pc_register_name = self.general_register_prefix + 'ip'
        assert not self.running
        self.threads = debug.task_threads(self.task)
        status = self.run_and_wait()

        while os.WIFSTOPPED(status):
            if os.WSTOPSIG(status) != signal.SIGTRAP:
                # Send all non-trap signals to the child.
                status = self.run_and_wait(signal=os.WSTOPSIG(status))
                continue

            try:
                state = self.general_register_state
            except OSError:
                # This condition occurs when a process performs an exec
                # call across bit-sizes. Everything is still a bit crazy,
                # though and maybe it should just crash until I find a
                # better way to detect "the program just changed".
                self.is64 = debug.is_64_bit(self.pid)
                pc_register_name = self.general_register_prefix + 'ip'
                state = self.general_register_state
            pc = getattr(state, pc_register_name)
            if pc - 1 in self.breakpoints:
                setattr(state, pc_register_name, pc - 1)
                address = pc - 1
                breakpoint = self.breakpoints[address]
                breakpoint.callback(self)

                # step past the breakpoint, then reinsert it:
                debug.thread_set_state(self.threads[0], state)
                old_value = breakpoint.old_value
                debug.vm_write_wrapper(self.task, address, old_value)
                self.run_and_wait(step=True)
                if breakpoint.remove_once_hit():
                    del self.breakpoints[address]
                else:
                    debug.vm_write_wrapper(self.task, address, '\xCC')
            status = self.run_and_wait()