gpt4 book ai didi

c++ - gRPC trace.cc 的方法 TraceFlagList::Add(TraceFlag* flag) 使其链表循环到自身

转载 作者:太空宇宙 更新时间:2023-11-04 12:33:00 33 4
gpt4 key购买 nike

我正在为 32 位 Atom 硬件集成 gRPC。 gRPC 在 64 位 Ubuntu PC 计算机上交叉编译。交叉编译使用 Yocto。 gRPC 的 CMakeLists.txt 文件通过 add_subdirectory() 函数包含到主项目中,并以静态方式链接。为了测试gRPC,我使用了谷歌的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 %s\n", __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 %s\n", __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 %s\n", __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。但是在多次添加之后,TraceFlagList::Add() 会再次使用相同的 TraceFlag 指针调用。第一个将其 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 指针仅添加一次。而且我真的不知道 TraceFlag 在 gRPC 中的用途。

恐怕解决方法可能会隐藏真正的问题,这可能会产生意想不到的副作用。有人知道这个问题的根源吗?或者我应该在 gRPC 项目中提出这个变通办法吗?

问候。

最佳答案

这看起来像 https://github.com/grpc/grpc/issues/20690grpc 核心使用一些全局变量,如果您以某种方式链接了多个版本的 grpc 库,则全局变量会损坏。

关于c++ - gRPC trace.cc 的方法 TraceFlagList::Add(TraceFlag* flag) 使其链表循环到自身,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57891055/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com