Beispiel #1
0
    virtual void SetUp() {
        // Compute link filename.
        wchar_t temp_dir[MAX_PATH];
        int len = GetTempPathW(BUFFER_SIZE_ELEMENTS(temp_dir), temp_dir);
        // GetTempPathW sometimes gives an 8.3 path, so canonicalize into a long
        // path.
        wchar_t long_dir[MAX_PATH];
        len = GetLongPathNameW(temp_dir, long_dir, BUFFER_SIZE_ELEMENTS(long_dir));
        EXPECT_NE(0, len) << "GetLongPathNameW failed: "
                          << GetLastError() << '\n';
        link_path_.clear();
        link_path_ += long_dir;  // Documented to end in trailing slash.
        link_path_ += kTempLinkName;

        // Create a text file.
        file_path_.clear();
        file_path_ += long_dir;  // Documented to end in trailing slash.
        file_path_ += kTempFileName;
        std::wofstream file;
        file.open(file_path_.c_str());
        file << L"File contents\r\n";
        file.close();

        // Initialize COM.
        HRESULT hr = CoInitialize(NULL);
        EXPECT_TRUE(SUCCEEDED(hr));
    }
Beispiel #2
0
drfront_status_t
drfront_get_app_full_path(const char *app, OUT char *buf, size_t buflen/*# elements*/)
{
    TCHAR wbuf[MAX_PATH];
    TCHAR wapp[MAX_PATH];
    drfront_status_t status_check = DRFRONT_ERROR;
    bool is_dir = false;

    status_check = drfront_char_to_tchar(app, wapp, BUFFER_SIZE_ELEMENTS(wapp));
    if (status_check != DRFRONT_SUCCESS)
        return status_check;
    _tsearchenv(wapp, _T("PATH"), wbuf);
    NULL_TERMINATE_BUFFER(wbuf);
    status_check = drfront_tchar_to_char(wbuf, buf, buflen);
    if (status_check != DRFRONT_SUCCESS)
        return status_check;
    if (wbuf[0] == _T('\0') ||
        /* DrM-i#1617: we might have a same-name directory on the path */
        (drfront_dir_exists(buf, &is_dir) == DRFRONT_SUCCESS && is_dir)) {
        /* may need to append .exe, FIXME : other executable types */
        TCHAR tmp_buf[MAX_PATH];
        _sntprintf(tmp_buf, BUFFER_SIZE_ELEMENTS(tmp_buf), _T("%s%s"), wapp, _T(".exe"));
        NULL_TERMINATE_BUFFER(wbuf);
        _tsearchenv(tmp_buf, _T("PATH"), wbuf);
    }
    if (wbuf[0] == _T('\0')) {
        /* last try: expand w/ cur dir */
        GetFullPathName(wapp, BUFFER_SIZE_ELEMENTS(wbuf), wbuf, NULL);
        NULL_TERMINATE_BUFFER(wbuf);
    }
    status_check = drfront_tchar_to_char(wbuf, buf, buflen);
    return status_check;
}
Beispiel #3
0
/* Implements a normal path search for fname on the paths in env_var. Resolves symlinks,
 * which is needed to get the right config filename (i#1062).
 */
