Skip to content

Can I call a Linux API from a Windows program? #3448

@thomassligon

Description

@thomassligon

Can I install WSL (but not Linux), and call a Unix/Posix/Linux command (such as backtrace) from a C++ Windows program?
Motivation: I am using a high-performance package for numerically solving differential equations (AMICI https://github.com/ICB-DCM/AMICI). Currently, it is a wrapper for Sundials/CVODES in MATLAB, but will also support Python in a future release. The C++ code makes a call to stacktrace when it runs on Linux or OSX, but skips it when it runs on Windows. Calling stacktrace on Windows/WSL would be a valuable addition to the Windows version. Some other alternatives look less attractive, including

  1. Running the Linux version on WSL on Windows would require users to run a completely different environment.
  2. Using StackWalk on Windows instead of stacktrace would require significant addition to the logic and appears to be rather complex (http://www.rioki.org/2017/01/09/windows_stacktrace.html). In contrast, using stacktrace on Windows would would make it easier for the developers to use other Posix APIs with ease and less maintenance overhead.
    Here is the code in question:
void storeBacktrace(const int nMaxFrames) {
    std::ostringstream trace_buf;
    
    #ifdef PLATFORM_WINDOWS
    
    trace_buf << "stacktrace not available on windows platforms\n";
    
    #else
    
    void *callstack[nMaxFrames];
    char buf[1024];
    int nFrames = backtrace(callstack, nMaxFrames);
    char **symbols = backtrace_symbols(callstack, nFrames);
    
    for (int i = 2; i < nFrames; i++) { // start at 2 to omit AmiException and storeBacktrace call
        Dl_info info;
        if (dladdr(callstack[i], &info) && info.dli_sname) {
            char *demangled = NULL;
            int status = -1;
            if (info.dli_sname[0] == '_')
                demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status);
            snprintf(buf, sizeof(buf), "%-3d %*p %s + %zd\n",
                     i-2, int(2 + sizeof(void*) * 2), callstack[i],
                     status == 0 ? demangled :
                     info.dli_sname == 0 ? symbols[i] : info.dli_sname,
                     (char *)callstack[i] - (char *)info.dli_saddr);
            free(demangled);
        } else {
            snprintf(buf, sizeof(buf), "%-3d %*p %s\n",
                     i-2, int(2 + sizeof(void*) * 2), callstack[i], symbols[i]);
        }
        trace_buf << buf;
    }
    free(symbols);
    if (nFrames == nMaxFrames)
        trace_buf << "[truncated]\n";
    
    #endif
    
    snprintf(trace, sizeof(trace), "%s", trace_buf.str().c_str());
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions