]> git.saurik.com Git - apple/libc.git/blobdiff - gen/stack_logging_disk.c
Libc-825.40.1.tar.gz
[apple/libc.git] / gen / stack_logging_disk.c
index 83c882f81dbff98a6543cb2cf0653f092b878365..00a0caed92a2b59b218a940bd48e64c70ff91c92 100644 (file)
@@ -170,6 +170,7 @@ static OSSpinLock stack_logging_lock = OS_SPINLOCK_INIT;
 extern void __stack_logging_fork_prepare();
 extern void __stack_logging_fork_parent();
 extern void __stack_logging_fork_child();
+extern void __stack_logging_early_finished();
 
 // support for gdb and others checking for stack_logging locks
 __private_extern__ boolean_t __stack_logging_locked();
@@ -187,9 +188,10 @@ static const char *stack_log_file_base_name = "stack-logs.";
 static const char *stack_log_file_suffix = ".index";
 static const char *stack_log_link_suffix = ".link";
 
-static char stack_log_location[PATH_MAX];
-static char stack_log_reference_file[PATH_MAX];
-static char index_file_path[PATH_MAX];
+static void *stack_log_path_buffers = NULL;
+static char *stack_log_location = NULL;
+static char *stack_log_reference_file = NULL;
+char *__stack_log_file_path__ = NULL;
 static int index_file_descriptor = -1;
 
 // for accessing remote log files
@@ -248,6 +250,13 @@ __create_uniquing_table(void)
        return uniquing_table;
 }
 
