Skip to content

Commit c07097c

Browse files
vpellanivoanjo
andauthored
[APMAPI-1774] Fix stable config segfault during error handling (#5073)
Co-authored-by: Ivo Anjo <[email protected]>
1 parent efaecc3 commit c07097c

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

ext/libdatadog_api/library_config.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,27 +99,28 @@ static VALUE _native_configurator_get(VALUE self) {
9999
ddog_Configurator *configurator;
100100
TypedData_Get_Struct(self, ddog_Configurator, &configurator_typed_data, configurator);
101101

102-
// Wrapping config_logged_result into a Ruby object enables the Ruby GC to manage its memory
103-
// We need to allocate memory for config_logged_result because once it is out of scope, it will be freed (at the end of this function)
104-
// So we cannot reference it with &config_logged_result
105-
// We are doing this in case one of the ruby API raises an exception before the end of this function,
106-
// so the allocated memory will still be freed
107-
ddog_LibraryConfigLoggedResult *configurator_logged_result = ruby_xcalloc(1, sizeof(ddog_LibraryConfigLoggedResult));
108-
*configurator_logged_result = ddog_library_configurator_get(configurator);
109-
VALUE config_logged_result_rb = TypedData_Wrap_Struct(config_logged_result_class, &config_logged_result_typed_data, configurator_logged_result);
102+
// We don't allocate memory here so if there is an error, we don't need to manage the memory
103+
ddog_LibraryConfigLoggedResult before_error_result = ddog_library_configurator_get(configurator);
110104

111-
if (configurator_logged_result->tag == DDOG_LIBRARY_CONFIG_LOGGED_RESULT_ERR) {
112-
ddog_Error err = configurator_logged_result->err;
105+
if (before_error_result.tag == DDOG_LIBRARY_CONFIG_LOGGED_RESULT_ERR) {
106+
ddog_Error err = before_error_result.err;
113107
VALUE message = get_error_details_and_drop(&err);
114108
if (is_config_loaded()) {
115109
log_warning(message);
116110
} else {
117111
log_warning_without_config(message);
118112
}
119-
RB_GC_GUARD(config_logged_result_rb);
120113
return rb_hash_new();
121114
}
122115

116+
// Wrapping config_logged_result into a Ruby object enables the Ruby GC to manage its memory
117+
// We need to allocate memory for config_logged_result because once it is out of scope, it will be freed (at the end of this function)
118+
// We are doing this in case one of the ruby API raises an exception before the end of this function,
119+
// so the allocated memory will still be freed
120+
ddog_LibraryConfigLoggedResult *configurator_logged_result = ruby_xcalloc(1, sizeof(ddog_LibraryConfigLoggedResult));
121+
*configurator_logged_result = before_error_result;
122+
VALUE config_logged_result_rb = TypedData_Wrap_Struct(config_logged_result_class, &config_logged_result_typed_data, configurator_logged_result);
123+
123124
VALUE logs = Qnil;
124125
if (configurator_logged_result->ok.logs.length > 0) {
125126
logs = rb_utf8_str_new_cstr(configurator_logged_result->ok.logs.ptr);

0 commit comments

Comments
 (0)