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)); }
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; }
/* 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; }
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(); }
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); }
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; }
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; }
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(); } } } }
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); }
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; }
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*/); }
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)); }
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"); }
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(); }
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); }
/* 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; }
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 */ }
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); }
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; }
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; }
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); } }
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"); } } }
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(); }
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); );
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); }
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; }
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); }
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); }