Skip to content

Commit

Permalink
Merging r366985:
Browse files Browse the repository at this point in the history
------------------------------------------------------------------------
r366985 | labath | 2019-07-25 08:38:33 +0200 (Thu, 25 Jul 2019) | 16 lines

LLGS: fix tracking execve on linux

Summary:
Due to a logic error, lldb-server ended up asserting/crashing every time
the debugged process attempted an execve(). This fixes the error, and
extends TestExec to work on other platforms too. The "extension"
consists of avoiding non-standard posix_spawn extensions and using the
classic execve() call, which should be available on any platform that
actually supports re-execing. I change the test decorator from
@skipUnlessDarwin to @skipIfWindows.

Reviewers: clayborg, jasonmolenda

Subscribers: lldb-commits

Differential Revision: https://reviews.llvm.org/D65207
------------------------------------------------------------------------

llvm-svn: 367128
  • Loading branch information
zmodem committed Jul 26, 2019
1 parent cb4f353 commit 8f23294
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 79 deletions.
Expand Up @@ -18,17 +18,17 @@ class ExecTestCase(TestBase):

mydir = TestBase.compute_mydir(__file__)

@skipUnlessDarwin
@expectedFailureAll(archs=['i386'], bugnumber="rdar://28656532")
@expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://problem/34559552") # this exec test has problems on ios systems
@skipIfSanitized # rdar://problem/43756823
@skipIfWindows
def test_hitting_exec (self):
self.do_test(False)

@skipUnlessDarwin
@expectedFailureAll(archs=['i386'], bugnumber="rdar://28656532")
@expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://problem/34559552") # this exec test has problems on ios systems
@skipIfSanitized # rdar://problem/43756823
@skipIfWindows
def test_skipping_exec (self):
self.do_test(True)

Expand Down
82 changes: 11 additions & 71 deletions lldb/packages/Python/lldbsuite/test/functionalities/exec/main.cpp
@@ -1,76 +1,16 @@
#include <errno.h>
#include <mach/mach.h>
#include <signal.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <spawn.h>
#include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <libgen.h>
#include <string>
#include <unistd.h>

static void
exit_with_errno (int err, const char *prefix)
{
if (err)
{
fprintf (stderr,
"%s%s",
prefix ? prefix : "",
strerror(err));
exit (err);
}
}

static pid_t
spawn_process (const char *progname,
const char **argv,
const char **envp,
int &err)
{
pid_t pid = 0;

const posix_spawn_file_actions_t *file_actions = NULL;
posix_spawnattr_t attr;
err = posix_spawnattr_init (&attr);
if (err)
return pid;

short flags = POSIX_SPAWN_SETEXEC | POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK;
err = posix_spawnattr_setflags (&attr, flags);
if (err == 0)
{
// Use the default signal masks
sigset_t no_signals;
sigset_t all_signals;
sigemptyset (&no_signals);
sigfillset (&all_signals);
posix_spawnattr_setsigmask(&attr, &no_signals);
posix_spawnattr_setsigdefault(&attr, &all_signals);

err = posix_spawn (&pid,
progname,
file_actions,
&attr,
(char * const *)argv,
(char * const *)envp);

posix_spawnattr_destroy(&attr);
}
return pid;
}

int
main (int argc, char const **argv)
{
char *buf = (char*) malloc (strlen (argv[0]) + 12);
strlcpy (buf, argv[0], strlen (argv[0]) + 1);
std::string directory_name (::dirname (buf));
int main(int argc, char const **argv) {
char *buf = strdup(argv[0]); // Set breakpoint 1 here
std::string directory_name(::dirname(buf));

std::string other_program = directory_name + "/secondprog";
int err = 0; // Set breakpoint 1 here
spawn_process (other_program.c_str(), argv, NULL, err);
if (err)
exit_with_errno (err, "posix_spawn x86_64 error");
return 0;
std::string other_program = directory_name + "/secondprog";
execve(other_program.c_str(), const_cast<char *const *>(argv), nullptr);
perror("execve");
abort();
}
9 changes: 3 additions & 6 deletions lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
Expand Up @@ -599,12 +599,9 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
// which only copies the main thread.
LLDB_LOG(log, "exec received, stop tracking all but main thread");

for (auto i = m_threads.begin(); i != m_threads.end();) {
if ((*i)->GetID() == GetID())
i = m_threads.erase(i);
else
++i;
}
llvm::erase_if(m_threads, [&](std::unique_ptr<NativeThreadProtocol> &t) {
return t->GetID() != GetID();
});
assert(m_threads.size() == 1);
auto *main_thread = static_cast<NativeThreadLinux *>(m_threads[0].get());

Expand Down

0 comments on commit 8f23294

Please sign in to comment.