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 |
symbol_map.h
Outdated
|
|
||
| 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"?
profile_reader.cc
Outdated
| 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.