1
0
mirror of https://github.com/dart-lang/sdk synced 2024-07-05 09:20:04 +00:00

[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.

This is a reland of 95474f44f1
with changes to android min-sdk to make android ARM builds
succeed (getline requires SDK 18+).

TEST=manually

Change-Id: I8b36fcd178680aed7f856bc884a5cd188a5f6e85
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319480
Commit-Queue: Slava Egorov <vegorov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This commit is contained in:
Vyacheslav Egorov 2023-08-09 12:59:31 +00:00 committed by Commit Queue
parent 0769b22b4f
commit 5ddb1b8ea7
2 changed files with 36 additions and 5 deletions

View File

@ -73,7 +73,7 @@ if (is_android) {
if (current_cpu == "x64" || current_cpu == "arm64") {
android_api_level = 22
} else {
android_api_level = 16
android_api_level = 19
}
# Toolchain root directory for each build. The actual binaries are inside

View File

@ -4562,14 +4562,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;
@ -4606,6 +4636,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);