My application works just fine when I have defined the CAMERA_NAME environment variable, but as soon as I remove that variable from my docker-compose file, the container will return a very useless error message that doesn’t give me information such as what variable/line the error is occurring on:
basler-hd | terminate called after throwing an instance of 'std::logic_error'
basler-hd | what(): basic_string::_M_construct null not valid
Here is the relevant code:
try {
char const* camera_name_ = std::getenv("CAMERA_NAME");
if (!camera_name_)
camera_name_ = generate_uuid_v4().c_str();
init_loggers(camera_name_);
SPDLOG_INFO("Camera name (found in environment or was generated): {}", camera_name_);
SPDLOG_INFO("Starting Application.");
PylonInitialize();
mqtt::async_client client(DEFAULT_SERVER_ADDRESS, CLIENT_ID, PERSIST_DIRECTORY);
auto willMessage = mqtt::message("nssams/camera", "Camera Disconnected", 1, true);
auto connectionOptions = mqtt::connect_options_builder()
.clean_session()
.will(willMessage)
.finalize();
std::string ip_address = std::getenv("IP_ADDRESS") != NULL ? std::string(std::getenv("IP_ADDRESS")) : "192.168.0.1";
if (ip_address.compare("192.168.0.1") == 0)
SPDLOG_WARN("No IP address was found in environment, setting to '192.168.0.1'");
std::string camera_name(camera_name_);
// Instantiate Camera instance and connect.
Camera::MqttBaslerCamera camera( client, camera_name );
try {
camera.discover_and_create_device(ip_address);
} catch (Camera::MqttBaslerCamera::DeviceNotFoundException & ex){
SPDLOG_CRITICAL("No device found matching IP [{}] from environment", ip_address);
PylonTerminate();
return 1;
}
camera.connect();
// Assign the Camera instance as the mqtt callback handler.
client.set_callback(camera);
I am just struggling to see what the issue is. I am checking for NULL after I attempt to get a value from the CAMERA_NAME environment variable. If it’s NULL, I am setting it to a value before I move on.
I just can’t tell where it’s crashing because the error message is so vague, and if I add any log/cout statements, they won’t even run due to this error so I can’t tell at what point it’s crashing
2
Answers
To see where the error is from you could use a debugger to step through the code line by line to find where something unexpected is happening.
camera_name_
is a pointer. It is not a string. It can point to a c-string. Here:You make it point to the internal buffer of the string returned by
generate_uuid_v4()
. If the function returns the string by value then this string is temporary and ceases to exist at the end of the line. The pointer you stored incamera_name_
is then dangling. If the function would return a reference to a string that is stored elsewhere, keeping a pointer to it would be fine.Don’t use a pointer to a string when you actually want to store a string:
Without more context, one can only guess:
I think this is a
logical_error
if
camera_name_
is anullptr
.Which might be what
std::getenv
returns if the system variable is not found.If this is the problem, the fix depends on what you really want to do with that variable if the environment variable doesn’t exists?
Or if you are too cool for C++ (non-standard)
In fact you are already doing that for
std::string ip_address
.