Sunday, May 26, 2013

Quote



( The INEXACT flag mandated by IEEE Standard 754 for Binary Floating–Point Arithmetic would, if MATLAB granted us access to that flag, help us discriminate between solutions x that are exactly right and those, perhaps arbitrarily wrong, whose residuals vanish by accident.) - http://www.eecs.berkeley.edu/~wkahan/ieee754status/baleful.pdf

Useful commands



leaks
heap
fs_usage
lsof
vm_stat
netstat
tcpdump
sc_usage
otool
xxd
pbcopy
pdfgrep
du -sh /private/var/vm/sleepimage

Friday, May 3, 2013

Not having to specify DYLD_LIBRARY_PATH for your app when using Intel TBB (on Darwin/Mac OS X)

When using Intel Threading Building Blocks,  you have to link against their dynamic library. They do not provide a way for static linking, because when dynamic linking is used, their library has a shared state and they use that to prevent contention from over-threading.

However, the only way they provide to load their library at run-time is by having to provide a path to their library (libtbb.dylib) through the
DYLD_LIBRARY_PATH environment variable. Before your application launches you are going to have to set it in the shell. They provide a handy script to do it for you too. It may be inconvenient but it is doable (especially in non-production environments like scientific experiments).

However, although Valgrind is able to load their library correctly (and therefore run your program), GDB (7.5) can not do it. I am not able to debug my program because GDB says it can not load libtbb and dies.

So I used my Google-fu and found a solution. Just run the following command in the tbb/lib directory:

$ install_name_tool -id /absolute/path/to/libtbb.dylib libtbb.dylib


There you go. The difference is that without doing it, LD linker only puts the library name in the binary. I.e., otool -L shows only libtbb.dylib, no path, no nothing. After the command, LD puts the absolute path, and therefore it gets encoded in the binary; no need for DYLD_LIBRARY_PATH again.

I found the useful information at https://dev.lsstcorp.org/trac/wiki/LinkingDarwin.

Tuesday, April 30, 2013

Segmentation fault

Getting a segmentation fault out of no where after a long execution can be frustrating. One reason is that you usually do not get any information on the source of error. Another reason is that using valgrind or gdb to debug will make the program run even slower until you hit the error, if you hit it again. Frustrating indeed. But not all hope lost. You can modify your program to catch the segmentation fault and generate the needed debugging information for you (only for POSIX-compliant operating systems – that is like every operating system in the world, except Windows).

Now when my program generates a segmentation fault that's what I get as output:

Segmentation fault: Address not mapped to object 
Invalid read of the address 0x0

Stack trace: 
 1: 0x103432c37 <attack_dataset int="" x2b7=""> (/Users/malaggan/Desktop/mac-only-ws/SVDAttack/jni/./svdattack)
 2: 0x103498f8b <main x9b=""> (/Users/malaggan/Desktop/mac-only-ws/SVDAttack/jni/./svdattack)

Line number: 
got symbolicator for svdattack, base address 100000000
attack_dataset(int) (in svdattack) (attack_dataset.cpp:104)

How it is done is fairly simple. When a segmentation fault happens, the operating system sends a signal to the program. The program, in turn, can handle this signal and act based on it, via a signal handler. The signal handler is a function that is called by the operating system, to which it also provide useful information for debugging (and a lot more, like user-space threading, and copy-on-write, and other things). The entire state of the machine, including its general registers, and floating point registers, are recorded and sent to the signal handler. The one register we are interested about is the instruction pointer register, which contains the address of the instruction which caused the segmentation fault. Along with that also goes the address that the program was trying to access, and whether the program was trying to read it or write it. The operating system also gives information about that address; whether it is a totally wrong address (not mapped in the program's address space), or a valid address but the program has no permission to read (or write) it.

The code I wrote to generate the message above goes next (the portion about the stack trace was taken from stackoverflow). It is written in C++11 and the machine-specific part is for Mac.


#include <sys/ucontext.h>
#include <dlfcn.h>
#include <cxxabi.h>
#include <unistd.h>


void print(int sig, siginfo_t *info, void *c)
{
    ucontext_t *context = reinterpret_cast<ucontext_t*>(c);

    // defined in mach/i386/_structs.h
    __darwin_mcontext64* mc = context->uc_mcontext;
    __darwin_x86_thread_state64* ss = &mc->__ss;
    __darwin_x86_exception_state64* es = &mc->__es;
    __darwin_x86_float_state64* fs = &mc->__fs;

    bool write_fault = (es->__err & 2) ? true : false;

    fprintf(stderr,"\n%s: %s \n"
        "Invalid %s of the address %p\n",
        sys_siglist[sig],
        (info->si_code == SEGV_MAPERR) ? "Address not mapped to object" : "Invalid permissions for mapped object",
        (write_fault)?"write":"read",
        es->__faultvaddr
    );

    // http://stackoverflow.com/questions/5397041/getting-the-saved-instruction-pointer-address-from-a-signal-handler
    void **ip = reinterpret_cast<void**>(ss->__rip);
    void **bp = reinterpret_cast<void**>(ss->__rbp);

    fprintf(stderr,"\nStack trace: \n");

    Dl_info dlinfo;
    int f = 0;
    while(bp && ip) 
    {
        if(!dladdr(ip, &dlinfo))
            break; 

        const char *symname = dlinfo.dli_sname;
 
        int status;
        char * tmp = abi::__cxa_demangle(symname, nullptr, 0, &status);

        if (status == 0 && tmp)
            symname = tmp;

        fprintf(stderr,"% 2d: %p <%s+0x%lx> (%s)\n",
                 ++f,
                 ip,
                 symname,
                 reinterpret_cast<unsigned long>>ip) - reinterpret_cast<unsigned long>(dlinfo.dli_saddr),
                 dlinfo.dli_fname);

        if (tmp)
            free(tmp);

        if(dlinfo.dli_sname && std::string(dlinfo.dli_sname) == "main")
            break;

        ip = reinterpret_cast<void**>(bp[1]);
        bp = reinterpret_cast<void**>(bp[0]);
    }

    fprintf(stderr,"\nLine number: \n"); 
    
    auto load_addr = dlinfo.dli_fbase;

    char str_pid[100]={0},
         str_rip[100]={0}, 
         str_load_addr[100]={0};

    sprintf(str_pid, "%d", getpid());
    sprintf(str_rip, "%p", ss->__rip);
    sprintf(str_load_addr, "%p", load_addr);

    char *argv[]={"atos","-o", "./svdattack", "-l", str_load_addr, str_rip, nullptr};
    char *envp[] = { nullptr };
    execve("/usr/bin/atos", argv, envp);

    fprintf(stderr,"\n\n");

    std::exit(1);
}



/*this is how the signal was registered*/
struct sigaction sa;
sigemptyset (&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = print;

sigaction(SIGSEGV, &sa, nullptr);
sigaction(SIGBUS, &sa, nullptr);