Beispiel #1
0
bool
AllocatedMemoryCache::DeallocateMemory (lldb::addr_t addr)
{
    Mutex::Locker locker (m_mutex);

    PermissionsToBlockMap::iterator pos, end = m_memory_map.end();
    bool success = false;
    for (pos = m_memory_map.begin(); pos != end; ++pos)
    {
        if (pos->second->Contains (addr))
        {
            success = pos->second->FreeBlock (addr);
            break;
        }
    }
    LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
    if (log)
        log->Printf("AllocatedMemoryCache::DeallocateMemory (addr = 0x%16.16llx) => %i", (uint64_t)addr, success);
    return success;
}
Beispiel #2
0
void
POSIXThread::Notify(const ProcessMessage &message)
{
    LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
    if (log)
        log->Printf ("POSIXThread::%s () message kind = '%s'", __FUNCTION__, message.PrintKind());

    switch (message.GetKind())
    {
    default:
        assert(false && "Unexpected message kind!");
        break;

    case ProcessMessage::eLimboMessage:
        LimboNotify(message);
        break;
        
    case ProcessMessage::eSignalMessage:
        SignalNotify(message);
        break;

    case ProcessMessage::eSignalDeliveredMessage:
        SignalDeliveredNotify(message);
        break;

    case ProcessMessage::eTraceMessage:
        TraceNotify(message);
        break;

    case ProcessMessage::eBreakpointMessage:
        BreakNotify(message);
        break;

    case ProcessMessage::eCrashMessage:
        CrashNotify(message);
        break;
    }
}
Beispiel #3
0
lldb::RegisterContextSP
POSIXThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame)
{
    lldb::RegisterContextSP reg_ctx_sp;
    uint32_t concrete_frame_idx = 0;

    LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
    if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
        log->Printf ("POSIXThread::%s ()", __FUNCTION__);

    if (frame)
        concrete_frame_idx = frame->GetConcreteFrameIndex();

    if (concrete_frame_idx == 0)
        reg_ctx_sp = GetRegisterContext();
    else
    {
        assert(GetUnwinder());
        reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame);
    }

    return reg_ctx_sp;
}
Beispiel #4
0
void
ModuleList::LogUUIDAndPaths (LogSP &log_sp, const char *prefix_cstr)
{
    if (log_sp)
    {   
        Mutex::Locker locker(m_modules_mutex);
        char uuid_cstr[256];
        collection::const_iterator pos, begin = m_modules.begin(), end = m_modules.end();
        for (pos = begin; pos != end; ++pos)
        {
            Module *module = pos->get();
            module->GetUUID().GetAsCString (uuid_cstr, sizeof(uuid_cstr));
            const FileSpec &module_file_spec = module->GetFileSpec();
            log_sp->Printf ("%s[%u] %s (%s) \"%s/%s\"", 
                            prefix_cstr ? prefix_cstr : "",
                            (uint32_t)std::distance (begin, pos),
                            uuid_cstr,
                            module->GetArchitecture().GetArchitectureName(),
                            module_file_spec.GetDirectory().GetCString(),
                            module_file_spec.GetFilename().GetCString());
        }
    }
}
Beispiel #5
0
bool
DWARFDebugPubnames::GeneratePubnames(SymbolFileDWARF* dwarf2Data)
{
    Timer scoped_timer (__PRETTY_FUNCTION__,
                        "DWARFDebugPubnames::GeneratePubnames (data = %p)",
                        dwarf2Data);

    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES));
    if (log)
        log->Printf("DWARFDebugPubnames::GeneratePubnames (data = %p)", dwarf2Data);

    m_sets.clear();
    DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo();
    if (debug_info)
    {

        const DataExtractor* debug_str = &dwarf2Data->get_debug_str_data();

        uint32_t cu_idx = 0;
        const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
        for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
        {

            DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);

            const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (cu->GetAddressByteSize());

            bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1;

            DWARFDIECollection dies;
            const size_t die_count = cu->AppendDIEsWithTag (DW_TAG_subprogram, dies) +
                                     cu->AppendDIEsWithTag (DW_TAG_variable, dies);

            dw_offset_t cu_offset = cu->GetOffset();
            DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset, cu->GetNextCompileUnitOffset() - cu_offset);

            size_t die_idx;
            for (die_idx = 0; die_idx < die_count; ++die_idx)
            {
                const DWARFDebugInfoEntry *die = dies.GetDIEPtrAtIndex(die_idx);
                DWARFDebugInfoEntry::Attributes attributes;
                const char *name = NULL;
                const char *mangled = NULL;
                bool add_die = false;
                bool is_variable = false;
                const size_t num_attributes = die->GetAttributes(dwarf2Data, cu, fixed_form_sizes, attributes);
                if (num_attributes > 0)
                {
                    uint32_t i;

                    dw_tag_t tag = die->Tag();
                    
                    is_variable = tag == DW_TAG_variable;

                    for (i=0; i<num_attributes; ++i)
                    {
                        dw_attr_t attr = attributes.AttributeAtIndex(i);
                        DWARFFormValue form_value;
                        switch (attr)
                        {
                        case DW_AT_name:
                            if (attributes.ExtractFormValueAtIndex(dwarf2Data, i, form_value))
                                name = form_value.AsCString(debug_str);
                            break;

                        case DW_AT_MIPS_linkage_name:
                            if (attributes.ExtractFormValueAtIndex(dwarf2Data, i, form_value))
                                mangled = form_value.AsCString(debug_str);
                            break;

                        case DW_AT_low_pc:
                        case DW_AT_ranges:
                        case DW_AT_entry_pc:
                            if (tag == DW_TAG_subprogram)
                                add_die = true;
                            break;

                        case DW_AT_location:
                            if (tag == DW_TAG_variable)
                            {
                                const DWARFDebugInfoEntry* parent_die = die->GetParent();
                                while ( parent_die != NULL )
                                {
                                    switch (parent_die->Tag())
                                    {
                                    case DW_TAG_subprogram:
                                    case DW_TAG_lexical_block:
                                    case DW_TAG_inlined_subroutine:
                                        // Even if this is a function level static, we don't add it. We could theoretically
                                        // add these if we wanted to by introspecting into the DW_AT_location and seeing
                                        // if the location describes a hard coded address, but we don't want the performance
                                        // penalty of that right now.
                                        add_die = false;
//                                      if (attributes.ExtractFormValueAtIndex(dwarf2Data, i, form_value))
//                                      {
//                                          // If we have valid block data, then we have location expression bytes
//                                          // that are fixed (not a location list).
//                                          const uint8_t *block_data = form_value.BlockData();
//                                          if (block_data)
//                                          {
//                                              uint32_t block_length = form_value.Unsigned();
//                                              if (block_length == 1 + attributes.CompileUnitAtIndex(i)->GetAddressByteSize())
//                                              {
//                                                  if (block_data[0] == DW_OP_addr)
//                                                      add_die = true;
//                                              }
//                                          }
//                                      }
                                        parent_die = NULL;  // Terminate the while loop.
                                        break;

                                    case DW_TAG_compile_unit:
                                        add_die = true;
                                        parent_die = NULL;  // Terminate the while loop.
                                        break;

                                    default:
                                        parent_die = parent_die->GetParent();   // Keep going in the while loop.
                                        break;
                                    }
                                }
                            }
                            break;
                        }
                    }
                }

                if (add_die && (name || mangled))
                {
                    pubnames_set.AddDescriptor(die->GetOffset() - cu_offset, mangled ? mangled : name);
                }
            }

            if (pubnames_set.NumDescriptors() > 0)
            {
                m_sets.push_back(pubnames_set);
            }
            
            // Keep memory down by clearing DIEs if this generate function
            // caused them to be parsed
            if (clear_dies)
                cu->ClearDIEs (true);
        }
    }
    if (m_sets.empty())
        return false;
    if (log)
        Dump (log.get());
    return true;
}
Beispiel #6
0
void
Breakpoint::ModulesChanged (ModuleList &module_list, bool load, bool delete_locations)
{
    Mutex::Locker modules_mutex(module_list.GetMutex());
    if (load)
    {
        // The logic for handling new modules is:
        // 1) If the filter rejects this module, then skip it.
        // 2) Run through the current location list and if there are any locations
        //    for that module, we mark the module as "seen" and we don't try to re-resolve
        //    breakpoint locations for that module.
        //    However, we do add breakpoint sites to these locations if needed.
        // 3) If we don't see this module in our breakpoint location list, call ResolveInModules.

        ModuleList new_modules;  // We'll stuff the "unseen" modules in this list, and then resolve
                                 // them after the locations pass.  Have to do it this way because
                                 // resolving breakpoints will add new locations potentially.

        const size_t num_locs = m_locations.GetSize();
        size_t num_modules = module_list.GetSize();
        for (size_t i = 0; i < num_modules; i++)
        {
            bool seen = false;
            ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i));
            if (!m_filter_sp->ModulePasses (module_sp))
                continue;

            for (size_t loc_idx = 0; loc_idx < num_locs; loc_idx++)
            {
                BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx);
                if (!break_loc->IsEnabled())
                    continue;
                SectionSP section_sp (break_loc->GetAddress().GetSection());
                if (!section_sp || section_sp->GetModule() == module_sp)
                {
                    if (!seen)
                        seen = true;

                    if (!break_loc->ResolveBreakpointSite())
                    {
                        LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
                        if (log)
                            log->Printf ("Warning: could not set breakpoint site for breakpoint location %d of breakpoint %d.\n",
                                         break_loc->GetID(), GetID());
                    }
                }
            }

            if (!seen)
                new_modules.AppendIfNeeded (module_sp);

        }
        
        if (new_modules.GetSize() > 0)
        {
            // If this is not an internal breakpoint, set up to record the new locations, then dispatch
            // an event with the new locations.
            if (!IsInternal())
            {
                BreakpointEventData *new_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsAdded, 
                                                                                    shared_from_this());
                
                m_locations.StartRecordingNewLocations(new_locations_event->GetBreakpointLocationCollection());
                
                ResolveBreakpointInModules(new_modules);

                m_locations.StopRecordingNewLocations();
                if (new_locations_event->GetBreakpointLocationCollection().GetSize() != 0)
                {
                    SendBreakpointChangedEvent (new_locations_event);
                }
                else
                    delete new_locations_event;
            }
            else
                ResolveBreakpointInModules(new_modules);
            
        }
    }
    else
    {
        // Go through the currently set locations and if any have breakpoints in
        // the module list, then remove their breakpoint sites, and their locations if asked to.

        BreakpointEventData *removed_locations_event;
        if (!IsInternal())
            removed_locations_event = new BreakpointEventData (eBreakpointEventTypeLocationsRemoved, 
                                                               shared_from_this());
        else
            removed_locations_event = NULL;
        
        size_t num_modules = module_list.GetSize();
        for (size_t i = 0; i < num_modules; i++)
        {
            ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (i));
            if (m_filter_sp->ModulePasses (module_sp))
            {
                size_t loc_idx = 0;
                size_t num_locations = m_locations.GetSize();
                BreakpointLocationCollection locations_to_remove;
                for (loc_idx = 0; loc_idx < num_locations; loc_idx++)
                {
                    BreakpointLocationSP break_loc_sp (m_locations.GetByIndex(loc_idx));
                    SectionSP section_sp (break_loc_sp->GetAddress().GetSection());
                    if (section_sp && section_sp->GetModule() == module_sp)
                    {
                        // Remove this breakpoint since the shared library is 
                        // unloaded, but keep the breakpoint location around
                        // so we always get complete hit count and breakpoint
                        // lifetime info
                        break_loc_sp->ClearBreakpointSite();
                        if (removed_locations_event)
                        {
                            removed_locations_event->GetBreakpointLocationCollection().Add(break_loc_sp);
                        }
                        if (delete_locations)
                            locations_to_remove.Add (break_loc_sp);
                            
                    }
                }
                
                if (delete_locations)
                {
                    size_t num_locations_to_remove = locations_to_remove.GetSize();
                    for (loc_idx = 0; loc_idx < num_locations_to_remove; loc_idx++)
                        m_locations.RemoveLocation  (locations_to_remove.GetByIndex(loc_idx));
                }
            }
        }
        SendBreakpointChangedEvent (removed_locations_event);
    }
}
Beispiel #7
0
lldb::addr_t
AllocatedBlock::ReserveBlock (uint32_t size)
{
    addr_t addr = LLDB_INVALID_ADDRESS;
    if (size <= m_byte_size)
    {
        const uint32_t needed_chunks = CalculateChunksNeededForSize (size);
        LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));

        if (m_offset_to_chunk_size.empty())
        {
            m_offset_to_chunk_size[0] = needed_chunks;
            if (log)
                log->Printf ("[1] AllocatedBlock::ReserveBlock (size = %u (0x%x)) => offset = 0x%x, %u %u bit chunks", size, size, 0, needed_chunks, m_chunk_size);
            addr = m_addr;
        }
        else
        {
            uint32_t last_offset = 0;
            OffsetToChunkSize::const_iterator pos = m_offset_to_chunk_size.begin();
            OffsetToChunkSize::const_iterator end = m_offset_to_chunk_size.end();
            while (pos != end)
            {
                if (pos->first > last_offset)
                {
                    const uint32_t bytes_available = pos->first - last_offset;
                    const uint32_t num_chunks = CalculateChunksNeededForSize (bytes_available);
                    if (num_chunks >= needed_chunks)
                    {
                        m_offset_to_chunk_size[last_offset] = needed_chunks;
                        if (log)
                            log->Printf ("[2] AllocatedBlock::ReserveBlock (size = %u (0x%x)) => offset = 0x%x, %u %u bit chunks", size, size, last_offset, needed_chunks, m_chunk_size);
                        addr = m_addr + last_offset;
                        break;
                    }
                }
                
                last_offset = pos->first + pos->second * m_chunk_size;

                if (++pos == end)
                {
                    // Last entry...
                    const uint32_t chunks_left = CalculateChunksNeededForSize (m_byte_size - last_offset);
                    if (chunks_left >= needed_chunks)
                    {
                        m_offset_to_chunk_size[last_offset] = needed_chunks;
                        if (log)
                            log->Printf ("[3] AllocatedBlock::ReserveBlock (size = %u (0x%x)) => offset = 0x%x, %u %u bit chunks", size, size, last_offset, needed_chunks, m_chunk_size);
                        addr = m_addr + last_offset;
                        break;
                    }
                }
            }
        }
