[vm/service] Use getline to read /proc/self/smaps

Previously the code was using `fgets` with a fixed
size buffer. This lead to a confusing behavior where
lines longer than 255 characters would be read
in multiple chunks and cause crashes in the parsing code.

Additionally make extraction of the path component slightly
more robust by searching for path field forward rather than
backwards. Path might contain white space and searching
backwards might stumble on that.

TEST=manually

Change-Id: I1d23df4a79b04721d3a812e19eae9b8ad0e955fa
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/317683
Commit-Queue: Slava Egorov <vegorov@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
This commit is contained in:
Vyacheslav Egorov 2023-08-02 17:13:30 +00:00 committed by Commit Queue
parent de85b75eb7
commit 95474f44f1

View file

@ -4567,14 +4567,44 @@ static void AddVMMappings(JSONArray* rss_children) {
}
MallocGrowableArray<VMMapping> mappings(10);
char line[256];
char* line = nullptr;
size_t line_buffer_size = 0;
char path[256];
char property[32];
size_t start, end, size;
while (fgets(line, sizeof(line), fp) != nullptr) {
while (getline(&line, &line_buffer_size, fp) > 0) {
if (sscanf(line, "%zx-%zx", &start, &end) == 2) {
// Mapping line.
strncpy(path, strrchr(line, ' ') + 1, sizeof(path) - 1);
// Each line has the following format:
//
// start-end flags offset dev inode path
//
// We want to skip 4 fields and get to the last one (path).
// Note that we can't scan backwards because path might contain white
// space.
const intptr_t kPathFieldIndex = 5;
char* path_start = line;
intptr_t current_field = 0;
while (*path_start != '\0') {
// Field separator.
if (*path_start == ' ') {
// Skip to the first non-space.
while (*path_start == ' ') {
path_start++;
}
current_field++;
if (current_field == kPathFieldIndex) {
break;
}
continue;
}
path_start++;
}
if (current_field != kPathFieldIndex) {
continue; // Malformed input.
}
strncpy(path, path_start, sizeof(path) - 1);
int len = strlen(path);
if ((len > 0) && path[len - 1] == '\n') {
path[len - 1] = 0;
@ -4611,6 +4641,7 @@ static void AddVMMappings(JSONArray* rss_children) {
}
}
fclose(fp);
free(line); // Free buffer allocated by getline.
for (intptr_t i = 0; i < mappings.length(); i++) {
JSONObject mapping(rss_children);