Fix dangling pointer bug in AutoFDOProfileReader::ReadNameTable#263
Fix dangling pointer bug in AutoFDOProfileReader::ReadNameTable#263snehasish merged 2 commits intogoogle:masterfrom
Conversation
The gcov_read_string function (https://github.com/google/autofdo/blob/master/gcov.cc#L226) returns a raw pointer to an internal buffer that can be realloc'd if it is too small (https://github.com/google/autofdo/blob/master/gcov.cc#L182-L184): ```cpp static inline void gcov_allocate(unsigned byte_length) { ... gcov_var.buffer = static_cast<char *>(realloc(gcov_var.buffer, new_byte_size)); } ... static inline const char *gcov_read_bytes(unsigned bytes) { const char *result; unsigned excess_bytes = gcov_var.byte_length - gcov_var.byte_offset; ... if (excess_bytes < bytes) { ... if (gcov_var.byte_length + bytes > gcov_var.byte_alloc) { gcov_allocate(gcov_var.byte_length + bytes); } ... } ... } const char * gcov_read_string(void) { ... if (absl::GetFlag(FLAGS_gcov_version) >= 2) { return gcov_read_bytes (length); } ... } ``` This means that the pointer that is returned can be invalidated by the very next read from the buffer, as seemed to be happening here. When I was stepping through this in a debugger, the string that was read magically got turned into an empty string after the next read.
|
Ping @snehasish |
|
|
||
| static std::string Name(const char *name) { | ||
| return (name && strlen(name) > 0) ? name : "noname"; | ||
| CHECK(strlen(name) > 0 && "Empty string should never occur in profile!"); |
There was a problem hiding this comment.
Calling strlen on null is undefined behaviour. This check doesn't seem to make sense if you return "noname" anyway? Can you refactor this to drop "noname"?
| uint32_t name_vector_size = gcov_read_unsigned(); | ||
| for (uint32_t i = 0; i < name_vector_size; i++) { | ||
| const char *name = gcov_read_string(); | ||
| const char *name = strdup(gcov_read_string()); |
There was a problem hiding this comment.
I think we are leaking memory here with strdup since the emplace call below copies the stirng content into names? Maybe just use std::string name(gcov_read_string()); here?
|
Ping @snehasish ? |
|
Hmm, the CI failure seems unrelated though I would like to have it fixed before we merge this. @dhoekwater Could you take a look? |
|
Could you try re-running the CI? Looks like a spurious apt failure. |
Thanks for the nudge, I should have looked more closely. |
The gcov_read_string function (https://github.com/google/autofdo/blob/master/gcov.cc#L226) returns a raw pointer to an internal buffer that can be realloc'd if it is too small (https://github.com/google/autofdo/blob/master/gcov.cc#L182-L184):
This means that the pointer that is returned can be invalidated by the very next read from the buffer, as seemed to be happening here. When I was stepping through this in a debugger, the string that was read magically got turned into an empty string after the next read.