From 644cfba9b20340ed15af5a112f9cadcf451c0b57 Mon Sep 17 00:00:00 2001 From: dreamsourcelabTAI Date: Thu, 20 Apr 2023 18:45:29 +0800 Subject: [PATCH] fix: Decoder readed a bad data buffer --- DSView/pv/data/decoderstack.cpp | 13 +++--- DSView/pv/data/logicsnapshot.cpp | 72 +++++++++++++++++++++++++++++--- DSView/pv/data/logicsnapshot.h | 5 +++ DSView/pv/dock/protocoldock.cpp | 13 +++--- DSView/pv/sigsession.cpp | 15 +++---- DSView/pv/sigsession.h | 1 - 6 files changed, 93 insertions(+), 26 deletions(-) diff --git a/DSView/pv/data/decoderstack.cpp b/DSView/pv/data/decoderstack.cpp index 9ea67ee1..b779fd4f 100644 --- a/DSView/pv/data/decoderstack.cpp +++ b/DSView/pv/data/decoderstack.cpp @@ -529,20 +529,20 @@ void DecoderStack::decode_data(const uint64_t decode_start, const uint64_t decod if (!bCheckEnd){ bCheckEnd = true; - if (end_index >= _snapshot->get_ring_sample_count()){ - end_index = _snapshot->get_ring_sample_count() - 1; + if (end_index >= _snapshot->get_mipmap_sample_count()){ + end_index = _snapshot->get_mipmap_sample_count() - 1; dsv_info("Reset the decode end sample, new:%llu, old:%llu", end_index, decode_end); } } } - else if (i >= _snapshot->get_ring_sample_count()) + else if (i >= _snapshot->get_mipmap_sample_count()) { // Wait the data is ready. std::this_thread::sleep_for(std::chrono::milliseconds(100)); continue; } - uint64_t chunk_end = end_index; + uint64_t chunk_end = end_index; for (int j =0 ; j < logic_di->dec_num_channels; j++) { int sig_index = logic_di->dec_channelmap[j]; @@ -552,7 +552,8 @@ void DecoderStack::decode_data(const uint64_t decode_start, const uint64_t decod chunk_const.push_back(0); } else { if (_snapshot->has_data(sig_index)) { - chunk.push_back(_snapshot->get_samples(i, chunk_end, sig_index)); + auto data_ptr = _snapshot->get_decode_samples(i, chunk_end, sig_index); + chunk.push_back(data_ptr); chunk_const.push_back(_snapshot->get_sample(i, sig_index)); } else { _error_message = L_S(STR_PAGE_MSG, S_ID(IDS_MSG_DECODERSTACK_DECODE_DATA_ERROR), @@ -641,7 +642,7 @@ void DecoderStack::execute_decode_stack() assert(session); // Get the intial sample count - _sample_count = _snapshot->get_ring_sample_count(); + _sample_count = _snapshot->get_mipmap_sample_count(); // Create the decoders for(auto dec : _stack) diff --git a/DSView/pv/data/logicsnapshot.cpp b/DSView/pv/data/logicsnapshot.cpp index 1528ed68..caf320ef 100644 --- a/DSView/pv/data/logicsnapshot.cpp +++ b/DSView/pv/data/logicsnapshot.cpp @@ -94,6 +94,7 @@ void LogicSnapshot::init_all() _dest_ptr = NULL; _memory_failed = false; _last_ended = true; + _mipmap_sample_count = 0; } void LogicSnapshot::clear() @@ -165,6 +166,7 @@ void LogicSnapshot::first_payload(const sr_datafeed_logic &logic, uint64_t total _sample_count = 0; _ring_sample_count = 0; + _mipmap_sample_count = 0; for (unsigned int i = 0; i < _channel_num; i++) { _last_sample[i] = 0; @@ -257,6 +259,7 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic) if (_ring_sample_count % LeafBlockSamples == 0){ calc_mipmap(_channel_num - 1, index0, index1, LeafBlockSamples, true); + _mipmap_sample_count = _ring_sample_count; } break; @@ -278,7 +281,7 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic) uint64_t* chans_read_addr[CHANNEL_MAX_COUNT]; for (unsigned int i=0; i<_channel_num; i++){ - chans_read_addr[i] = (uint64_t*)data_src_ptr + i; + chans_read_addr[i] = (uint64_t*)data_src_ptr + i; } uint16_t fill_chan = _ch_fraction; @@ -286,7 +289,12 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic) index0 = align_sample_count / LeafBlockSamples / RootScale; index1 = (align_sample_count / LeafBlockSamples) % RootScale; offset = align_sample_count % LeafBlockSamples; - uint64_t *write_ptr = (uint64_t*)_ch_data[fill_chan][index0].lbp[index1] + offset / Scale; + uint64_t *write_ptr = (uint64_t*)_ch_data[fill_chan][index0].lbp[index1] + offset / Scale; + + if (_ch_data[fill_chan][index0].lbp[index1] == NULL){ + dsv_err("Write buffer is null."); + assert(false); + } while (len >= 8) { @@ -304,6 +312,9 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic) { calc_mipmap(fill_chan, index0, index1, LeafBlockSamples, true); + if (fill_chan + 1 == _channel_num) + _mipmap_sample_count = _ring_sample_count; + chans_read_addr[fill_chan] = read_ptr; fill_chan = (fill_chan + 1) % _channel_num; @@ -317,11 +328,16 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic) old_filled_sample = filled_sample; write_ptr = (uint64_t*)_ch_data[fill_chan][index0].lbp[index1] + offset / Scale; - read_ptr = chans_read_addr[fill_chan]; + read_ptr = chans_read_addr[fill_chan]; + + if (_ch_data[fill_chan][index0].lbp[index1] == NULL){ + dsv_err("Write buffer is null."); + assert(false); + } } else if (read_ptr >= end_read_ptr) { - calc_mipmap(fill_chan, index0, index1, filled_sample, false); + calc_mipmap(fill_chan, index0, index1, filled_sample, false); fill_chan = (fill_chan + 1) % _channel_num; @@ -336,13 +352,23 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic) write_ptr = (uint64_t*)_ch_data[fill_chan][index0].lbp[index1] + offset / Scale; read_ptr = chans_read_addr[fill_chan]; + + if (_ch_data[fill_chan][index0].lbp[index1] == NULL){ + dsv_err("Write buffer is null."); + assert(false); + } } } _ring_sample_count = align_sample_count; _ch_fraction = last_chan; - _dest_ptr = (uint8_t*)_ch_data[_ch_fraction][index0].lbp[index1] + offset / 8; + _dest_ptr = (uint8_t*)_ch_data[_ch_fraction][index0].lbp[index1] + offset / 8; + + if (_ch_data[_ch_fraction][index0].lbp[index1] == NULL){ + dsv_err("Write buffer is null."); + assert(false); + } if (len > 0) { @@ -382,6 +408,8 @@ void LogicSnapshot::capture_ended() calc_mipmap(chan, index0, index1, offset * 8, true); } + + _mipmap_sample_count = _ring_sample_count; } void LogicSnapshot::calc_mipmap(unsigned int order, uint8_t index0, uint8_t index1, uint64_t samples, bool isEnd) @@ -502,6 +530,34 @@ const uint8_t *LogicSnapshot::get_samples(uint64_t start_sample, uint64_t &end_s return (uint8_t*)_ch_data[order][index0].lbp[index1] + offset; } +const uint8_t *LogicSnapshot::get_decode_samples(uint64_t start_sample, uint64_t &end_sample, int sig_index) +{ + std::lock_guard lock(_mutex); + + assert(start_sample < _mipmap_sample_count); + assert(start_sample <= end_sample); + + if (end_sample >= _mipmap_sample_count){ + end_sample = _mipmap_sample_count - 1; + } + + int order = get_ch_order(sig_index); + uint64_t index0 = start_sample >> (LeafBlockPower + RootScalePower); + uint64_t index1 = (start_sample & RootMask) >> LeafBlockPower; + uint64_t offset = (start_sample & LeafMask) / 8; + + end_sample = (index0 << (LeafBlockPower + RootScalePower)) + + (index1 << LeafBlockPower) + + ~(~0ULL << LeafBlockPower); + + end_sample = min(end_sample + 1, _mipmap_sample_count); + + if (order == -1 || _ch_data[order][index0].lbp[index1] == NULL) + return NULL; + else + return (uint8_t*)_ch_data[order][index0].lbp[index1] + offset; +} + bool LogicSnapshot::get_sample(uint64_t index, int sig_index) { int order = get_ch_order(sig_index); @@ -1039,5 +1095,11 @@ int LogicSnapshot::get_ch_order(int sig_index) return -1; } +uint64_t LogicSnapshot::get_mipmap_sample_count() +{ + std::lock_guard lock(_mutex); + return _mipmap_sample_count; +} + } // namespace data } // namespace pv diff --git a/DSView/pv/data/logicsnapshot.h b/DSView/pv/data/logicsnapshot.h index 4f6af221..3478f2a7 100644 --- a/DSView/pv/data/logicsnapshot.h +++ b/DSView/pv/data/logicsnapshot.h @@ -96,6 +96,8 @@ public: const uint8_t * get_samples(uint64_t start_sample, uint64_t& end_sample, int sig_index); + const uint8_t * get_decode_samples(uint64_t start_sample, uint64_t& end_sample, int sig_index); + bool get_sample(uint64_t index, int sig_index); void capture_ended(); @@ -120,6 +122,8 @@ public: bool pattern_search(int64_t start, int64_t end, int64_t& index, std::map pattern, bool isNext); + uint64_t get_mipmap_sample_count(); + private: int get_ch_order(int sig_index); void calc_mipmap(unsigned int order, uint8_t index0, uint8_t index1, uint64_t samples, bool isEnd); @@ -192,6 +196,7 @@ private: uint64_t _last_sample[CHANNEL_MAX_COUNT]; uint64_t _last_calc_count[CHANNEL_MAX_COUNT]; + uint64_t _mipmap_sample_count; friend class LogicSnapshotTest::Pow2; friend class LogicSnapshotTest::Basic; diff --git a/DSView/pv/dock/protocoldock.cpp b/DSView/pv/dock/protocoldock.cpp index dd769065..5deed7f5 100644 --- a/DSView/pv/dock/protocoldock.cpp +++ b/DSView/pv/dock/protocoldock.cpp @@ -444,15 +444,13 @@ void ProtocolDock::del_all_protocol() void ProtocolDock::decoded_progress(int progress) { - (void) progress; - - int pg = 0; - QString err=""; const auto &decode_sigs = _session->get_decode_signals(); int index = 0; for(auto d : decode_sigs) { - pg = d->get_progress(); + int pg = d->get_progress(); + QString err; + if (d->decoder()->out_of_memory()) err = L_S(STR_PAGE_DLG, S_ID(IDS_DLG_OUT_OF_MEMORY), "Out of Memory"); @@ -470,8 +468,8 @@ void ProtocolDock::decoded_progress(int progress) index++; } - if (pg == 0 || pg % 10 == 1){ - update_model(); + if (progress == 0 || progress % 10 == 1){ + update_model(); } } @@ -1002,6 +1000,7 @@ bool ProtocolDock::protocol_sort_callback(const DecoderInfoItem *o1, const Decod void ProtocolDock::reset_view() { decoded_progress(0); + update(); } void ProtocolDock::update_view_status() diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index 8d0aae91..064ed6df 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -465,7 +465,7 @@ namespace pv } clear_all_decode_task2(); - clear_decode_result(); + clear_decode_result(); _capture_data->clear(); _view_data->clear(); @@ -581,7 +581,7 @@ namespace pv if (bAddDecoder){ clear_all_decode_task2(); - clear_decode_result(); + clear_decode_result(); } if (bSwapBuffer){ @@ -611,9 +611,8 @@ namespace pv if (mode == LOGIC) { for (auto de : _decode_traces){ - de->decoder()->set_capture_end_flag(false); - if (bAddDecoder){ + de->decoder()->set_capture_end_flag(false); de->frame_ended(); add_decode_task(de); } @@ -935,6 +934,7 @@ namespace pv _data_lock = true; _view_data->get_logic()->init(); + clear_all_decode_task2(); clear_decode_result(); _view_data->get_dso()->init(); @@ -2121,10 +2121,11 @@ namespace pv void SigSession::clear_decode_result() { - for (auto d : _decode_traces) - { - d->decoder()->init(); + for (auto de : _decode_traces){ + de->decoder()->init(); + de->decoder()->set_capture_end_flag(false); } + _callback->trigger_message(DSV_MSG_CLEAR_DECODE_DATA); } void SigSession::attach_data_to_signal(SessionData *data) diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h index b10f7b0a..58b991ed 100644 --- a/DSView/pv/sigsession.h +++ b/DSView/pv/sigsession.h @@ -442,7 +442,6 @@ private: inline void clear_all_decode_task2(){ int run_dex = 0; clear_all_decode_task(run_dex); - _callback->trigger_message(DSV_MSG_CLEAR_DECODE_DATA); } void decode_task_proc();