+static void
+__destroy_uniquing_table(backtrace_uniquing_table* table)
+{
+       deallocate_pages(table->table, table->tableSize);
+       deallocate_pages(table, sizeof(backtrace_uniquing_table));
+}
+
 static void 
 __expand_uniquing_table(backtrace_uniquing_table *uniquing_table)
 {
@@ -285,10 +294,13 @@ __expand_uniquing_table(backtrace_uniquing_table *uniquing_table)
 static int 
 __enter_frames_in_table(backtrace_uniquing_table *uniquing_table, uint64_t *foundIndex, mach_vm_address_t *frames, int32_t count)
 {      
+       // The hash values need to be the same size as the addresses (because we use the value -1), for clarity, define a new type
+       typedef mach_vm_address_t hash_index_t;
+
        mach_vm_address_t thisPC;
-       uint64_t hash, uParent = (uint64_t)(-1ll), modulus = (uniquing_table->numNodes-uniquing_table->untouchableNodes-1);
+       hash_index_t hash, uParent = (hash_index_t)(-1ll), modulus = (uniquing_table->numNodes-uniquing_table->untouchableNodes-1);
        int32_t collisions, lcopy = count, returnVal = 1;
-       uint64_t hash_multiplier = ((uniquing_table->numNodes - uniquing_table->untouchableNodes)/(uniquing_table->max_collide*2+1));
+       hash_index_t hash_multiplier = ((uniquing_table->numNodes - uniquing_table->untouchableNodes)/(uniquing_table->max_collide*2+1));
        mach_vm_address_t *node;
        while (--lcopy >= 0) {
         thisPC = frames[lcopy];
@@ -384,7 +396,63 @@ append_int(char * filename, pid_t pid, size_t maxLength)
        }
 }
 
-// If successful, returns path to log file that was created.  Otherwise returns NULL.
+/*
+ * <rdar://problem/11128080> if we needed to call confstr during init then setting this
+ * flag will postpone stack logging until after Libsystem's initialiser has run.
+ */
+static void
+postpone_stack_logging(void)
+{
+       _malloc_printf(ASL_LEVEL_INFO, "stack logging postponed until after initialization.\n");
+       stack_logging_postponed = 1;
+}
+
+/*
+ * Check various temporary directory options starting with _PATH_TMP and use confstr.
+ * Allocating and releasing target buffer is the caller's responsibility.
+ */
+static bool
+get_writeable_temp_dir(char* target)
+{
+       if (!target) return false;
+       if (-1 != access(_PATH_TMP, W_OK)) {
+               strlcpy(target, _PATH_TMP, (size_t)PATH_MAX);
+               return true;
+       }
+       if (getenv("TMPDIR") && (-1 != access(getenv("TMPDIR"), W_OK))) {
+               strlcpy(target, getenv("TMPDIR"), (size_t)PATH_MAX);
+               return true;
+       }
+       if (stack_logging_finished_init) {
+               size_t n = confstr(_CS_DARWIN_USER_TEMP_DIR, target, (size_t) PATH_MAX);
+               if ((n > 0) && (n < PATH_MAX)) return true;
+               n = confstr(_CS_DARWIN_USER_CACHE_DIR, target, (size_t) PATH_MAX);
+               if ((n > 0) && (n < PATH_MAX)) return true;
+       } else {
+               /* <rdar://problem/11128080> Can't call confstr during init, so postpone
+                logging till after */
+               postpone_stack_logging();
+       }
+       /* No writeable tmp directory found. Maybe shd try /private/var/tmp for device here ... */
+       *target = '\0';
+       return false;
+}
+
+/*
+ * If successful, returns path to log file that was created, otherwise NULL.
+ *
+ * The log could be in one of 3 places (in decreasing order of preference)
+ *
+ * 1)  value of environment variable MallocStackLoggingDirectory
+ * 2)  the temp directory /tmp for desktop apps and internal apps on devices, or
+ * 3)  the sandbox location + tmp/ in case of 3rd party apps on the device.
+ *
+ * For 1 and 3, we create a .link file with the path of the file. We prefer to
+ * create this file in /tmp, but if we are unable to (device 3rd party case),
+ * we create it in the same location as the .index file and issue a message
+ * in syslog asking for it to be copied to /tmp to enable tools.
+ *
+ */
 static char *
 create_log_file(void)
 {
@@ -392,69 +460,112 @@ create_log_file(void)
        const char *progname = getprogname();
        char *created_log_location = NULL;
 
+       if (stack_log_path_buffers == NULL) {
+               /*
+                * on first use, allocate buffers directly from the OS without
+                * using malloc
+                */
+
+               stack_log_path_buffers = allocate_pages((uint64_t)round_page(3*PATH_MAX));
+               if (stack_log_path_buffers == NULL) {
+                       _malloc_printf(ASL_LEVEL_INFO, "unable to allocate memory for path buffers\n");
+                       return NULL;
+               }
+               
+               stack_log_location = &((char *)stack_log_path_buffers)[0*PATH_MAX];
+               stack_log_reference_file = &((char *)stack_log_path_buffers)[1*PATH_MAX];
+               __stack_log_file_path__ = &((char *)stack_log_path_buffers)[2*PATH_MAX];
+       }
+       
        // WARNING! use of snprintf can induce malloc() calls 
        bool use_alternate_location = false;
        char *evn_log_directory = getenv("MallocStackLoggingDirectory");
+       size_t stack_log_len;
        if (evn_log_directory && *evn_log_directory) {
                use_alternate_location = true;
                strlcpy(stack_log_location, evn_log_directory, (size_t)PATH_MAX);
-               size_t evn_log_len = strlen(stack_log_location);
-               // add the '/' only if it's not already there.
-               if (evn_log_directory[evn_log_len-1] != '/') {
-                       strlcat(stack_log_location, "/", (size_t)PATH_MAX);
+       }
+       if (!use_alternate_location || (access(stack_log_location, W_OK) == -1)) {
+               if (!get_writeable_temp_dir(stack_log_location)) {
+                       if (!stack_logging_postponed) {
+                               _malloc_printf(ASL_LEVEL_INFO, "No writeable tmp dir\n");
+                       }
+                       return NULL;
                }
-       } else {
-               strlcpy(stack_log_location, _PATH_TMP, (size_t)PATH_MAX);       
+               if (0 != strcmp(stack_log_location, _PATH_TMP))
+                       use_alternate_location = true;
+       }
+       stack_log_len = strlen(stack_log_location);
+       // add the '/' only if it's not already there.
+       if (stack_log_location[stack_log_len-1] != '/') {
+               strlcat(stack_log_location, "/", (size_t)PATH_MAX);
+               ++stack_log_len;
        }
        
-       strlcat(stack_log_location, stack_log_file_base_name, (size_t)PATH_MAX);
-       append_int(stack_log_location, pid, (size_t)PATH_MAX);
+       strlcpy(__stack_log_file_path__, stack_log_location, (size_t)PATH_MAX);
+       
+       strlcat(__stack_log_file_path__, stack_log_file_base_name, (size_t)PATH_MAX);
+       append_int(__stack_log_file_path__, pid, (size_t)PATH_MAX);
        if (progname && progname[0] != '\0') {
-               strlcat(stack_log_location, ".", (size_t)PATH_MAX);
-               strlcat(stack_log_location, progname, (size_t)PATH_MAX);
+               strlcat(__stack_log_file_path__, ".", (size_t)PATH_MAX);
+               strlcat(__stack_log_file_path__, progname, (size_t)PATH_MAX);
+       }
+       if (!use_alternate_location) strlcat(__stack_log_file_path__, ".XXXXXX", (size_t)PATH_MAX);
+       strlcat(__stack_log_file_path__, stack_log_file_suffix, (size_t)PATH_MAX);
+       
+       // Securely create the log file.
+       if ((index_file_descriptor = mkstemps(__stack_log_file_path__, (int)strlen(stack_log_file_suffix))) != -1) {
+               _malloc_printf(ASL_LEVEL_INFO, "stack logs being written into %s\n", __stack_log_file_path__);
+               created_log_location = __stack_log_file_path__;
+       } else {
+               _malloc_printf(ASL_LEVEL_INFO, "unable to create stack logs at %s\n", stack_log_location);
+               if (use_alternate_location) delete_logging_file(stack_log_reference_file);
+               stack_log_reference_file[0] = '\0';
+               stack_log_location[0] = '\0';
+               __stack_log_file_path__[0] = '\0';
+               created_log_location = NULL;
+               return created_log_location;
        }
-       if (!use_alternate_location) strlcat(stack_log_location, ".XXXXXX", (size_t)PATH_MAX);
-       strlcat(stack_log_location, stack_log_file_suffix, (size_t)PATH_MAX);
        
        // in the case where the user has specified an alternate location, drop a reference file
        // in /tmp with the suffix 'stack_log_link_suffix' (".link") and save the path of the
        // stack logging file there.
+       bool use_alternate_link_location = false;
        if (use_alternate_location) {
                strlcpy(stack_log_reference_file, _PATH_TMP, (size_t)PATH_MAX);
+               if (access(stack_log_reference_file, W_OK) == -1) {
+                       strlcpy(stack_log_reference_file, stack_log_location, (size_t)PATH_MAX);
+                       use_alternate_link_location = true;
+               }
                strlcat(stack_log_reference_file, stack_log_file_base_name, (size_t)PATH_MAX);
                append_int(stack_log_reference_file, pid, (size_t)PATH_MAX);
                if (progname && progname[0] != '\0') {
                        strlcat(stack_log_reference_file, ".", (size_t)PATH_MAX);
                        strlcat(stack_log_reference_file, progname, (size_t)PATH_MAX);
                }
+               if (!use_alternate_link_location)
+               strlcat(stack_log_reference_file, ".XXXXXX", (size_t)PATH_MAX);
                strlcat(stack_log_reference_file, ".XXXXXX", (size_t)PATH_MAX);
                strlcat(stack_log_reference_file, stack_log_link_suffix, (size_t)PATH_MAX);
                
                int link_file_descriptor = mkstemps(stack_log_reference_file, (int)strlen(stack_log_link_suffix));
                if (link_file_descriptor == -1) {
-                       _malloc_printf(ASL_LEVEL_INFO, "unable to create stack reference file at %s\n", stack_log_location);
-                       return NULL;
+                       _malloc_printf(ASL_LEVEL_INFO, "unable to create stack reference file %s at %s\n",
+                               stack_log_reference_file, stack_log_location);
+               } else {
+                       ssize_t written = write(link_file_descriptor, __stack_log_file_path__, strlen(__stack_log_file_path__));
+                       if (written < (ssize_t)strlen(__stack_log_file_path__)) {
+                               _malloc_printf(ASL_LEVEL_INFO, "unable to write to stack reference file %s at %s\n",
+                                       stack_log_reference_file, stack_log_location);
+                       } else {
+                               const char *description_string = "\n(This is a reference file to the stack logs at the path above.)\n";
+                               write(link_file_descriptor, description_string, strlen(description_string));
                }
-               ssize_t written = write(link_file_descriptor, stack_log_location, strlen(stack_log_location));
-               if (written < (ssize_t)strlen(stack_log_location)) {
-                       _malloc_printf(ASL_LEVEL_INFO, "unable to write to stack reference file at %s\n", stack_log_location);
-                       return NULL;
                }
-               const char *description_string = "\n(This is a reference file to the stack logs at the path above.)\n";
-               write(link_file_descriptor, description_string, strlen(description_string));
                close(link_file_descriptor);
        }
-       
-       // Securely create the log file.
-       if ((index_file_descriptor = mkstemps(stack_log_location, (int)strlen(stack_log_file_suffix))) != -1) {
-               _malloc_printf(ASL_LEVEL_INFO, "stack logs being written into %s\n", stack_log_location);
-               created_log_location = stack_log_location;
-       } else {
-               _malloc_printf(ASL_LEVEL_INFO, "unable to create stack logs at %s\n", stack_log_location);
-               if (use_alternate_location) delete_logging_file(stack_log_reference_file);
-               stack_log_reference_file[0] = '\0';
-               stack_log_location[0] = '\0';
-               created_log_location = NULL;
+       if (use_alternate_link_location) {
+               _malloc_printf(ASL_LEVEL_INFO, "Please issue: cp %s %s\n", stack_log_reference_file, _PATH_TMP);
        }
        return created_log_location;
 }
@@ -517,12 +628,12 @@ delete_logging_file(char *log_location)
 static void
 delete_log_files(void)
 {
-       if (stack_log_location && stack_log_location[0]) {
-               if (delete_logging_file(stack_log_location) == 0) {
-                       _malloc_printf(ASL_LEVEL_INFO, "stack logs deleted from %s\n", stack_log_location);
-                       index_file_path[0] = '\0';
+       if (__stack_log_file_path__ && __stack_log_file_path__[0]) {
+               if (delete_logging_file(__stack_log_file_path__) == 0) {
+                       _malloc_printf(ASL_LEVEL_INFO, "stack logs deleted from %s\n", __stack_log_file_path__);
+                       __stack_log_file_path__[0] = '\0';
                } else {
-                       _malloc_printf(ASL_LEVEL_INFO, "unable to delete stack logs from %s\n", stack_log_location);
+                       _malloc_printf(ASL_LEVEL_INFO, "unable to delete stack logs from %s\n", __stack_log_file_path__);
                }
        }
        if (stack_log_reference_file && stack_log_reference_file[0]) {
@@ -629,7 +740,7 @@ robust_write(int fd, const void *buf, size_t nbyte) {
 
                // descriptor was closed on us. We need to reopen it
                if (fd == index_file_descriptor) {
-                       file_to_reopen = index_file_path;
+                       file_to_reopen = __stack_log_file_path__;
                        fd_to_reset = &index_file_descriptor;
                } else {
                        // We don't know about this file. Return (and abort()).
@@ -684,7 +795,8 @@ flush_data(void)
        while (remaining > 0) {
                written = robust_write(index_file_descriptor, p, remaining);
                if (written == -1) {
-                       _malloc_printf(ASL_LEVEL_INFO, "Unable to write to stack logging file %s (%s)\n", index_file_path, strerror(errno));
+                       _malloc_printf(ASL_LEVEL_INFO, "Unable to write to stack logging file %s (%s)\n",
+                               __stack_log_file_path__, strerror(errno));
                        disable_stack_logging();
                        return;
                }
@@ -723,12 +835,12 @@ prepare_to_log_stacks(void)
                pre_write_buffers = (stack_buffer_shared_memory*)mmap(0, full_shared_mem_size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, (off_t)0);
                close(shmid);
                
-               if (!pre_write_buffers) {
+               if (MAP_FAILED == pre_write_buffers) {
                        _malloc_printf(ASL_LEVEL_INFO, "error mapping in shared memory for disk-based stack logging output buffers\n");
                        disable_stack_logging();
                        return;
                }
-               
+
                // Store and use the buffer offsets in shared memory so that they can be accessed remotely
                pre_write_buffers->start_index_offset = 0ull;
                pre_write_buffers->next_free_index_buffer_offset = 0;
@@ -741,8 +853,9 @@ prepare_to_log_stacks(void)
                        disable_stack_logging();
                        return;
                }
-               
-               stack_buffer = (vm_address_t*)allocate_pages((uint64_t)round_page(sizeof(vm_address_t) * STACK_LOGGING_MAX_STACK_SIZE));
+
+               uint64_t stack_buffer_sz = (uint64_t)round_page(sizeof(vm_address_t) * STACK_LOGGING_MAX_STACK_SIZE);
+               stack_buffer = (vm_address_t*)allocate_pages(stack_buffer_sz);
                if (!stack_buffer) {
                        _malloc_printf(ASL_LEVEL_INFO, "error while allocating stack trace buffer\n");
                        disable_stack_logging();
@@ -752,10 +865,20 @@ prepare_to_log_stacks(void)
                // malloc() can be called by the following, so these need to be done outside the stack_logging_lock but after the buffers have been set up.
                atexit(delete_log_files);               // atexit() can call malloc()
                reap_orphaned_log_files(true);          // this calls opendir() which calls malloc()
-               
+
                // this call ensures that the log files exist; analyzing processes will rely on this assumption.
                if (create_log_file() == NULL) {
-                       disable_stack_logging();
+                       /* postponement support requires cleaning up these structures now */
+                       __destroy_uniquing_table(pre_write_buffers->uniquing_table);
+                       deallocate_pages(stack_buffer, stack_buffer_sz);
+                       stack_buffer = NULL;
+
+                       munmap(pre_write_buffers, full_shared_mem_size);
+                       pre_write_buffers = NULL;
+
+                       if (!stack_logging_postponed) {
+                               disable_stack_logging();
+                       }
                        return;
                }
        }
@@ -764,7 +887,7 @@ prepare_to_log_stacks(void)
 void
 __disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr, uintptr_t size, uintptr_t ptr_arg, uintptr_t return_val, uint32_t num_hot_to_skip)
 {
-       if (!stack_logging_enable_logging) return;
+       if (!stack_logging_enable_logging || stack_logging_postponed) return;
        
        // check incoming data
        if (type_flags & stack_logging_type_alloc && type_flags & stack_logging_type_dealloc) {
@@ -796,7 +919,8 @@ __disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr, uintptr_
        prepare_to_log_stacks();
 
        // since there could have been a fatal (to stack logging) error such as the log files not being created, check this variable before continuing
-       if (!stack_logging_enable_logging) return;
+       if (!stack_logging_enable_logging || stack_logging_postponed) return;
+
        vm_address_t self_thread = (vm_address_t)pthread_self();        // use pthread_self() rather than mach_thread_self() to avoid system call
        
        // lock and enter
@@ -891,8 +1015,14 @@ __stack_logging_fork_child() {
        OSSpinLockUnlock(&stack_logging_lock);
 }
 
+void
+__stack_logging_early_finished() {
+       stack_logging_finished_init = 1;
+       stack_logging_postponed = 0;
+}
+
 boolean_t
-__stack_logging_locked() 
+__stack_logging_locked()
 {
        bool acquired_lock = OSSpinLockTry(&stack_logging_lock);
        if (acquired_lock) OSSpinLockUnlock(&stack_logging_lock);
@@ -1042,7 +1172,7 @@ update_cache_for_file_streams(remote_task_file_streams *descriptors)
                        close(shmid);
                }
                
-               if (shmid < 0 || cache->shmem == NULL) {
+               if (shmid < 0 || cache->shmem == MAP_FAILED) {
                        // failed to connect to the shared memory region; warn and continue.
                        _malloc_printf(ASL_LEVEL_INFO, "warning: unable to connect to remote process' shared memory; allocation histories may not be up-to-date.\n");
                }
@@ -1084,7 +1214,7 @@ update_cache_for_file_streams(remote_task_file_streams *descriptors)
        }
        
        // if a snapshot is necessary, memcpy from remote frozen process' memory 
-       // note: there were two ways to do this ‚Äì spin lock or suspend. suspend allows us to
+       // note: there were two ways to do this - spin lock or suspend. suspend allows us to
        // analyze processes even if they were artificially suspended. with a lock, there'd be
        // worry that the target was suspended with the lock taken.
        if (update_snapshot) {
@@ -1203,8 +1333,10 @@ destroy_cache_for_file_streams(remote_task_file_streams *descriptors)
 // In the stack log analysis process, find the stack logging files for target process <pid>
 // by scanning the temporary directory for directory entries with names of the form "stack-logs.<pid>."
 // If we find such a directory then open the stack logging files in there.
+// We might also have been passed the file path if the client first read it from __stack_log_file_path__
+// global variable in the target task, as will be needed if the .link cannot be put in /tmp.
 static void
-open_log_files(pid_t pid, remote_task_file_streams *this_task_streams)
+open_log_files(pid_t pid, char* file_path, remote_task_file_streams *this_task_streams)
 {
        DIR *dp;
        struct dirent *entry;
@@ -1213,6 +1345,11 @@ open_log_files(pid_t pid, remote_task_file_streams *this_task_streams)
 
        reap_orphaned_log_files(false);         // reap any left-over log files (for non-existant processes, but not for this analysis process)
 
+       if (file_path != NULL) {
+               this_task_streams->index_file_stream = fopen(file_path, "r");
+               return;
+       }
+
        if ((dp = opendir(_PATH_TMP)) == NULL) {
                return;
        }
@@ -1239,7 +1376,7 @@ open_log_files(pid_t pid, remote_task_file_streams *this_task_streams)
 }      
 
 static remote_task_file_streams*
-retain_file_streams_for_task(task_t task)
+retain_file_streams_for_task(task_t task, char* file_path)
 {
        if (task == MACH_PORT_NULL) return NULL;
        
@@ -1280,7 +1417,7 @@ retain_file_streams_for_task(task_t task)
        
        remote_task_file_streams *this_task_streams = &remote_fds[next_remote_task_fd];
        
-       open_log_files(pid, this_task_streams);
+       open_log_files(pid, file_path, this_task_streams);
 
        // check if opens failed
        if (this_task_streams->index_file_stream == NULL) {
@@ -1330,10 +1467,25 @@ release_file_streams_for_task(task_t task)
 
 #pragma mark - extern
 
+//
+// The following is used by client tools like malloc_history and Instruments to pass along the path
+// of the index file as read from the target task's __stack_log_file_path__ variable (set in this file)
+// Eventually, at a suitable point, this additional argument should just be added to the other APIs below.
+//
+kern_return_t
+__mach_stack_logging_set_file_path(task_t task, char* file_path)
+{
+       remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, file_path);
+       if (remote_fd == NULL) {
+               return KERN_FAILURE;
+       }
+       return KERN_SUCCESS;
+}
+
 kern_return_t
 __mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count)
 {
-       remote_task_file_streams *remote_fd = retain_file_streams_for_task(task);
+       remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, NULL);
        if (remote_fd == NULL) {
                return KERN_FAILURE;
        }
@@ -1413,7 +1565,7 @@ __mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_
 kern_return_t
 __mach_stack_logging_enumerate_records(task_t task, mach_vm_address_t address, void enumerator(mach_stack_logging_record_t, void *), void *context)
 {
-       remote_task_file_streams *remote_fd = retain_file_streams_for_task(task);
+       remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, NULL);
        if (remote_fd == NULL) {
                return KERN_FAILURE;
        }
@@ -1496,7 +1648,7 @@ __mach_stack_logging_enumerate_records(task_t task, mach_vm_address_t address, v
 kern_return_t
 __mach_stack_logging_frames_for_uniqued_stack(task_t task, uint64_t stack_identifier, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count)
 {
-       remote_task_file_streams *remote_fd = retain_file_streams_for_task(task);
+       remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, NULL);
        if (remote_fd == NULL) return KERN_FAILURE;
 
        __unwind_stack_from_table_index(&remote_fd->cache->uniquing_table, stack_identifier, stack_frames_buffer, count, max_stack_frames);     
@@ -1528,9 +1680,9 @@ main()
   fprintf(stderr, "sizeof stack_log_file_base_name: %lu\n", sizeof(stack_log_file_base_name)); total_globals += sizeof(stack_log_file_base_name);
   fprintf(stderr, "sizeof stack_log_file_suffix: %lu\n", sizeof(stack_log_file_suffix)); total_globals += sizeof(stack_log_file_suffix);
   fprintf(stderr, "sizeof stack_log_link_suffix: %lu\n", sizeof(stack_log_link_suffix)); total_globals += sizeof(stack_log_link_suffix);
-  fprintf(stderr, "sizeof stack_log_location: %lu\n", sizeof(stack_log_location)); total_globals += sizeof(stack_log_location);
-  fprintf(stderr, "sizeof stack_log_reference_file: %lu\n", sizeof(stack_log_reference_file)); total_globals += sizeof(stack_log_reference_file);
-  fprintf(stderr, "sizeof index_file_path: %lu\n", sizeof(index_file_path)); total_globals += sizeof(index_file_path);
+  fprintf(stderr, "sizeof stack_log_location: %lu\n", (size_t)PATH_MAX); total_globals += (size_t)PATH_MAX;
+  fprintf(stderr, "sizeof stack_log_reference_file: %lu\n", (size_t)PATH_MAX); total_globals += (size_t)PATH_MAX;
+  fprintf(stderr, "sizeof __stack_log_file_path__ (index_file_path): %lu\n", (size_t)PATH_MAX); total_globals += (size_t)PATH_MAX;
   fprintf(stderr, "sizeof index_file_descriptor: %lu\n", sizeof(index_file_descriptor)); total_globals += sizeof(index_file_descriptor);
   fprintf(stderr, "sizeof remote_fds: %lu\n", sizeof(remote_fds)); total_globals += sizeof(remote_fds);
   fprintf(stderr, "sizeof next_remote_task_fd: %lu\n", sizeof(next_remote_task_fd)); total_globals += sizeof(next_remote_task_fd);