# Buggy code
def handle_compare(self, args):
    if len(args) < 2:
        print("Error: missing argument")
        return 1
    addr = self.convert_value(args[0])
    if len(args) < 3:
        filename = args[1]
        length = None
    else:
        filename = args[2]
        length = self.convert_value(args[1])

    region = self.session.target.memory_map.get_region_for_address(addr)
    flash_init_required = (
        region is not None
        and region.is_flash
        and not region.is_powered_on_boot
        and region.flash is not None
    )
    if flash_init_required:
        region.flash.init(region.flash.Operation.VERIFY)

    with open(filename, "rb") as f:
        file_data = f.read(length)

    if length is None:
        length = len(file_data)
    elif len(file_data) < length:
        print(
            "File is %d bytes long; reducing comparison length to match."
            % len(file_data)
        )
        length = len(file_data)

    # Divide into 32 kB chunks.
    CHUNK_SIZE = 32 * 1024
    chunk_count = (length + CHUNK_SIZE - 1) // CHUNK_SIZE

    end_addr = addr + length
    offset = 0
    mismatch = False

    for chunk in range(chunk_count):
        # Get this chunk's size.
        chunk_size = min(end_addr - addr, CHUNK_SIZE)
        print("Comparing %d bytes @ 0x%08x" % (chunk_size, addr))

        data = bytearray(
            self.target.aps[self.selected_ap].read_memory_block8(addr, chunk_size)
        )

        for i in range(chunk_size):
            if data[i] != file_data[offset + i]:
                mismatch = True
                print(
                    "Mismatched byte at 0x%08x (offset 0x%x): 0x%02x (memory) != 0x%02x (file)"
                    % (addr + i, offset + i, data[i], file_data[offset + i])
                )
                break

        if mismatch:
            break

        offset += chunk_size
        addr += chunk_size

    if not mismatch:
        print("All %d bytes match." % length)

    if flash_init_required:
        region.flash.cleanup()


# Traceback (AttributeError)
$ pyocd gdbserver --trust-crc --uid 0231000026294e450024000e58a900543ee1000097969900 --port 7100
0000675:WARNING:common:STLink and CMSIS-DAPv2 probes are not supported because no libusb library was found.
0001093:INFO:board:Target type is k22f
0001108:INFO:coresight_target:Performing connect pre-reset
0001342:INFO:dap:DP IDR = 0x2ba01477 (v1 rev2)
0001367:INFO:ap:AP#0 IDR = 0x24770011 (AHB-AP var1 rev2)
0001386:INFO:ap:AP#1 IDR = 0x001c0000 (proprietary)
0003197:WARNING:target_kinetis:K22F in secure state: will try to unlock via mass erase
0003426:WARNING:target_kinetis:K22F secure state: unlocked successfully
0003440:INFO:rom_table:AP#0 Class 0x1 ROM table #0 @ 0xe00ff000 (designer=43b part=4c4)
0003451:INFO:rom_table:[0]<e000e000:SCS-M4 class=14 designer=43b part=00c>
0003459:INFO:rom_table:[1]<e0001000:DWT class=14 designer=43b part=002>
0003467:INFO:rom_table:[2]<e0002000:FPB class=14 designer=43b part=003>
0003476:INFO:rom_table:[3]<e0000000:ITM class=14 designer=43b part=001>
0003484:INFO:rom_table:[4]<e0040000:TPIU-M4 class=9 designer=43b part=9a1 devtype=11 archid=0000 devid=ca0:0:0>
0003488:INFO:cortex_m:CPU core #0 is Cortex-M4 r0p1
0003501:INFO:dwt:4 hardware watchpoints
0003506:INFO:fpb:6 hardware breakpoints, 4 literal comparators
0003538:INFO:server:Semihost server started on port 4444 (core 0)
0003539:INFO:gdbserver:GDB server started on port 7100 (core 0)
0004069:INFO:gdbserver:One client connected!
0004102:ERROR:gdbserver:Unhandled exception in handle_message: type object 'CortexM' has no attribute 'DFSR_PMU'
Traceback (most recent call last):
File "c:\python27\lib\site-packages\pyocd\gdbserver\gdbserver.py", line 381, in handle_message
reply = handler()
File "c:\python27\lib\site-packages\pyocd\gdbserver\gdbserver.py", line 516, in stop_reason_query
return self.create_rsp_packet(self.get_t_response())
File "c:\python27\lib\site-packages\pyocd\gdbserver\gdbserver.py", line 1116, in get_t_response
response = self.target_facade.get_t_response(forceSignal)
File "c:\python27\lib\site-packages\pyocd\gdbserver\context_facade.py", line 138, in get_t_response
response = six.b('T' + conversion.byte_to_hex2(self.get_signal_value()))
File "c:\python27\lib\site-packages\pyocd\gdbserver\context_facade.py", line 152, in get_signal_value
if self._context.core.is_vector_catch():
File "c:\python27\lib\site-packages\pyocd\coresight\cortex_m.py", line 1335, in is_vector_catch
return self.get_halt_reason() == Target.HaltReason.VECTOR_CATCH
File "c:\python27\lib\site-packages\pyocd\coresight\cortex_m.py", line 1349, in get_halt_reason
elif dfsr &amp; CortexM.DFSR_PMU:
AttributeError: type object 'CortexM' has no attribute 'DFSR_PMU'
0008320:ERROR:gdbserver:Unhandled exception in handle_message: init error: 536870913
Traceback (most recent call last):
File "c:\python27\lib\site-packages\pyocd\gdbserver\gdbserver.py", line 383, in handle_message
reply = handler(msg[msgStart:])
File "c:\python27\lib\site-packages\pyocd\gdbserver\gdbserver.py", line 602, in v_command
return self.flash_op(data)
File "c:\python27\lib\site-packages\pyocd\gdbserver\gdbserver.py", line 718, in flash_op
self.flash_loader.commit()
File "c:\python27\lib\site-packages\pyocd\flash\loader.py", line 168, in commit
keep_unwritten=self._keep_unwritten)
File "c:\python27\lib\site-packages\pyocd\flash\builder.py", line 417, in program
self._build_sectors_and_pages(keep_unwritten)
File "c:\python27\lib\site-packages\pyocd\flash\builder.py", line 315, in _build_sectors_and_pages
fill_end_of_page_gap()
File "c:\python27\lib\site-packages\pyocd\flash\builder.py", line 259, in fill_end_of_page_gap
self._enable_read_access()
File "c:\python27\lib\site-packages\pyocd\flash\builder.py", line 221, in _enable_read_access
self.flash.init(self.flash.Operation.VERIFY)
File "c:\python27\lib\site-packages\pyocd\flash\flash.py", line 250, in init
raise FlashFailure('init error: %i' % result, result_code=result)
FlashFailure: init error: 536870913
0008342:INFO:gdbserver:Client detached
0008342:INFO:gdbserver:Client disconnected!
0008546:INFO:server:Semihost server stopped