drfront_status_t
drfront_searchenv(const char *fname, const char *env_var, OUT char *full_path,
                  const size_t full_path_size, OUT bool *ret)
{
    drfront_status_t status_check = DRFRONT_ERROR;
    size_t size_needed = 0;
    TCHAR wfname[MAX_PATH];
    /* XXX: Not sure what the size for environment variable names should be.
     *      Perhaps we want a drfront_char_to_tchar_size_needed
     */
    TCHAR wenv_var[MAX_PATH];
    TCHAR wfull_path[MAX_PATH];

    if (full_path == NULL && ret == NULL)
        return DRFRONT_ERROR_INVALID_PARAMETER;

    status_check = drfront_char_to_tchar(fname, wfname, BUFFER_SIZE_ELEMENTS(wfname));
    if (status_check != DRFRONT_SUCCESS) {
        *ret = false;
        return status_check;
    }
    status_check = drfront_char_to_tchar(env_var, wenv_var,
                                         BUFFER_SIZE_ELEMENTS(wenv_var));
    if (status_check != DRFRONT_SUCCESS) {
        *ret = false;
        return status_check;
    }

    _wsearchenv(wfname, wenv_var, wfull_path);

    if (wfull_path[0] == L'\0') {
        *ret = false;
        return DRFRONT_ERROR;
    }

    status_check = drfront_tchar_to_char_size_needed(wfull_path, &size_needed);
    if (status_check != DRFRONT_SUCCESS) {
        *ret = false;
        return status_check;
    } else if (full_path_size < size_needed) {
        *ret = true;
        return DRFRONT_ERROR_INVALID_SIZE;
    }

    status_check = drfront_tchar_to_char(wfull_path, full_path, full_path_size);
    if (status_check != DRFRONT_SUCCESS) {
        *ret = false;
        return status_check;
    }
    full_path[full_path_size - 1] = '\0';
    *ret = true;
    return DRFRONT_SUCCESS;
}
Beispiel #4
0
drcovlib_status_t
drcovlib_init(drcovlib_options_t *ops)
{
    int count = dr_atomic_add32_return_sum(&drcovlib_init_count, 1);
    if (count > 1)
        return DRCOVLIB_SUCCESS;

    if (ops->struct_size != sizeof(options))
        return DRCOVLIB_ERROR_INVALID_PARAMETER;
    if ((ops->flags & (~(DRCOVLIB_DUMP_AS_TEXT|DRCOVLIB_THREAD_PRIVATE))) != 0)
        return DRCOVLIB_ERROR_INVALID_PARAMETER;
    if (TEST(DRCOVLIB_THREAD_PRIVATE, ops->flags)) {
        if (!dr_using_all_private_caches())
            return DRCOVLIB_ERROR_INVALID_SETUP;
        drcov_per_thread = true;
    }
    options = *ops;
    if (options.logdir != NULL)
        dr_snprintf(logdir, BUFFER_SIZE_ELEMENTS(logdir), "%s", ops->logdir);
    else /* default */
        dr_snprintf(logdir, BUFFER_SIZE_ELEMENTS(logdir), ".");
    NULL_TERMINATE_BUFFER(logdir);
    options.logdir = logdir;
    if (options.native_until_thread > 0)
        go_native = true;

    drmgr_init();
    drx_init();

    /* We follow a simple model of the caller requesting the coverage dump,
     * either via calling the exit routine, using its own soft_kills nudge, or
     * an explicit dump call for unusual cases.  This means that drx's
     * soft_kills remains inside the outer later, i.e., the drcov client.  This
     * is the easiest approach for coordinating soft_kills among many libraries.
     * Thus, we do *not* register for an exit event here.
     */

    drmgr_register_thread_init_event(event_thread_init);
    drmgr_register_thread_exit_event(event_thread_exit);
    drmgr_register_bb_instrumentation_event(event_basic_block_analysis, NULL, NULL);
    dr_register_filter_syscall_event(event_filter_syscall);
    drmgr_register_pre_syscall_event(event_pre_syscall);
#ifdef UNIX
    dr_register_fork_init_event(event_fork);
#endif

    tls_idx = drmgr_register_tls_field();
    if (tls_idx == -1)
        return DRCOVLIB_ERROR;

    return event_init();
}
Beispiel #5
0
static void
generate_process_name(process_info_t *pi, WCHAR *name_buf /* OUT */,
                      uint name_buf_length /* elements */)
{
    WCHAR qual_name[MAX_CMDLINE];
    WCHAR qual_args[MAX_CMDLINE];
    int res;
    BOOL use_args = FALSE;

    /* hack: we assume only need qualified names for these hardcoded apps
     * FIXME: read registry to see whether need qualification
     */
    if (wcsicmp(pi->ProcessName, L"svchost.exe") == 0 ||
        wcsicmp(pi->ProcessName, L"msiexec.exe") == 0 ||
        wcsicmp(pi->ProcessName, L"tomcat.exe") == 0 ||
        wcsicmp(pi->ProcessName, L"dllhost.exe") == 0) {
        /* use qualified names */
        res = get_process_cmdline(pi->ProcessID, qual_name,
                                  BUFFER_SIZE_ELEMENTS(qual_name));
        NULL_TERMINATE_BUFFER(qual_name);
        if (res == ERROR_SUCCESS) {
            if (get_commandline_qualifier(qual_name, qual_args,
                                          BUFFER_SIZE_ELEMENTS(qual_args),
                                          /* hack: we assume we only strip svchost,
                                           * and we also strip dllhost here to
                                           * fit more of the GUI in and avoid the
                                           * "Processid" string.
                                           * FIXME: read from registry.
                                           */
                                          (wcsicmp(pi->ProcessName, L"svchost.exe") != 0 &&
                                           wcsicmp(pi->ProcessName, L"dllhost.exe") != 0))) {
                NULL_TERMINATE_BUFFER(qual_args);
                use_args = TRUE;
            } /* else not an error, just no args. e.g.: plain sqlservr.exe */
        } else {
            /* this is an error => notify user */
            _snwprintf(qual_args, BUFFER_SIZE_ELEMENTS(qual_args), L"<error>");
            NULL_TERMINATE_BUFFER(qual_args);
            use_args = TRUE;
        }
    }
    if (use_args) {
        _snwprintf(name_buf, name_buf_length, L"%s-%s",
                   pi->ProcessName, qual_args);
    } else {
        _snwprintf(name_buf, name_buf_length, L"%s", pi->ProcessName);
    }
    NULL_TERMINATE_SIZED_BUFFER(name_buf, name_buf_length);
}
Beispiel #6
0
static bool
configure_application(char *app_name, char **app_argv,
                      std::string tracer_ops, void **inject_data)
{
    int errcode;
    char *process;
    process_id_t pid;

#ifdef UNIX
    errcode = dr_inject_prepare_to_exec(app_name, (const char **)app_argv, inject_data);
#else
    errcode = dr_inject_process_create(app_name, (const char **)app_argv, inject_data);
#endif
    if (errcode != 0 && errcode != WARN_IMAGE_MACHINE_TYPE_MISMATCH_EXE) {
        std::string msg =
            std::string("failed to create process for \"") + app_name + "\"";
#ifdef WINDOWS
        char buf[MAXIMUM_PATH];
        int sofar = _snprintf(buf, BUFFER_SIZE_ELEMENTS(buf), "%s", msg.c_str());
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                      NULL, errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                      (LPTSTR) buf + sofar,
                      BUFFER_SIZE_ELEMENTS(buf) - sofar*sizeof(char), NULL);
#endif
        FATAL_ERROR("%s", msg.c_str());
    }

    pid = dr_inject_get_process_id(*inject_data);

    process = dr_inject_get_image_name(*inject_data);
    NOTIFY(1, "INFO", "configuring %s pid=%d dr_ops=\"%s\"", process, pid,
           op_dr_ops.get_value().c_str());
    if (dr_register_process(process, pid,
                            false/*local*/, op_dr_root.get_value().c_str(),
                            DR_MODE_CODE_MANIPULATION,
                            op_dr_debug.get_value(), DR_PLATFORM_DEFAULT,
                            op_dr_ops.get_value().c_str()) != DR_SUCCESS) {
        FATAL_ERROR("failed to register DynamoRIO configuration");
    }
    NOTIFY(1, "INFO", "configuring client \"%s\" ops=\"%s\"",
           op_tracer.get_value().c_str(), tracer_ops.c_str());
    if (dr_register_client(process, pid,
                           false/*local*/, DR_PLATFORM_DEFAULT, CLIENT_ID,
                           0, op_tracer.get_value().c_str(),
                           tracer_ops.c_str()) != DR_SUCCESS) {
        FATAL_ERROR("failed to register DynamoRIO client configuration");
    }
    return true;
}
Beispiel #7
0
drfront_status_t
drfront_get_env_var(const char *name, OUT char *buf, size_t buflen/*# elements*/)
{
    TCHAR wbuf[MAX_PATH];
    /* XXX: Not sure what the size for environment variable names should be. */
    TCHAR wname[MAX_PATH];
    drfront_status_t res =
        drfront_char_to_tchar(name, wname, BUFFER_SIZE_ELEMENTS(wname));
    if (res != DRFRONT_SUCCESS)
        return res;
    if (GetEnvironmentVariable(wname, wbuf, BUFFER_SIZE_ELEMENTS(wbuf)) > 0) {
        return drfront_tchar_to_char(wbuf, buf, buflen);
    }
    return DRFRONT_ERROR;
}
Beispiel #8
0
void
symcache_init(const char *symcache_dir_in,
              size_t modsize_cache_threshold)
{
    initialized = true;

    op_modsize_cache_threshold = modsize_cache_threshold;

    hashtable_init_ex(&symcache_table, SYMCACHE_MASTER_TABLE_HASH_BITS,
                      IF_WINDOWS_ELSE(HASH_STRING_NOCASE, HASH_STRING),
                      true/*strdup*/, false/*!synch*/,
                      symcache_free_entry, NULL, NULL);
    symcache_lock = dr_mutex_create();

    dr_snprintf(symcache_dir, BUFFER_SIZE_ELEMENTS(symcache_dir), 
                "%s", symcache_dir_in);
    NULL_TERMINATE_BUFFER(symcache_dir);
    if (!dr_directory_exists(symcache_dir)) {
        if (!dr_create_dir(symcache_dir)) {
            /* check again in case of a race (i#616) */
            if (!dr_directory_exists(symcache_dir)) {
                NOTIFY_ERROR("Unable to create symcache dir %s"NL, symcache_dir);
                ASSERT(false, "unable to create symcache dir");
                dr_abort();
            }
        }
    }
}
Beispiel #9
0
static void
wrap_pre_SSL_write(void *wrapcxt, OUT void **user_data)
{
    /* int SSL_write(SSL *ssl, const void *buf, int num);
     *
     * ssize_t gnutls_record_send(gnutls_session_t session,
     *                            const void * data, size_t sizeofdata);
     */

    void *ssl = (void *)drwrap_get_arg(wrapcxt, 0);
    unsigned char *buf = (unsigned char *)drwrap_get_arg(wrapcxt, 1);
    size_t sz = (size_t)drwrap_get_arg(wrapcxt, 2);

    /* By generating unique filenames (per SSL context), we are able to
     * simplify logging of SSL traffic (no file locking is required).
     */
    char filename[MAXIMUM_PATH] = { 0 };
    dr_snprintf(filename, BUFFER_SIZE_ELEMENTS(filename), "trace-%x.write", ssl);
    NULL_TERMINATE_BUFFER(filename);
    FILE *fp = fopen(filename, "ab+");
    /* Error handling of logging operations isn't critical - in fact, we don't
     * even know what to do in such error conditions, so we simply return!
     */
    if (!fp) {
        dr_fprintf(STDERR, "Couldn’t open the output file %s\n", filename);
        return;
    }

    /* We assume that SSL_write always succeeds and writes the whole buffer. */
    fwrite(buf, 1, sz, fp);
    fclose(fp);
}
Beispiel #10
0
drfront_status_t
drfront_dir_try_writable(const char *path, OUT bool *is_writable)
{
    /* It would be convenient to use O_TMPFILE but not all filesystems support it */
    int fd;
    char tmpname[PATH_MAX];
    /* We actually don't care about races w/ other threads or processes running
     * this same code: each syscall should succeed and truncate whatever is there.
     */
#   define TMP_FILE_NAME ".__drfrontendlib_tmp"
    if (is_writable == NULL)
        return DRFRONT_ERROR_INVALID_PARAMETER;
    snprintf(tmpname, BUFFER_SIZE_ELEMENTS(tmpname), "%s/%s", path, TMP_FILE_NAME);
    NULL_TERMINATE_BUFFER(tmpname);
    fd = creat(tmpname, S_IRUSR | S_IWUSR);
    if (fd == -1) {
        drfront_status_t res;
        bool is_dir;
        *is_writable = false;
        res = drfront_dir_exists(path, &is_dir);
        if (res != DRFRONT_SUCCESS)
            return res;
        if (!is_dir)
            return DRFRONT_ERROR_INVALID_PATH;
    } else {
        *is_writable = true;
        close(fd);
        unlink(tmpname);
    }
    return DRFRONT_SUCCESS;
}
Beispiel #11
0
static void
test_x86_mode(void *dc)
{
    byte *pc, *end;
    instr_t *instr;

    /* create instr that looks different in x86 vs x64 */
    instr = INSTR_CREATE_add(dc, opnd_create_reg(REG_RAX), OPND_CREATE_INT32(42));
    end = instr_encode(dc, instr, buf);
    ASSERT(end - buf < BUFFER_SIZE_ELEMENTS(buf));

    /* read back in */
    set_x86_mode(dc, false/*64-bit*/);
    instr_reset(dc, instr);
    pc = decode(dc, buf, instr);
    ASSERT(pc != NULL);
    ASSERT(instr_get_opcode(instr) == OP_add);

    /* now interpret as 32-bit where rex will be an inc */
    set_x86_mode(dc, true/*32-bit*/);
    instr_reset(dc, instr);
    pc = decode(dc, buf, instr);
    ASSERT(pc != NULL);
    ASSERT(instr_get_opcode(instr) == OP_dec);

    instr_free(dc, instr);
    set_x86_mode(dc, false/*64-bit*/);
}
Beispiel #12
0
static void
log_file_create(void *drcontext, per_thread_t *data)
{
    data->log = log_file_create_helper(drcontext, drcontext == NULL ?
                                       "proc.log" : "thd.log", data->logname,
                                       BUFFER_SIZE_ELEMENTS(data->logname));
}
Beispiel #13
0
static void
print_mem_stats(process_info_t *pi, char reschar, int version)
{
    WCHAR qual_name[MAX_CMDLINE];
    int cpu = -1, user = -1;
    LONGLONG wallclock_time = get_system_time() - pi->CreateTime.QuadPart;
    LONGLONG scheduled_time = pi->UserTime.QuadPart + pi->KernelTime.QuadPart;
    static LONGLONG firstproc_time = 0;
    if (wallclock_time != (LONGLONG) 0) {
        cpu = (int) ((100 * scheduled_time) / wallclock_time);
    }
    if (scheduled_time != (LONGLONG) 0) {
        user = (int) ((100 * pi->UserTime.QuadPart) / scheduled_time);
    }

    /* Total user and kernel time scheduled for all processes.  Don't include idle
     * process, and if -skip option is specified don't include DRview.exe */
    if (wcsicmp(pi->ProcessName, L"") != 0
        && (wcsicmp(pi->ProcessName, L"drview.exe") != 0 || !skip)) {
        total_user   += pi->UserTime.QuadPart;
        total_kernel += pi->KernelTime.QuadPart;
    }

    /* CreateTime.QuadPart is a counter since 1916.  Both idle process and
     * System have create time of 0, so report create time, in ms, relative to
     * smss.exe */
    if (wcsicmp(pi->ProcessName, L"") == 0
        || wcsicmp(pi->ProcessName, L"system") == 0
        || wcsicmp(pi->ProcessName, L"smss.exe") == 0) {
        firstproc_time = pi->CreateTime.QuadPart;
    }

    generate_process_name(pi, qual_name, BUFFER_SIZE_ELEMENTS(qual_name));

    /* single line best so can line up columns and process output easily */
    fprintf(fp, "%-23.23S %5d %c %5d %2d%% %3d%% %5d %3d %7d %7d %8d %7d %7d %7d %7d %5d %5d %5d %5d %5d",
            qual_name, pi->ProcessID, reschar, version,
            cpu, user,
            pi->HandleCount, pi->ThreadCount,
            pi->VmCounters.PeakVirtualSize/1024,
            pi->VmCounters.VirtualSize/1024,
            pi->VmCounters.PeakPagefileUsage/1024,
            pi->VmCounters.PagefileUsage/1024, /* aka Private */
            pi->VmCounters.PeakWorkingSetSize/1024,
            pi->VmCounters.WorkingSetSize/1024,
            pi->VmCounters.PageFaultCount,
            pi->VmCounters.QuotaPeakPagedPoolUsage/1024,
            pi->VmCounters.QuotaPagedPoolUsage/1024,
            pi->VmCounters.QuotaPeakNonPagedPoolUsage/1024,
            pi->VmCounters.QuotaNonPagedPoolUsage/1024,
            pi->InheritedFromProcessID);
    if (showtime) {
        /* QuadPart is in ticks 1 tick = 100 nano secs. In ms = n * 100/(1000*1000) */
        fprintf(fp, " %15I64d %15I64d %15I64d",
                    (pi->UserTime.QuadPart/10000),
                    (pi->KernelTime.QuadPart/10000),
                    ((pi->CreateTime.QuadPart - firstproc_time)/10000));
    }
    fprintf(fp, "\n");
}
Beispiel #14
0
static void
process_symbols(void *dcontext, char *dllname, LOADED_IMAGE *img)
{
    /* We have to specify the module via "modname!symname".
     * We must use the same modname as in full_path.
     */
# define MAX_SYM_WITH_MOD_LEN 256
    char sym_with_mod[MAX_SYM_WITH_MOD_LEN];
    size_t modoffs;
    drsym_error_t symres;
    char *fname = NULL, *c;
    search_data_t sd;

    if (drsym_init(NULL) != DRSYM_SUCCESS) {
        print("WARNING: unable to initialize symbol engine\n");
        return;
    }

    if (dllname == NULL)
        return;
    for (c = dllname; *c != '\0'; c++) {
        if (*c == '/' || *c == '\\')
            fname = c + 1;
    }
    assert(fname != NULL && "unable to get fname for module");
    if (fname == NULL)
        return;
    /* now get rid of extension */
    for (; c > fname && *c != '.'; c--)
        ; /* nothing */

    assert(c - fname < BUFFER_SIZE_ELEMENTS(sym_with_mod) && "sizes way off");
    modoffs = dr_snprintf(sym_with_mod, c - fname, "%s", fname);
    assert(modoffs > 0 && "error printing modname!symname");
    modoffs = dr_snprintf(sym_with_mod + modoffs,
                          BUFFER_SIZE_ELEMENTS(sym_with_mod) - modoffs,
                          "!%s", SYM_PATTERN);
    assert(modoffs > 0 && "error printing modname!symname");

    sd.dcontext = dcontext;
    sd.img = img;
    verbose_print("Searching \"%s\" for \"%s\"\n", dllname, sym_with_mod);
    symres = drsym_search_symbols(dllname, sym_with_mod, true, search_syms_cb, &sd);
    if (symres != DRSYM_SUCCESS)
        print("Error %d searching \"%s\" for \"%s\"\n", dllname, sym_with_mod);
    drsym_exit();
}
Beispiel #15
0
void
display_error(char *msg)
{
    wchar_t buf[512];
    _snwprintf(buf, BUFFER_SIZE_ELEMENTS(buf), L"%hs", msg);
    NULL_TERMINATE_BUFFER(buf);
    display_error_helper(buf);
}
Beispiel #16
0
/* Implements a normal path search for fname on the paths in env_var.
 * Resolves symlinks, which is needed to get the right config filename (i#1062).
 */
