diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp index d61c1cd5e..176676268 100644 --- a/tests/pthread_test.cpp +++ b/tests/pthread_test.cpp @@ -41,6 +41,8 @@ #include "BionicDeathTest.h" #include "ScopedSignalHandler.h" +#include "utils.h" + extern "C" pid_t gettid(); TEST(pthread, pthread_key_create) { @@ -1158,19 +1160,14 @@ TEST(pthread, pthread_attr_getstack__main_thread) { #if defined(__BIONIC__) // What does /proc/self/maps' [stack] line say? void* maps_stack_hi = NULL; - FILE* fp = fopen("/proc/self/maps", "r"); - ASSERT_TRUE(fp != NULL); - char line[BUFSIZ]; - while (fgets(line, sizeof(line), fp) != NULL) { - uintptr_t lo, hi; - int name_pos; - sscanf(line, "%" PRIxPTR "-%" PRIxPTR " %*4s %*x %*x:%*x %*d %n", &lo, &hi, &name_pos); - if (strcmp(line + name_pos, "[stack]\n") == 0) { - maps_stack_hi = reinterpret_cast(hi); + std::vector maps; + ASSERT_TRUE(Maps::parse_maps(&maps)); + for (auto& map : maps) { + if (map.pathname == "[stack]") { + maps_stack_hi = reinterpret_cast(map.addr_end); break; } } - fclose(fp); // The high address of the /proc/self/maps [stack] region should equal stack_base + stack_size. // Remember that the stack grows down (and is mapped in on demand), so the low address of the diff --git a/tests/utils.h b/tests/utils.h index fd012a345..53cf6b6ea 100644 --- a/tests/utils.h +++ b/tests/utils.h @@ -38,9 +38,7 @@ struct map_record { class Maps { public: static bool parse_maps(std::vector* maps) { - char path[64]; - snprintf(path, sizeof(path), "/proc/self/task/%d/maps", getpid()); - FILE* fp = fopen(path, "re"); + FILE* fp = fopen("/proc/self/maps", "re"); if (fp == nullptr) { return false; } @@ -53,11 +51,11 @@ class Maps { while (fgets(line, sizeof(line), fp) != nullptr) { map_record record; uint32_t dev_major, dev_minor; - char pathstr[BUFSIZ]; + int path_offset; char prot[5]; // sizeof("rwxp") - if (sscanf(line, "%" SCNxPTR "-%" SCNxPTR " %4s %" SCNxPTR " %x:%x %lu %s", + if (sscanf(line, "%" SCNxPTR "-%" SCNxPTR " %4s %" SCNxPTR " %x:%x %lu %n", &record.addr_start, &record.addr_end, prot, &record.offset, - &dev_major, &dev_minor, &record.inode, pathstr) == 8) { + &dev_major, &dev_minor, &record.inode, &path_offset) == 7) { record.perms = 0; if (prot[0] == 'r') { record.perms |= PROT_READ; @@ -72,7 +70,10 @@ class Maps { // TODO: parse shared/private? record.device = makedev(dev_major, dev_minor); - record.pathname = pathstr; + record.pathname = line + path_offset; + if (!record.pathname.empty() && record.pathname.back() == '\n') { + record.pathname.pop_back(); + } maps->push_back(record); } }