gRPC trace.cc 的方法 TraceFlagList::Add(TraceFlag* flag) 使其链接列表
Method TraceFlagList::Add(TraceFlag* flag) of gRPC trace.cc makes its chained list loop to itself
我正在为 32 位 Atom 硬件集成 gRPC。 gRPC 在 64 位 Ubuntu PC 计算机上交叉编译。交叉编译使用Yocto。gRPC 的 CMakeLists.txt 文件包含在带有 add_subdirectory(( 函数的主项目中,并以静态方式链接。为了测试 gRPC,我使用了 Google 的C++语音示例代码。
完整的项目正确构建,并且可以毫无问题地部署在目标硬件上。当我运行示例程序时,执行卡在文件 trace.cc 的方法 TraceFlagList::Set(const char* name, bool enabled( 中的无限循环中。
为了检查问题,我在每个循环中都用这种方法放了一些 printf((:
bool TraceFlagList::Set(const char* name, bool enabled) {
TraceFlag* t;
if (0 == strcmp(name, "all")) {
for (t = root_tracer_; t; t = t->next_tracer_) {
printf("%s 1 %sn", __func__, t->name_);
t->set_enabled(enabled);
}
} else if (0 == strcmp(name, "list_tracers")) {
LogAllTracers();
} else if (0 == strcmp(name, "refcount")) {
for (t = root_tracer_; t; t = t->next_tracer_) {
printf("%s 2 %sn", __func__, t->name_);
if (strstr(t->name_, "refcount") != nullptr) {
t->set_enabled(enabled);
}
}
} else {
bool found = false;
for (t = root_tracer_; t; t = t->next_tracer_) {
printf("%s 3 %sn", __func__, t->name_);
if (0 == strcmp(name, t->name_)) {
t->set_enabled(enabled);
found = true;
}
}
// check for unknowns, but ignore "", to allow to GRPC_TRACE=
if (!found && 0 != strcmp(name, "")) {
gpr_log(GPR_ERROR, "Unknown trace var: '%s'", name);
return false; /* early return */
}
}
return true;
}
似乎在 TraceFlagList 对象中添加了多次 TraceFlag 指针。下面是添加方法:
void TraceFlagList::Add(TraceFlag* flag) {
flag->next_tracer_ = root_tracer_;
root_tracer_ = flag;
}
要添加的第一个元素的next_tracer_成员指向 null。但是经过几次添加后,使用相同的 TraceFlag 指针再次调用 TraceFlagList::Add((。第一个成员将使其next_tracer_成员指向列表的最后一个元素,使列表循环到自身。
运行可执行文件会在命令行中显示以下行:
...
Set 3 api
Set 3 timer_check
Set 3 timer
Set 3 resource_quota
Set 3 executor
Set 3 bdp_estimator
Set 3 client_idle_filter
Set 3 cares_resolver
Set 3 cares_address_sorting
Set 3 round_robin
Set 3 pick_first
Set 3 xds
Set 3 glb
Set 3 inproc
Set 3 health_check_client
Set 3 secure_endpoint
Set 3 http2_stream_state
Set 3 flowctl
Set 3 http
Set 3 connectivity_state
Set 3 tcp
Set 3 http1
Set 3 handshaker
Set 3 channel
Set 3 subchannel_pool
Set 3 subchannel
Set 3 client_channel_routing
Set 3 client_channel_call
Set 3 tsi
Set 3 plugin_credentials
Set 3 server_channel
Set 3 queue_pluck
Set 3 op_failure
Set 3 compression
Set 3 call_error
Set 3 api
Set 3 timer_check
Set 3 timer
Set 3 resource_quota
Set 3 executor
Set 3 bdp_estimator
Set 3 client_idle_filter
Set 3 cares_resolver
Set 3 cares_address_sorting
^C
我必须用ctrl + c破坏可执行文件才能停止它。我通过首先检查要添加到列表中的元素是否存在来解决此问题:
void TraceFlagList::Add(TraceFlag* flag) {
// Check TraceFlag existence in the list before adding it.
for (const TraceFlag* t = root_tracer_; t != nullptr; t = t->next_tracer_) {
if (t == flag) {
gpr_log(GPR_DEBUG, "t%s", t->name_);
printf("TraceFlag %s already in TraceFlagList. Ignore.n", t->name_);
return;
}
}
flag->next_tracer_ = root_tracer_;
root_tracer_ = flag;
}
但这是一个解决方法:在为 Ubuntu 主机构建和运行原始代码时,不存在无限循环的问题。每个跟踪标志指针仅添加一次。我真的不知道 TraceFlag 在 gRPC 中的用途。
我担心解决方法可能会隐藏真正的问题,这可能会产生意想不到的副作用。有没有人知道这个问题的根源?或者我应该在 gRPC 项目中提出这种解决方法?
问候。
这看起来像 https://github.com/grpc/grpc/issues/20690 gRPC核心使用一些全局变量,如果你以某种方式链接了多个版本的grpC库,全局变量就会损坏。
- Pybind11:将元组列表从Python传递到C++
- 从链接列表c++中删除一个项目
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- C++如何通过用户输入删除列表元素
- 读取文件的最后一行并输入到链接列表时出错
- 复制列表初始化的隐式转换的等级是多少
- LNK2038、MSVS2017 MAGMA的原因列表
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 没有为自己的结构调用列表推回方法
- 使用简单类型列表实现的指数编译时间.为什么
- 一对向量构造函数:初始值设定项列表与显式构造
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 通过for循环使用用户输入填充列表
- C++:如何使函数只返回作为列表一部分的字符串
- 概念中的cv限定符需要表达式参数列表
- 下面是我为检测链接列表中的循环而制作的代码
- 建议在运行时将带有类实例的列表从c++导入qml
- 如何维护资源管理器项目视图中当前可见的项目列表
- 在卡萨布兰卡形成编码参数的列表
- gRPC trace.cc 的方法 TraceFlagList::Add(TraceFlag* flag) 使其链接列表