Fix debugger to run debuggee with original environment variables ##debug (#17116)

* Change `fork_and_ptraceme` to start debuggee with rarun2 profile on Linux & Mac
* Add two new commands `doe` and `doe!` to show and edit rarun2 startup profile
* Fix `r_run_parse` to read last line
This commit is contained in:
Zi Fan 2020-07-24 01:25:55 -07:00 committed by GitHub
parent 2b38b2f03c
commit ac126508d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 76 additions and 106 deletions

View File

@ -296,6 +296,8 @@ static const char *help_msg_do[] = {
"Usage:", "do", " # Debug (re)open commands",
"do", "", "Open process (reload, alias for 'oo')",
"dor", " [rarun2]", "Comma separated list of k=v rarun2 profile options (e dbg.profile)",
"doe", "", "Show rarun2 startup profile",
"doe!", "", "Edit rarun2 startup profile with $EDITOR",
"doo", " [args]", "Reopen in debug mode with args (alias for 'ood')",
"doof", " [args]", "Reopen in debug mode from file (alias for 'oodf')",
"doc", "", "Close debug session",
@ -5383,6 +5385,26 @@ static int cmd_debug(void *data, const char *input) {
case '\0': // "do"
r_core_file_reopen (core, input[1] ? input + 2: NULL, 0, 1);
break;
case 'e': // "doe"
switch (input[2]) {
case '\0': // "doe"
if (core->io->envprofile) {
r_cons_println (core->io->envprofile);
}
break;
case '!': // "doe!"
{
char *out = r_core_editor (core, NULL, core->io->envprofile);
if (out) {
free (core->io->envprofile);
core->io->envprofile = out;
eprintf ("%s\n", core->io->envprofile);
}
} break;
default:
break;
}
break;
case 'r': // "dor" : rarun profile
if (input[2] == ' ') {
setRarunProfileString (core, input + 3);

View File

@ -100,6 +100,7 @@ typedef struct r_io_t {
RIOUndo undo;
SdbList *plugins;
char *runprofile;
char *envprofile;
#if USE_PTRACE_WRAP
struct ptrace_wrap_instance_t *ptrace_wrap;
#endif

View File

@ -34,6 +34,7 @@ R_API void r_sys_info_free(RSysInfo *si);
R_API int r_sys_sigaction(int *sig, void (*handler) (int));
R_API int r_sys_signal(int sig, void (*handler) (int));
R_API void r_sys_env_init(void);
R_API char **r_sys_get_environ(void);
R_API void r_sys_set_environ(char **e);
R_API ut64 r_sys_now(void);

View File

@ -267,6 +267,12 @@ static RRunProfile* _get_run_profile(RIO *io, int bits, char **argv) {
if (strstr (io->runprofile, R_SYS_DIR ".rarun2.")) {
(void)r_file_rm (io->runprofile);
}
} else if (io->envprofile) {
if (!r_run_parse (rp, io->envprofile)) {
eprintf ("Can't parse default rarun2 profile\n");
r_run_free (rp);
return NULL;
}
}
if (bits == 64) {
r_run_parseline (rp, expr=strdup ("bits=64"));
@ -299,7 +305,6 @@ static void handle_posix_redirection(RRunProfile *rp, posix_spawn_file_actions_t
// __UNIX__ (not windows)
static int fork_and_ptraceme_for_mac(RIO *io, int bits, const char *cmd) {
bool runprofile = io->runprofile && *(io->runprofile);
pid_t p = -1;
char **argv;
posix_spawn_file_actions_t fileActions;
@ -324,51 +329,6 @@ static int fork_and_ptraceme_for_mac(RIO *io, int bits, const char *cmd) {
ps_flags |= POSIX_SPAWN_CLOEXEC_DEFAULT;
ps_flags |= POSIX_SPAWN_START_SUSPENDED;
#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
if (!runprofile) {
int ret, useASLR = io->aslr;
char *_cmd = io->args
? r_str_appendf (strdup (cmd), " %s", io->args)
: strdup (cmd);
argv = r_str_argv (_cmd, NULL);
if (!argv) {
free (_cmd);
return -1;
}
if (!*argv) {
r_str_argv_free (argv);
free (_cmd);
eprintf ("Invalid execvp\n");
return -1;
}
if (useASLR != -1) {
if (!useASLR) {
ps_flags |= _POSIX_SPAWN_DISABLE_ASLR;
}
}
(void)posix_spawnattr_setflags (&attr, ps_flags);
#if __x86_64__
if (bits == 32) {
cpu = CPU_TYPE_I386;
// cpu |= CPU_ARCH_ABI64;
}
#endif
posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &copied);
{
char *dst = r_file_readlink (argv[0]);
if (dst) {
argv[0] = dst;
}
}
// XXX: this is a workaround to fix spawning programs with spaces in path
r_str_arg_unescape (argv[0]);
ret = posix_spawnp (&p, argv[0], &fileActions, &attr, argv, NULL);
handle_posix_error (ret);
posix_spawn_file_actions_destroy (&fileActions);
r_str_argv_free (argv);
free (_cmd);
return p;
}
int ret;
argv = r_str_argv (cmd, NULL);
if (!argv) {
@ -407,65 +367,34 @@ static int fork_and_ptraceme_for_mac(RIO *io, int bits, const char *cmd) {
typedef struct fork_child_data_t {
RIO *io;
int bits;
bool runprofile;
const char *cmd;
} fork_child_data;
static void fork_child_callback(void *user) {
fork_child_data *data = user;
if (data->runprofile) {
char **argv = r_str_argv (data->cmd, NULL);
if (!argv) {
exit (1);
}
RRunProfile *rp = _get_run_profile (data->io, data->bits, argv);
if (!rp) {
r_str_argv_free (argv);
exit (1);
}
trace_me ();
r_run_start (rp);
r_run_free (rp);
char **argv = r_str_argv (data->cmd, NULL);
if (!argv) {
exit (1);
}
r_sys_clearenv ();
RRunProfile *rp = _get_run_profile (data->io, data->bits, argv);
if (!rp) {
r_str_argv_free (argv);
exit (1);
} else {
char *_cmd = data->io->args ?
r_str_appendf (strdup (data->cmd), " %s", data->io->args) :
strdup (data->cmd);
trace_me ();
char **argv = r_str_argv (_cmd, NULL);
if (!argv) {
free (_cmd);
return;
}
if (argv && *argv) {
int i;
for (i = 3; i < 1024; i++) {
(void)close (i);
}
for (i = 0; argv[i]; i++) {
r_str_arg_unescape (argv[i]);
}
if (execvp (argv[0], argv) == -1) {
eprintf ("Could not execvp: %s\n", strerror (errno));
exit (MAGIC_EXIT);
}
} else {
eprintf ("Invalid execvp\n");
}
r_str_argv_free (argv);
free (_cmd);
}
trace_me ();
r_run_start (rp);
r_run_free (rp);
r_str_argv_free (argv);
exit (1);
}
static int fork_and_ptraceme_for_unix(RIO *io, int bits, const char *cmd) {
int ret, status, child_pid;
bool runprofile = io->runprofile && *(io->runprofile);
void *bed = NULL;
fork_child_data child_data;
child_data.io = io;
child_data.bits = bits;
child_data.runprofile = runprofile;
child_data.cmd = cmd;
child_pid = r_io_ptrace_fork (io, fork_child_callback, &child_data);
switch (child_pid) {

View File

@ -384,9 +384,17 @@ R_API int r_main_radare2(int argc, const char **argv) {
r_signal_sigmask (SIG_BLOCK, &sigBlockMask, NULL);
#endif
char **envp = r_sys_get_environ ();
if (envp) {
r_sys_set_environ (envp);
r_sys_env_init ();
// Create rarun2 profile with startup environ
char *envprofile = NULL;
char **e = r_sys_get_environ ();
if (e) {
RStrBuf *sb = r_strbuf_new (NULL);
while (e && *e) {
r_strbuf_appendf (sb, "setenv=%s\n", *e);
e++;
}
envprofile = r_strbuf_drain (sb);
}
if (r_sys_getenv_asbool ("R2_DEBUG")) {
@ -420,6 +428,8 @@ R_API int r_main_radare2(int argc, const char **argv) {
r->r_main_rasm2 = r_main_rasm2;
r->r_main_rax2 = r_main_rax2;
r->io->envprofile = envprofile;
r_core_task_sync_begin (&r->tasks);
if (argc == 2 && !strcmp (argv[1], "-p")) {
r_core_project_list (r, 0);

View File

@ -106,9 +106,13 @@ R_API bool r_run_parse(RRunProfile *pf, const char *profile) {
return false;
}
r_str_replace_char (str, '\r',0);
for (p = str; (o = strchr (p, '\n')); p = o) {
*o++ = 0;
p = str;
while (p) {
if ((o = strchr (p, '\n'))) {
*o++ = 0;
}
r_run_parseline (pf, p);
p = o;
}
free (str);
return true;
@ -379,13 +383,12 @@ static int handle_redirection_proc(const char *cmd, bool in, bool out, bool err)
}
static int handle_redirection(const char *cmd, bool in, bool out, bool err) {
r_return_val_if_fail (cmd, 0);
#if __APPLE__ && !__POWERPC__
//XXX handle this in other layer since things changes a little bit
//this seems like a really good place to refactor stuff
return 0;
#else
if (!*cmd) {
if (!cmd || !*cmd) {
return 0;
}
if (cmd[0] == '"') {
@ -1125,7 +1128,7 @@ R_API int r_run_start(RRunProfile *p) {
#if __UNIX__
// XXX HACK close all non-tty fds
{ int i;
for (i = 3; i < 10; i++) {
for (i = 3; i < 1024; i++) {
close (i);
}
}

View File

@ -371,14 +371,12 @@ R_API int r_sys_clearenv(void) {
#if __APPLE__ && !HAVE_ENVIRON
/* do nothing */
if (!env) {
env = r_sys_get_environ ();
r_sys_env_init ();
return 0;
}
if (env) {
char **e = env;
while (*e) {
*e++ = NULL;
}
char **e = env;
while (*e) {
*e++ = NULL;
}
#else
if (!environ) {
@ -1208,8 +1206,14 @@ R_API char *r_sys_pid_to_path(int pid) {
#endif
}
// TODO: rename to r_sys_env_init()
R_API char **r_sys_get_environ (void) {
R_API void r_sys_env_init(void) {
char **envp = r_sys_get_environ ();
if (envp) {
r_sys_set_environ (envp);
}
}
R_API char **r_sys_get_environ(void) {
#if __APPLE__ && !HAVE_ENVIRON
env = *_NSGetEnviron();
#else
@ -1222,7 +1226,7 @@ R_API char **r_sys_get_environ (void) {
return env;
}
R_API void r_sys_set_environ (char **e) {
R_API void r_sys_set_environ(char **e) {
env = e;
}