Use %n to parse maps in libpagemap.
Bug: http://b/24212024
Change-Id: If00782c7af6fde30650045180512132ee5a8fd89
diff --git a/libpagemap/Android.mk b/libpagemap/Android.mk
index 96a4e94..05e6f01 100644
--- a/libpagemap/Android.mk
+++ b/libpagemap/Android.mk
@@ -13,17 +13,23 @@
# limitations under the License.
LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
+pagemap_src_files := \
+ pm_kernel.c \
+ pm_process.c \
+ pm_map.c \
+ pm_memusage.c \
+
+include $(CLEAR_VARS)
LOCAL_MODULE := libpagemap
LOCAL_MODULE_TAGS := debug
-
-LOCAL_SRC_FILES := \
- pm_kernel.c \
- pm_process.c \
- pm_map.c \
- pm_memusage.c
-
+LOCAL_SRC_FILES := $(pagemap_src_files)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
-
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := pagemap_test
+LOCAL_SRC_FILES := pagemap_test.cpp
+LOCAL_SHARED_LIBRARIES := libpagemap
+include $(BUILD_NATIVE_TEST)
diff --git a/libpagemap/pagemap_test.cpp b/libpagemap/pagemap_test.cpp
new file mode 100644
index 0000000..ccbc211
--- /dev/null
+++ b/libpagemap/pagemap_test.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <pagemap/pagemap.h>
+
+TEST(pagemap, maps) {
+ pm_kernel_t* kernel;
+ ASSERT_EQ(0, pm_kernel_create(&kernel));
+
+ pm_process_t* process;
+ ASSERT_EQ(0, pm_process_create(kernel, getpid(), &process));
+
+ pm_map_t** maps;
+ size_t num_maps;
+ ASSERT_EQ(0, pm_process_maps(process, &maps, &num_maps));
+
+ bool found_heap = false;
+ bool found_stack = false;
+ for (size_t i = 0; i < num_maps; i++) {
+ if (strcmp(maps[i]->name, "[heap]") == 0) found_heap = true;
+ if (strcmp(maps[i]->name, "[stack]") == 0) found_stack = true;
+ }
+
+ ASSERT_TRUE(found_heap);
+ ASSERT_TRUE(found_stack);
+
+ free(maps);
+ pm_process_destroy(process);
+ pm_kernel_destroy(kernel);
+}
diff --git a/libpagemap/pm_process.c b/libpagemap/pm_process.c
index 4d56428..b8e06c1 100644
--- a/libpagemap/pm_process.c
+++ b/libpagemap/pm_process.c
@@ -231,19 +231,13 @@
}
#define INITIAL_MAPS 10
-#define MAX_LINE 1024
#define MAX_PERMS 5
-/*
- * #define FOO 123
- * S(FOO) => "123"
- */
-#define _S(n) #n
-#define S(n) _S(n)
-
static int read_maps(pm_process_t *proc) {
char filename[MAX_FILENAME];
- char line[MAX_LINE], name[MAX_LINE], perms[MAX_PERMS];
+ char *line = NULL;
+ size_t line_length = 0;
+ char perms[MAX_PERMS];
FILE *maps_f;
pm_map_t *map, **maps, **new_maps;
int maps_count, maps_size;
@@ -269,12 +263,15 @@
return errno;
}
- while (fgets(line, MAX_LINE, maps_f)) {
+ while (getline(&line, &line_length, maps_f) != -1) {
+ line[strlen(line) - 1] = '\0'; // Lose the newline.
+
if (maps_count >= maps_size) {
new_maps = realloc(maps, 2 * maps_size * sizeof(pm_map_t*));
if (!new_maps) {
error = errno;
free(maps);
+ free(line);
fclose(maps_f);
return error;
}
@@ -286,20 +283,21 @@
map->proc = proc;
- name[0] = '\0';
- sscanf(line, "%" SCNx64 "-%" SCNx64 " %s %" SCNx64 " %*s %*d %" S(MAX_LINE) "s",
- &map->start, &map->end, perms, &map->offset, name);
+ int name_offset;
+ sscanf(line, "%" SCNx64 "-%" SCNx64 " %4s %" SCNx64 " %*s %*d %n",
+ &map->start, &map->end, perms, &map->offset, &name_offset);
- map->name = malloc(strlen(name) + 1);
+ map->name = strdup(line + name_offset);
if (!map->name) {
error = errno;
for (; maps_count > 0; maps_count--)
pm_map_destroy(maps[maps_count]);
free(maps);
+ free(line);
fclose(maps_f);
return error;
}
- strcpy(map->name, name);
+
if (perms[0] == 'r') map->flags |= PM_MAP_READ;
if (perms[1] == 'w') map->flags |= PM_MAP_WRITE;
if (perms[2] == 'x') map->flags |= PM_MAP_EXEC;
@@ -307,6 +305,7 @@
maps_count++;
}
+ free(line);
fclose(maps_f);
new_maps = realloc(maps, maps_count * sizeof(pm_map_t*));