# Fixed code
def handle_compare(self, args):
    if len(args) < 2:
        print("Error: missing argument")
        return 1
    addr = self.convert_value(args[0])
    if len(args) < 3:
        filename = args[1]
        length = None
    else:
        filename = args[2]
        length = self.convert_value(args[1])

    region = self.session.target.memory_map.get_region_for_address(addr)
    flash_init_required = (
        region is not None
        and region.is_flash
        and not region.is_powered_on_boot
        and region.flash is not None
    )
    if flash_init_required:
        try:
            region.flash.init(region.flash.Operation.VERIFY)
        except exceptions.FlashFailure:
            region.flash.init(region.flash.Operation.ERASE)

    with open(filename, "rb") as f:
        file_data = f.read(length)

    if length is None:
        length = len(file_data)
    elif len(file_data) < length:
        print(
            "File is %d bytes long; reducing comparison length to match."
            % len(file_data)
        )
        length = len(file_data)

    # Divide into 32 kB chunks.
    CHUNK_SIZE = 32 * 1024
    chunk_count = (length + CHUNK_SIZE - 1) // CHUNK_SIZE

    end_addr = addr + length
    offset = 0
    mismatch = False

    for chunk in range(chunk_count):
        # Get this chunk's size.
        chunk_size = min(end_addr - addr, CHUNK_SIZE)
        print("Comparing %d bytes @ 0x%08x" % (chunk_size, addr))

        data = bytearray(
            self.target.aps[self.selected_ap].read_memory_block8(addr, chunk_size)
        )

        for i in range(chunk_size):
            if data[i] != file_data[offset + i]:
                mismatch = True
                print(
                    "Mismatched byte at 0x%08x (offset 0x%x): 0x%02x (memory) != 0x%02x (file)"
                    % (addr + i, offset + i, data[i], file_data[offset + i])
                )
                break

        if mismatch:
            break

        offset += chunk_size
        addr += chunk_size

    if not mismatch:
        print("All %d bytes match." % length)

    if flash_init_required:
        region.flash.cleanup()