2646 // |
2646 // |
2647 // We only need this for stacks that are growable: at the time of |
2647 // We only need this for stacks that are growable: at the time of |
2648 // writing thread stacks don't use growable mappings (i.e. those |
2648 // writing thread stacks don't use growable mappings (i.e. those |
2649 // creeated with MAP_GROWSDOWN), and aren't marked "[stack]", so this |
2649 // creeated with MAP_GROWSDOWN), and aren't marked "[stack]", so this |
2650 // only applies to the main thread. |
2650 // only applies to the main thread. |
2651 static bool |
2651 |
2652 get_stack_bounds(uintptr_t *bottom, uintptr_t *top) |
2652 static |
2653 { |
2653 bool get_stack_bounds(uintptr_t *bottom, uintptr_t *top) { |
2654 FILE *f = fopen("/proc/self/maps", "r"); |
2654 |
2655 if (f == NULL) |
2655 char buf[128]; |
|
2656 int fd, sz; |
|
2657 |
|
2658 if ((fd = ::open("/proc/self/maps", O_RDONLY)) < 0) { |
2656 return false; |
2659 return false; |
2657 |
2660 } |
2658 while (!feof(f)) { |
2661 |
2659 size_t dummy; |
2662 const char kw[] = "[stack]"; |
2660 char *str = NULL; |
2663 const int kwlen = sizeof(kw)-1; |
2661 ssize_t len = getline(&str, &dummy, f); |
2664 |
2662 if (len == -1) { |
2665 // Address part of /proc/self/maps couldn't be more than 128 bytes |
2663 fclose(f); |
2666 while ((sz = os::get_line_chars(fd, buf, sizeof(buf))) > 0) { |
2664 return false; |
2667 if (sz > kwlen && ::memcmp(buf+sz-kwlen, kw, kwlen) == 0) { |
2665 } |
2668 // Extract addresses |
2666 |
2669 if (sscanf(buf, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) { |
2667 if (len > 0 && str[len-1] == '\n') { |
2670 uintptr_t sp = (uintptr_t) __builtin_frame_address(0); |
2668 str[len-1] = 0; |
2671 if (sp >= *bottom && sp <= *top) { |
2669 len--; |
2672 ::close(fd); |
2670 } |
2673 return true; |
2671 |
2674 } |
2672 static const char *stack_str = "[stack]"; |
|
2673 if (len > (ssize_t)strlen(stack_str) |
|
2674 && (strcmp(str + len - strlen(stack_str), stack_str) == 0)) { |
|
2675 if (sscanf(str, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) { |
|
2676 uintptr_t sp = (uintptr_t)__builtin_frame_address(0); |
|
2677 if (sp >= *bottom && sp <= *top) { |
|
2678 free(str); |
|
2679 fclose(f); |
|
2680 return true; |
|
2681 } |
2675 } |
2682 } |
2676 } |
2683 } |
2677 } |
2684 free(str); |
2678 |
2685 } |
2679 ::close(fd); |
2686 fclose(f); |
|
2687 return false; |
2680 return false; |
2688 } |
2681 } |
|
2682 |
2689 |
2683 |
2690 // If the (growable) stack mapping already extends beyond the point |
2684 // If the (growable) stack mapping already extends beyond the point |
2691 // where we're going to put our guard pages, truncate the mapping at |
2685 // where we're going to put our guard pages, truncate the mapping at |
2692 // that point by munmap()ping it. This ensures that when we later |
2686 // that point by munmap()ping it. This ensures that when we later |
2693 // munmap() the guard pages we don't leave a hole in the stack |
2687 // munmap() the guard pages we don't leave a hole in the stack |