Skip to content

Common Issues

Sengming edited this page Apr 23, 2019 · 1 revision

Common Issues

Here we'll document potential problems and solutions which don't warrant their own issues, in the hope it will be useful to others.

Segfault in the Migration Library Due to Executable Stack

When running an application compiled with the Popcorn Compiler on popcorn systems, upon migrating you may get a segmentation fault before exiting the migration library. Trace based on the page server's debug calls. Usually, the call will come from a pthread_get_migrate_args call. This call actually attempts to retrieve the TLS for a specific architecture from the Origin node. Looking in lib/migration/src/arch/<target_arch>/migrate_<target_arch>.s file you can see that the return from pthread_migrate_args is compared to zero and jumps to Lcrash if it is zero.

In some cases, this can occur because the stack and other VMAs on our binary were actually marked as executable and when attempted to be retrieved from the local binary and is treated as a .text section page, as shown in the code block below where vma->vm_flags & VM_EXEC is being checked. This resides in popcorn/page_server.c.

/**                                                                                                                                                                                                   
* Thread running at a remote                                                                                                                                                                         
*                                                                                                                                                                                                    
* Fault handling at the remote side is simpler than at the origin.                                                                                                                                   
* There will be no copy-on-write case at the remote since no thread                                                                                                                                  
* creation is allowed at the remote side.                                                                                                                                                            
*/                                                                                                                                                                                                   
if (pte_none(pte_val)) {                                                                                                                                                                              
/* Can we handle the fault locally? */                                                                                                                                                        
        if (vma->vm_flags & VM_EXEC) {                                                                                                                                                                
                PGPRINTK("  [%d] VM_EXEC. continue\n", current->pid);                                                                                                                                 
                ret = VM_FAULT_CONTINUE;                                                                                                                                                              
                goto out;                                                                                                                                                                             
        }                                                                                                                                                                                             
        if (!vma_is_anonymous(vma) &&                                                                                                                                                                 
               ((vma->vm_flags & (VM_WRITE | VM_SHARED)) == 0)) {                                                                                                                            
                PGPRINTK("  [%d] locally file-mapped read-only. continue\n",                                                                                                                          
                                         current->pid);                                                                                                                                                        
                ret = VM_FAULT_CONTINUE;                                                                                                                                                              
                goto out;                                                                                                                                                                             
        }                                                                                                                                                                                             }

The reason this might occur is because if the binary has been set to have an executable stack, it makes all other VMA's with the read permissions bit executable, as is seen in the code block below, taken from fs/binfmt_elf.c <<load_elf_binary>>

SET_PERSONALITY2(loc->elf_ex, &arch_state);
                                                                                                                                              
if (elf_read_implies_exec(loc->elf_ex, executable_stack)){                                                                                                                                            
        printk(KERN_ALERT "Personality of Elf says READ_IMPLIES_EXEC");                                                                                                                               
        current->personality |= READ_IMPLIES_EXEC;                                                                                                                                                    
}

To rectify this, during linking, please add -z noexecstack to the LDFLAGS.