drfront_status_t
drfront_searchenv(const char *fname, const char *env_var, OUT char *full_path,
                  const size_t full_path_size, OUT bool *ret)
{
    const char *paths = getenv(env_var);
    const char *cur;
    const char *next;
    const char *end;
    char tmp[full_path_size];
    char realpath_buf[PATH_MAX]; /* realpath hardcodes its buffer length */
    drfront_status_t status_check = DRFRONT_ERROR;
    bool access_ret = false;

    if (ret == NULL)
        return DRFRONT_ERROR_INVALID_PARAMETER;

    /* Windows searches the current directory first. */
    /* XXX: realpath resolves symlinks, which we may not want. */
    if (realpath(fname, realpath_buf) != NULL) {
        status_check = drfront_access(realpath_buf, DRFRONT_EXIST, &access_ret);
        if (status_check != DRFRONT_SUCCESS) {
            *ret = false;
            return status_check;
        } else if (access_ret == true) {
            *ret = true;
            snprintf(full_path, full_path_size, "%s", realpath_buf);
            full_path[full_path_size - 1] = '\0';
            return DRFRONT_SUCCESS;
        }
    }

    cur = paths;
    end = strchr(paths, '\0');
    while (cur < end) {
        next = strchr(cur, ':');
        next = (next == NULL ? end : next);
        snprintf(tmp, BUFFER_SIZE_ELEMENTS(tmp),
                 "%.*s/%s", (int)(next - cur), cur, fname);
        NULL_TERMINATE_BUFFER(tmp);
        /* realpath checks for existence too. */
        if (realpath(tmp, realpath_buf) != NULL) {
            status_check = drfront_access(realpath_buf, DRFRONT_EXIST, &access_ret);
            if (status_check != DRFRONT_SUCCESS) {
                *ret = false;
                return status_check;
            } else if (access_ret == true) {
                *ret = true;
                snprintf(full_path, full_path_size, "%s", realpath_buf);
                full_path[full_path_size - 1] = '\0';
                return DRFRONT_SUCCESS;
            }
        }
        cur = next + 1;
    }
    full_path[0] = '\0';
    *ret = false;
    return DRFRONT_ERROR;
}
Beispiel #17
0
uint CDynamoRIOView::PrintStat(TCHAR *c, uint i, BOOL filter)
{
    if (filter) {
#if 0
        // Filter out persisted cache stat for now
        // FIXME: have "show 0 values" checkbox
        // FIXME: need to count up stats that match filter and use that
        // for scrollbar max, else get flicker and empty space at bottom
        if (strncmp(m_stats->stats[i].name, "Persisted caches",
                    strlen("Persisted caches")) == 0)
            return 0;
#endif
    }
    return _stprintf(c, _T("%*.*") ASCII_PRINTF _T(" = ") DR_STAT_PFMT _T("\r\n"),
                     BUFFER_SIZE_ELEMENTS(m_stats->stats[i].name),
                     BUFFER_SIZE_ELEMENTS(m_stats->stats[i].name),
                     m_stats->stats[i].name, m_stats->stats[i].value);
}
/* XXX i#1440: share w/ Linux */
static bool
handle_strarray_access(sysarg_iter_info_t *ii, const sysinfo_arg_t *arg_info,
                       app_pc start, uint size)
{
    char id[16];
    dr_snprintf(id, BUFFER_SIZE_ELEMENTS(id), "%s%d", "parameter #", arg_info->param);
    NULL_TERMINATE_BUFFER(id);
    check_strarray(ii, (char **)start, arg_info->param, id);
    return true; /* check_strarray checks whole array */
}
Beispiel #19
0
static void
display_error_helper(wchar_t *msg)
{
    wchar_t title_buf[MAX_PATH + 64];
    _snwprintf(title_buf, BUFFER_SIZE_ELEMENTS(title_buf),
               L_PRODUCT_NAME L" Notice: %hs(%hs)", get_application_name(),
               get_application_pid());
    NULL_TERMINATE_BUFFER(title_buf);
    nt_messagebox(msg, title_buf);
}
Beispiel #20
0
int
main(int argc, char *argv[])
{
    /* Test reading the symlink via readlink */
    char proc[64];
    char buf[512];
    ssize_t res;
    snprintf(proc, BUFFER_SIZE_ELEMENTS(proc), "/proc/%d/exe", getpid());
    NULL_TERMINATE_BUFFER(proc);
    res = readlink(proc, buf, BUFFER_SIZE_ELEMENTS(buf));
    NULL_TERMINATE_BUFFER(buf);
    if (res > 0 && strrchr(buf, '/') != NULL)
        print("/proc/pid/exe points to %s\n", strrchr(buf, '/') + 1);
    else {
        perror("readlink failed");
        return 1;
    }
    /* XXX: another good test would be to make a thread and use /proc/tid/exe */

    /* Test executing the symlink via execve.
     * We invoked ourselves initially with an arg, to avoid repeated execs.
     */
    if (argc > 1) {
        pid_t child = fork();
        if (child < 0) {
            perror("fork failed");
        } else if (child > 0) {
            pid_t result = waitpid(child, NULL, 0);
            assert(result == child);
            print("child has exited\n");
        } else {
            const char *arg[2] = { proc, NULL };
            /* Update for child's pid */
            snprintf(proc, BUFFER_SIZE_ELEMENTS(proc), "/proc/%d/exe", getpid());
            NULL_TERMINATE_BUFFER(proc);
            res = execve(proc, (char **)arg, NULL /*env*/);
            if (res < 0)
                perror("execve failed");
        }
    }
    return 0;
}
Beispiel #21
0
drfront_status_t
drfront_get_absolute_path(const char *src, OUT char *buf, size_t buflen/*# elements*/)
{
    TCHAR wsrc[MAX_PATH];
    TCHAR wdst[MAX_PATH];
    drfront_status_t status_check = DRFRONT_ERROR;
    int res;

    status_check = drfront_char_to_tchar(src, wsrc, BUFFER_SIZE_ELEMENTS(wsrc));
    if (status_check != DRFRONT_SUCCESS)
        return status_check;

    res = GetFullPathName(wsrc, BUFFER_SIZE_ELEMENTS(wdst), wdst, NULL);
    if (res <= 0)
        return DRFRONT_ERROR;

    NULL_TERMINATE_BUFFER(wdst);
    status_check = drfront_tchar_to_char(wdst, buf, buflen);
    return status_check;
}
Beispiel #22
0
void
display_error(char *msg)
{
# ifdef DISABLED /* going with msgbox always! */
    fprintf(FP, msg);
# else
    wchar_t buf[512];
    _snwprintf(buf, BUFFER_SIZE_ELEMENTS(buf), L"%hs", msg);
    NULL_TERMINATE_BUFFER(buf);
    display_error_helper(buf);
# endif
}
/* i#200/PR 459481: communicate child pid via file.
 * We don't need this on unix b/c we use exec.
 */