//        const uint32_t total_chunks = m_allocated.size ();
//        uint32_t unallocated_idx = 0;
//        uint32_t allocated_idx = m_allocated.find_first();
//        uint32_t first_chunk_idx = UINT32_MAX;
//        uint32_t num_chunks;
//        while (1)
//        {
//            if (allocated_idx == UINT32_MAX)
//            {
//                // No more bits are set starting from unallocated_idx, so we
//                // either have enough chunks for the request, or we don't.
//                // Eiter way we break out of the while loop...
//                num_chunks = total_chunks - unallocated_idx;
//                if (needed_chunks <= num_chunks)
//                    first_chunk_idx = unallocated_idx;
//                break;                
//            }
//            else if (allocated_idx > unallocated_idx)
//            {
//                // We have some allocated chunks, check if there are enough
//                // free chunks to satisfy the request?
//                num_chunks = allocated_idx - unallocated_idx;
//                if (needed_chunks <= num_chunks)
//                {
//                    // Yep, we have enough!
//                    first_chunk_idx = unallocated_idx;
//                    break;
//                }
//            }
//            
//            while (unallocated_idx < total_chunks)
//            {
//                if (m_allocated[unallocated_idx])
//                    ++unallocated_idx;
//                else
//                    break;
//            }
//            
//            if (unallocated_idx >= total_chunks)
//                break;
//            
//            allocated_idx = m_allocated.find_next(unallocated_idx);
//        }
//        
//        if (first_chunk_idx != UINT32_MAX)
//        {
//            const uint32_t end_bit_idx = unallocated_idx + needed_chunks;
//            for (uint32_t idx = first_chunk_idx; idx < end_bit_idx; ++idx)
//                m_allocated.set(idx);
//            return m_addr + m_chunk_size * first_chunk_idx;
//        }
    }
    LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
    if (log)
        log->Printf ("AllocatedBlock::ReserveBlock (size = %u (0x%x)) => 0x%16.16llx", size, size, (uint64_t)addr);
    return addr;
}
Beispiel #8
0
void
Breakpoint::ModulesChanged (ModuleList &module_list, bool load)
{
    if (load)
    {
        // The logic for handling new modules is:
        // 1) If the filter rejects this module, then skip it.
        // 2) Run through the current location list and if there are any locations
        //    for that module, we mark the module as "seen" and we don't try to re-resolve
        //    breakpoint locations for that module.
        //    However, we do add breakpoint sites to these locations if needed.
        // 3) If we don't see this module in our breakpoint location list, call ResolveInModules.

        ModuleList new_modules;  // We'll stuff the "unseen" modules in this list, and then resolve
                                 // them after the locations pass.  Have to do it this way because
                                 // resolving breakpoints will add new locations potentially.

        const size_t num_locs = m_locations.GetSize();

        for (size_t i = 0; i < module_list.GetSize(); i++)
        {
            bool seen = false;
            ModuleSP module_sp (module_list.GetModuleAtIndex (i));
            if (!m_filter_sp->ModulePasses (module_sp))
                continue;

            for (size_t loc_idx = 0; loc_idx < num_locs; loc_idx++)
            {
                BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx);
                if (!break_loc->IsEnabled())
                    continue;
                const Section *section = break_loc->GetAddress().GetSection();
                if (section == NULL || section->GetModule() == module_sp.get())
                {
                    if (!seen)
                        seen = true;

                    if (!break_loc->ResolveBreakpointSite())
                    {
                        LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
                        if (log)
                            log->Printf ("Warning: could not set breakpoint site for breakpoint location %d of breakpoint %d.\n",
                                         break_loc->GetID(), GetID());
                    }
                }
            }

            if (!seen)
                new_modules.AppendIfNeeded (module_sp);

        }
        if (new_modules.GetSize() > 0)
        {
            ResolveBreakpointInModules(new_modules);
        }
    }
    else
    {
        // Go through the currently set locations and if any have breakpoints in
        // the module list, then remove their breakpoint sites.
        // FIXME: Think about this...  Maybe it's better to delete the locations?
        // Are we sure that on load-unload-reload the module pointer will remain
        // the same?  Or do we need to do an equality on modules that is an
        // "equivalence"???

        for (size_t i = 0; i < module_list.GetSize(); i++)
        {
            ModuleSP module_sp (module_list.GetModuleAtIndex (i));
            if (m_filter_sp->ModulePasses (module_sp))
            {
                const size_t num_locs = m_locations.GetSize();
                for (size_t loc_idx = 0; loc_idx < num_locs; ++loc_idx)
                {
                    BreakpointLocationSP break_loc = m_locations.GetByIndex(loc_idx);
                    const Section *section = break_loc->GetAddress().GetSection();
                    if (section && section->GetModule() == module_sp.get())
                    {
                        // Remove this breakpoint since the shared library is 
                        // unloaded, but keep the breakpoint location around
                        // so we always get complete hit count and breakpoint
                        // lifetime info
                        break_loc->ClearBreakpointSite();
                    }
                }
            }
        }
    }
}
Beispiel #9
0
bool
CommunicationKDP::CheckForPacket (const uint8_t *src, size_t src_len, DataExtractor &packet)
{
    // Put the packet data into the buffer in a thread safe fashion
    Mutex::Locker locker(m_bytes_mutex);

    LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));

    if (src && src_len > 0)
    {
        if (log && log->GetVerbose())
        {
            PacketStreamType log_strm;
            DataExtractor::DumpHexBytes (&log_strm, src, src_len, UINT32_MAX, LLDB_INVALID_ADDRESS);
            log->Printf ("CommunicationKDP::%s adding %u bytes: %s",
                         __FUNCTION__,
                         (uint32_t)src_len,
                         log_strm.GetData());
        }
        m_bytes.append ((const char *)src, src_len);
    }

    // Make sure we at least have enough bytes for a packet header
    const size_t bytes_available = m_bytes.size();
    if (bytes_available >= 8)
    {
        packet.SetData (&m_bytes[0], bytes_available, m_byte_order);
        uint32_t offset = 0;
        uint8_t reply_command = packet.GetU8(&offset);
        switch (reply_command)
        {
        case ePacketTypeRequest | KDP_EXCEPTION:
        case ePacketTypeRequest | KDP_TERMINATION:
            // We got an exception request, so be sure to send an ACK
        {
            PacketStreamType request_ack_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
            // Set the reply but and make the ACK packet
            request_ack_packet.PutHex8 (reply_command | ePacketTypeReply);
            request_ack_packet.PutHex8 (packet.GetU8(&offset));
            request_ack_packet.PutHex16 (packet.GetU16(&offset));
            request_ack_packet.PutHex32 (packet.GetU32(&offset));
            m_is_running.SetValue(false, eBroadcastAlways);
            // Ack to the exception or termination
            SendRequestPacketNoLock (request_ack_packet);
        }
        // Fall through to case below to get packet contents
        case ePacketTypeReply | KDP_CONNECT:
        case ePacketTypeReply | KDP_DISCONNECT:
        case ePacketTypeReply | KDP_HOSTINFO:
        case ePacketTypeReply | KDP_VERSION:
        case ePacketTypeReply | KDP_MAXBYTES:
        case ePacketTypeReply | KDP_READMEM:
        case ePacketTypeReply | KDP_WRITEMEM:
        case ePacketTypeReply | KDP_READREGS:
        case ePacketTypeReply | KDP_WRITEREGS:
        case ePacketTypeReply | KDP_LOAD:
        case ePacketTypeReply | KDP_IMAGEPATH:
        case ePacketTypeReply | KDP_SUSPEND:
        case ePacketTypeReply | KDP_RESUMECPUS:
        case ePacketTypeReply | KDP_BREAKPOINT_SET:
        case ePacketTypeReply | KDP_BREAKPOINT_REMOVE:
        case ePacketTypeReply | KDP_REGIONS:
        case ePacketTypeReply | KDP_REATTACH:
        case ePacketTypeReply | KDP_HOSTREBOOT:
        case ePacketTypeReply | KDP_READMEM64:
        case ePacketTypeReply | KDP_WRITEMEM64:
        case ePacketTypeReply | KDP_BREAKPOINT_SET64:
        case ePacketTypeReply | KDP_BREAKPOINT_REMOVE64:
        case ePacketTypeReply | KDP_KERNELVERSION:
        {
            offset = 2;
            const uint16_t length = packet.GetU16 (&offset);
            if (length <= bytes_available)
            {
                // We have an entire packet ready, we need to copy the data
                // bytes into a buffer that will be owned by the packet and
                // erase the bytes from our communcation buffer "m_bytes"
                packet.SetData (DataBufferSP (new DataBufferHeap (&m_bytes[0], length)));
                m_bytes.erase (0, length);

                if (log)
                {
                    PacketStreamType log_strm;
                    DumpPacket (log_strm, packet);

                    log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
                }
                return true;
            }
        }
        break;

        default:
            // Unrecognized reply command byte, erase this byte and try to get back on track
            if (log)
                log->Printf ("CommunicationKDP::%s: tossing junk byte: 0x%2.2x",
                             __FUNCTION__,
                             (uint8_t)m_bytes[0]);
            m_bytes.erase(0, 1);
            break;
        }
    }
    packet.Clear();
    return false;
}