Describe your environment
Reproduced by source read + build on main at 11fa0db0 (also present in v1.28.0, the latest release -- not a regression). sdk/src/resource/resource.cc, Resource::Create.
Steps to reproduce
Resource Resource::Create(const ResourceAttributes &attributes, const std::string &schema_url)
{
...
if (resource.attributes_.find(semconv::service::kServiceName) == resource.attributes_.end())
{
std::string default_service_name = "unknown_service";
auto it_process_executable_name =
resource.attributes_.find(semconv::process::kProcessExecutableName);
if (it_process_executable_name != resource.attributes_.end())
{
default_service_name += ":" + nostd::get<std::string>(it_process_executable_name->second);
}
resource.attributes_[semconv::service::kServiceName] = default_service_name;
}
return resource;
}
it_process_executable_name->second is an AttributeValue (nostd::variant). nostd::get<std::string> throws if the variant doesn't currently hold a std::string. process.executable.name can end up holding a different alternative than std::string in more than one way: a custom ResourceDetector setting it directly, an environment/config-driven attribute source, or simply a caller passing it in attributes as const char*/string_view/an integer by mistake -- none of those are prevented by the ResourceAttributes type itself.
To trigger: call Resource::Create(attributes, schema_url) with attributes containing {"process.executable.name", <anything that isn't a std::string>} and no service.name already set.
What is the expected behavior?
If process.executable.name is present but not a string, Resource::Create should fall back to just "unknown_service" (or otherwise degrade gracefully) rather than crash.
What is the actual behavior?
nostd::get<std::string> throws nostd::bad_variant_access. Since Resource::Create (and its callers up through TracerProvider/LoggerProvider/MeterProvider construction) isn't inside any exception handling, this propagates out and terminates initialization -- often during process/provider startup or a reload, i.e. exactly when an application least wants an unhandled crash.
Additional context
Suggested fix -- use nostd::get_if instead of the throwing nostd::get, and simply skip the suffix if the attribute isn't a string:
if (it_process_executable_name != resource.attributes_.end())
{
- default_service_name += ":" + nostd::get<std::string>(it_process_executable_name->second);
+ if (const auto *executable_name =
+ nostd::get_if<std::string>(&it_process_executable_name->second))
+ {
+ default_service_name += ":" + *executable_name;
+ }
}
Compile-checked against a clean build of this file -- no warnings or errors. Happy to open a PR with this if useful.
Describe your environment
Reproduced by source read + build on
mainat11fa0db0(also present in v1.28.0, the latest release -- not a regression).sdk/src/resource/resource.cc,Resource::Create.Steps to reproduce
it_process_executable_name->secondis anAttributeValue(nostd::variant).nostd::get<std::string>throws if the variant doesn't currently hold astd::string.process.executable.namecan end up holding a different alternative thanstd::stringin more than one way: a customResourceDetectorsetting it directly, an environment/config-driven attribute source, or simply a caller passing it inattributesasconst char*/string_view/an integer by mistake -- none of those are prevented by theResourceAttributestype itself.To trigger: call
Resource::Create(attributes, schema_url)withattributescontaining{"process.executable.name", <anything that isn't a std::string>}and noservice.namealready set.What is the expected behavior?
If
process.executable.nameis present but not a string,Resource::Createshould fall back to just"unknown_service"(or otherwise degrade gracefully) rather than crash.What is the actual behavior?
nostd::get<std::string>throwsnostd::bad_variant_access. SinceResource::Create(and its callers up throughTracerProvider/LoggerProvider/MeterProviderconstruction) isn't inside any exception handling, this propagates out and terminates initialization -- often during process/provider startup or a reload, i.e. exactly when an application least wants an unhandled crash.Additional context
Suggested fix -- use
nostd::get_ifinstead of the throwingnostd::get, and simply skip the suffix if the attribute isn't a string:if (it_process_executable_name != resource.attributes_.end()) { - default_service_name += ":" + nostd::get<std::string>(it_process_executable_name->second); + if (const auto *executable_name = + nostd::get_if<std::string>(&it_process_executable_name->second)) + { + default_service_name += ":" + *executable_name; + } }Compile-checked against a clean build of this file -- no warnings or errors. Happy to open a PR with this if useful.