C++ WebRTC std::当RTC\u DCHECK\u打开时,取消迭代器异常
最近,自从lib WebRTC的M83和M84发布以来,当我在Visual Studio上的Windows x64调试配置(RTC\u DCHECK\u IS\u ON)中运行主机程序时,我遇到了一个奇怪的错误: 在WebRTC库中创建视频频道时,我在C++ WebRTC std::当RTC\u DCHECK\u打开时,取消迭代器异常,c++,webrtc,deque,C++,Webrtc,Deque,最近,自从lib WebRTC的M83和M84发布以来,当我在Visual Studio上的Windows x64调试配置(RTC\u DCHECK\u IS\u ON)中运行主机程序时,我遇到了一个奇怪的错误: 在WebRTC库中创建视频频道时,我在 _Deque_const_iterator& operator++() { #if _ITERATOR_DEBUG_LEVEL != 0 const auto _Mycont = static_ca
_Deque_const_iterator& operator++() {
#if _ITERATOR_DEBUG_LEVEL != 0
const auto _Mycont = static_cast<const _Mydeque*>(this->_Getcont());
_STL_VERIFY(_Mycont, "cannot increment value-initialized deque iterator");
here----> _STL_VERIFY(this->_Myoff < _Mycont->_Myoff + _Mycont->_Mysize, "cannot increment deque iterator past end");**
#endif // _ITERATOR_DEBUG_LEVEL != 0
++_Myoff;
return *this;
}
\u Deque\u const\u迭代器和运算符++(){
#如果_迭代器_调试_级别!=0
const auto_Mycont=static_cast(this->_Getcont());
_STL_VERIFY(_Mycont,“无法增量值初始化的deque迭代器”);
此处-->\u STL\u VERIFY(此->\u Myoff<\u Mycont->\u Myoff+\u Mycont->\u Mysize,“无法增加数据迭代器的末尾”)**
#endif/\迭代器\调试\级别!=0
++_迈奥夫;
归还*这个;
}
因为_Myoff是空的
此++运算符是从WebRTC库中的rtc_base/thread.cc调用的,如下所示:
void ThreadManager::RegisterSendAndCheckForCycles(Thread* source,
Thread* target) {
CritScope cs(&crit_);
std::deque<Thread*> all_targets({target});
// We check the pre-existing who-sends-to-who graph for any path from target
// to source. This loop is guaranteed to terminate because per the send graph
// invariant, there are no cycles in the graph.
for (auto it = all_targets.begin(); it != all_targets.end(); ++it) {
const auto& targets = send_graph_[*it];
all_targets.insert(all_targets.end(), targets.begin(), targets.end());
}
...
void ThreadManager::RegisterSendAndCheckForCycles(线程*源、,
线程*目标){
CritScope-cs(和crit_uu);
std::确定所有_目标({target});
//我们检查预先存在的who发送给who的图,以查找来自目标的任何路径
//到源。此循环保证终止,因为根据发送图
//不变,图中没有循环。
for(自动it=所有_目标。开始();it!=所有_目标。结束();++it){
const auto&targets=send_graph_uu[*it];
所有_targets.insert(所有_targets.end(),targets.begin(),targets.end());
}
...
它来自于++它来自于std::deque请注意,我还向WebRTC团队报告了此错误:问题来自rtc_base/thread.cc文件的函数寄存器SendAndCheckForCycles
for (auto it = all_targets.begin(); it != all_targets.end(); ++it) {
const auto& targets = send_graph_[*it];
all_targets.insert(all_targets.end(), targets.begin(), targets.end());
}
调用all_targets.insert时,“it”无效,因为所有_目标中的内存分配都已更改,因此下一个++it生成断言失败。使用索引可以解决此问题
以下是固定版本:
void ThreadManager::RegisterSendAndCheckForCycles(Thread* source,Thread* target) {
CritScope cs(&crit_);
std::deque<Thread*> all_targets({target});
// We check the pre-existing who-sends-to-who graph for any path from target
// to source. This loop is guaranteed to terminate because per the send graph
// invariant, there are no cycles in the graph.
for (size_t i = 0; i < all_targets.size(); i++) {
const auto& targets = send_graph_[all_targets[i]];
all_targets.insert(all_targets.end(), targets.begin(), targets.end());
}
RTC_CHECK_EQ(absl::c_count(all_targets, source), 0)
<< " send loop between " << source->name() << " and " << target->name();
// We may now insert source -> target without creating a cycle, since there
// was no path from target to source per the prior CHECK.
send_graph_[source].insert(target);
}
void ThreadManager::RegisterSendAndCheckForCycles(线程*源,线程*目标){
CritScope-cs(和crit_uu);
std::确定所有_目标({target});
//我们检查预先存在的who发送给who的图,以查找来自目标的任何路径
//到源。此循环保证终止,因为根据发送图
//不变,图中没有循环。
对于(size_t i=0;i 问题来自rtc_base/thread.cc文件的函数RegisterSendAndCheckForCycles
for (auto it = all_targets.begin(); it != all_targets.end(); ++it) {
const auto& targets = send_graph_[*it];
all_targets.insert(all_targets.end(), targets.begin(), targets.end());
}
调用all_targets.insert时,“it”无效,因为所有_目标中的内存分配都已更改,因此下一个++it生成断言失败。使用索引可以解决此问题
以下是固定版本:
void ThreadManager::RegisterSendAndCheckForCycles(Thread* source,Thread* target) {
CritScope cs(&crit_);
std::deque<Thread*> all_targets({target});
// We check the pre-existing who-sends-to-who graph for any path from target
// to source. This loop is guaranteed to terminate because per the send graph
// invariant, there are no cycles in the graph.
for (size_t i = 0; i < all_targets.size(); i++) {
const auto& targets = send_graph_[all_targets[i]];
all_targets.insert(all_targets.end(), targets.begin(), targets.end());
}
RTC_CHECK_EQ(absl::c_count(all_targets, source), 0)
<< " send loop between " << source->name() << " and " << target->name();
// We may now insert source -> target without creating a cycle, since there
// was no path from target to source per the prior CHECK.
send_graph_[source].insert(target);
}
void ThreadManager::RegisterSendAndCheckForCycles(线程*源,线程*目标){
CritScope-cs(和crit_uu);
std::确定所有_目标({target});
//我们检查预先存在的who发送给who的图,以查找来自目标的任何路径
//到源。此循环保证终止,因为根据发送图
//不变,图中没有循环。
对于(size_t i=0;i