static void
write_pid_to_file(const char *pidfile, process_id_t pid)
{
    TCHAR wpidfile[MAXIMUM_PATH];
    HANDLE f;
    char_to_tchar(pidfile, wpidfile, BUFFER_SIZE_ELEMENTS(wpidfile));
    f = CreateFile(wpidfile, GENERIC_WRITE, FILE_SHARE_READ,
                          NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (f == INVALID_HANDLE_VALUE) {
        warn("cannot open %s: %d", pidfile, GetLastError());
    } else {
        char pidbuf[16];
        BOOL ok;
        DWORD written;
        _snprintf(pidbuf, BUFFER_SIZE_ELEMENTS(pidbuf), "%d\n", pid);
        NULL_TERMINATE_BUFFER(pidbuf);
        ok = WriteFile(f, pidbuf, (DWORD)strlen(pidbuf), &written, NULL);
        assert(ok && written == strlen(pidbuf));
        CloseHandle(f);
    }
}
Beispiel #24
0
static void
options_init(client_id_t id)
{
    const char *opstr = dr_get_options(id);
    const char *s;
    char token[OPTION_MAX_LENGTH];

    /* default values */
    dr_snprintf(options.logdir, BUFFER_SIZE_ELEMENTS(options.logdir), ".");

    for (s = dr_get_token(opstr, token, BUFFER_SIZE_ELEMENTS(token));
         s != NULL;
         s = dr_get_token(s, token, BUFFER_SIZE_ELEMENTS(token))) {
        if (strcmp(token, "-logdir") == 0) {
            s = dr_get_token(s, options.logdir,
                             BUFFER_SIZE_ELEMENTS(options.logdir));
            USAGE_CHECK(s != NULL, "missing logdir path");
        } else if (strcmp(token, "-verbose") == 0) {
            s = dr_get_token(s, token, BUFFER_SIZE_ELEMENTS(token));
            USAGE_CHECK(s != NULL, "missing -verbose number");
            if (s != NULL) {
                int res = dr_sscanf(token, "%u", &verbose);
                USAGE_CHECK(res == 1, "invalid -verbose number");
            }
        } else if (strcmp(token, "-symcache_path") == 0) {
            s = dr_get_token(s, options.sympath,
                             BUFFER_SIZE_ELEMENTS(options.sympath));
            USAGE_CHECK(s != NULL, "missing symcache dir path");
            ALERT(2, "<drstrace symbol source is %s>\n", options.sympath);
        } else {
            ALERT(0, "UNRECOGNIZED OPTION: \"%s\"\n", token);
            USAGE_CHECK(false, "invalid option");
        }
    }
}
Beispiel #25
0
void
drmemory_abort(void)
{
    if (op_pause_at_assert) {
        char buf[64];
        /* very useful to have the pid */
        dr_snprintf(buf, BUFFER_SIZE_ELEMENTS(buf),
                    "Dr. Memory is paused at an assert in pid=%d",
                    dr_get_process_id());
        wait_for_user(buf);
    }
    dr_abort();
}
Beispiel #26
0
drfront_status_t
drfront_set_client_symbol_search_path(const char *symdir, bool ignore_env,
                                      OUT char *symsrv_path, size_t symsrv_path_sz)
{
    char app_symsrv_path[MAX_SYMSRV_PATH];
    TCHAR wapp_symsrv_path[MAX_SYMSRV_PATH];
    char tmp_srv_path[MAX_SYMSRV_PATH];
    char tmp_symsrv_path[MAX_SYMSRV_PATH];
    char *cur;
    char *end;
    size_t sofar;
    ssize_t len;
    bool has_srv;
    bool dir_exists;
    bool has_ms_symsrv;
    drfront_status_t sc;
    static const char ms_symsrv[] = "http://msdl.microsoft.com/download/symbols";

    if (sym_set_path_func == NULL)
        return DRFRONT_ERROR_LIB_UNSUPPORTED;
    /* If the user set a non-empty _NT_SYMBOL_PATH, then we use that.
     * If not, we use symdir/symbols path and make sure it exists.
     */
    if (ignore_env ||
        drfront_get_env_var("_NT_SYMBOL_PATH", tmp_symsrv_path,
                            BUFFER_SIZE_ELEMENTS(tmp_symsrv_path)) != DRFRONT_SUCCESS ||
        strlen(tmp_symsrv_path) == 0) {
        char pdb_dir[MAXIMUM_PATH];
        _snprintf(pdb_dir, BUFFER_SIZE_ELEMENTS(pdb_dir), "%s/symbols", symdir);
        NULL_TERMINATE_BUFFER(pdb_dir);
        drfront_string_replace_character(pdb_dir, '/', '\\'); /* canonicalize */
        sc = drfront_create_dir(pdb_dir);
        if ((sc != DRFRONT_SUCCESS && sc != DRFRONT_ERROR_FILE_EXISTS) ||
            drfront_access(pdb_dir, DRFRONT_READ, &dir_exists) != DRFRONT_SUCCESS ||
            !dir_exists) {
            DO_DEBUG(DL_WARN,
                     printf("Failed to create directory for symbols: %s\n", pdb_dir);
                     );
Beispiel #27
0
LSTATUS
WINAPI
redirect_RegOpenKeyExA(
    __in HKEY hKey,
    __in_opt LPCSTR lpSubKey,
    __in_opt DWORD ulOptions,
    __in REGSAM samDesired,
    __out PHKEY phkResult
    )
{
    wchar_t *wkey;
    wchar_t wbuf[MAX_REG_KEY_NAME_LEN];
    int len;
    if (lpSubKey != NULL) {
        len = _snwprintf(wbuf, BUFFER_SIZE_ELEMENTS(wbuf), L"%hs", lpSubKey);
        if (len < 0 || len >= BUFFER_SIZE_ELEMENTS(wbuf))
            return ERROR_INVALID_PARAMETER;
        NULL_TERMINATE_BUFFER(wbuf); /* be paranoid */
        wkey = wbuf;
    } else
        wkey = NULL;
    return redirect_RegOpenKeyExW(hKey, wkey, ulOptions, samDesired, phkResult);
}
Beispiel #28
0
int
main(int argc, const char *argv[])
{
    /* We put the pid into the title so that tools/closewnd can target it
     * uniquely when run in a parallel test suite.
     * runall.cmake assumes this precise title.
     */
    char title[64];
    _snprintf_s(title, BUFFER_SIZE_BYTES(title), BUFFER_SIZE_ELEMENTS(title),
                "Infloop pid=%d", GetProcessId(GetCurrentProcess()));
    SetTimer(NULL, NULL, 180 * 1000 /*3 mins*/, TimerProc);
    MessageBoxA(NULL, "DynamoRIO test: will be auto-closed", title, MB_OK);
    print("MessageBox closed\n");
    return 0;
}
Beispiel #29
0
void
loader_init(void)
{
    uint i;
    privmod_t *mod;

    acquire_recursive_lock(&privload_lock);
    VMVECTOR_ALLOC_VECTOR(modlist_areas, GLOBAL_DCONTEXT,
                          VECTOR_SHARED | VECTOR_NEVER_MERGE
                          /* protected by privload_lock */
                          | VECTOR_NO_LOCK,
                          modlist_areas);
    /* os specific loader initialization prologue before finalize the load */
    os_loader_init_prologue();

    /* Process client libs we loaded early but did not finalize */
    for (i = 0; i < privmod_static_idx; i++) {
        /* Transfer to real list so we can do normal processing */
        char name_copy[MAXIMUM_PATH];
        mod = privload_insert(NULL,
                              privmod_static[i].base,
                              privmod_static[i].size,
                              privmod_static[i].name,
                              privmod_static[i].path);
        LOG(GLOBAL, LOG_LOADER, 1, "%s: processing imports for %s\n",
            __FUNCTION__, mod->name);
        /* save a copy for error msg, b/c mod will be unloaded (i#643) */
        snprintf(name_copy, BUFFER_SIZE_ELEMENTS(name_copy), "%s", mod->name);
        NULL_TERMINATE_BUFFER(name_copy);
        if (!privload_load_finalize(mod)) {
            mod = NULL; /* it's been unloaded! */
#ifdef CLIENT_INTERFACE
            SYSLOG(SYSLOG_ERROR, CLIENT_LIBRARY_UNLOADABLE, 5,
                   get_application_name(), get_application_pid(), name_copy,
                   "\n\tUnable to locate imports of client library");
#endif
            os_terminate(NULL, TERMINATE_PROCESS);
            ASSERT_NOT_REACHED();
        }
    }
    /* os specific loader initialization epilogue after finalize the load */
    os_loader_init_epilogue();
    /* FIXME i#338: call loader_thread_init here once get
     * loader_init called after dynamo_thread_init but in a way that
     * works with Windows
     */
    release_recursive_lock(&privload_lock);
}
Beispiel #30
0
void
internal_error(char *file, int line, char *expr)
{
#ifdef INTERNAL
#    define FILENAME_LENGTH L""
#else
    /* truncate file name to first character */
#    define FILENAME_LENGTH L".1"
#endif
    wchar_t buf[512];
    _snwprintf(buf, BUFFER_SIZE_ELEMENTS(buf),
               L"Preinject Error %" FILENAME_LENGTH L"hs:%d %hs\n", file, line, expr);
    NULL_TERMINATE_BUFFER(buf);
    display_error_helper(buf);
    TerminateProcess(GetCurrentProcess(), (uint)-1);
}