open-telemetry / open-telemetry/opentelemetry-cpp
[BUG] Resource::Create() throws bad_variant_access if process.executable.name isn't a string
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 1.4k
- Forks
- 632
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 75
Description
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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in sdk/src/resource/resource.cc at Resource::Create, focusing on the default service-name logic and the process.executable.name attribute. Verify behavior with a non-string attribute and confirm that creation falls back to "unknown_service" without throwing or terminating initialization.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- observability-sre
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 84/100