Details
Details
Diff Detail
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Skipped - Unit
Tests Skipped - Build Status
Buildable 73722 Build 70605: arc lint + arc unit
Event Timeline
Comment Actions
This is what I used to test the async exit changes.
/*-
* Copyright 2026 Konstantin Belousov <kib@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/ptrace.h>
#include <sys/syscall.h>
#include <sys/sysctl.h>
#include <sys/wait.h>
#include <assert.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static const char *
decode_wait_status(int status)
{
static char c[128];
char b[32];
int first;
c[0] = '\0';
first = 1;
if (WIFCONTINUED(status)) {
first = 0;
strlcat(c, "CONT", sizeof(c));
}
if (WIFEXITED(status)) {
if (first)
first = 0;
else
strlcat(c, ",", sizeof(c));
snprintf(b, sizeof(b), "EXIT(%d)", WEXITSTATUS(status));
strlcat(c, b, sizeof(c));
}
if (WIFSIGNALED(status)) {
if (first)
first = 0;
else
strlcat(c, ",", sizeof(c));
snprintf(b, sizeof(b), "SIG(%s)", strsignal(WTERMSIG(status)));
strlcat(c, b, sizeof(c));
if (WCOREDUMP(status))
strlcat(c, ",CORE", sizeof(c));
}
if (WIFSTOPPED(status)) {
if (first)
first = 0;
else
strlcat(c, ",", sizeof(c));
snprintf(b, sizeof(b), "SIG(%s)", strsignal(WSTOPSIG(status)));
strlcat(c, b, sizeof(c));
}
return (c);
}
int
main(void)
{
struct ptrace_sc_remote pscr;
syscallarg_t args[1];
int status;
pid_t pid;
if ((pid = fork()) < 0) {
perror("fork");
return 1;
}
else if (pid == 0) {
if (ptrace(PT_TRACE_ME, 0, NULL, 0) < 0) {
perror("PT_TRACE_ME");
_exit(1);
}
kill(getpid(), SIGSTOP);
for (;;)
sleep(1);
}
if (waitpid(pid, &status, 0) == -1) {
perror("waitpid");
return (-1);
}
assert(WIFSTOPPED(status));
assert(WSTOPSIG(status) == SIGSTOP);
memset(&pscr, 0, sizeof(pscr));
pscr.pscr_syscall = SYS_exit;
pscr.pscr_nargs = 1;
pscr.pscr_args = args;
args[0] = 66;
if (ptrace(PT_SC_REMOTE, pid, (caddr_t)&pscr, sizeof(pscr)) < 0) {
perror("PT_SC_REMOTE");
} else {
printf("remote exit %#lx errno %d\n",
pscr.pscr_ret.sr_retval[0],
pscr.pscr_ret.sr_error);
}
ptrace(PT_CONTINUE, pid, (caddr_t)1, SIGCONT);
for (;;) {
if (waitpid(pid, &status, 0) == -1) {
perror("waitpid");
exit(1);
}
printf("pid %d status %s\n", pid, decode_wait_status(status));
if (WIFSTOPPED(status))
ptrace(PT_CONTINUE, pid, (caddr_t)1, SIGCONT);
else if (WIFSIGNALED(status))
ptrace(PT_CONTINUE, pid, (caddr_t)1, 0/* XXX */);
else if (WIFEXITED(status))
break;
}
return (0);
}Comment Actions
I made the following changes/fixes to the exit test. Note that PT_SC_REMOTE does not lift the 'T' state.
The test passes afterward.
ATF_TC_WITHOUT_HEAD(ptrace__PT_SC_REMOTE_exit);
ATF_TC_BODY(ptrace__PT_SC_REMOTE_exit, tc)
{
struct ptrace_sc_remote pscr;
syscallarg_t args[1];
pid_t fpid, wpid;
int status;
ATF_REQUIRE((fpid = fork()) != -1);
if (fpid == 0) {
trace_me();
exit(66);
}
wpid = waitpid(fpid, &status, 0);
REQUIRE_EQ(wpid, fpid);
ATF_REQUIRE(WIFSTOPPED(status));
REQUIRE_EQ(WSTOPSIG(status), SIGSTOP);
args[0] = 42;
pscr.pscr_syscall = SYS_exit;
pscr.pscr_nargs = 1;
pscr.pscr_args = args;
ATF_REQUIRE(ptrace(PT_SC_REMOTE, fpid, (caddr_t)&pscr,
sizeof(pscr)) != -1);
ATF_REQUIRE(pscr.pscr_ret.sr_error == 0);
wpid = waitpid(fpid, &status, 0);
REQUIRE_EQ(wpid, fpid);
ATF_REQUIRE(WIFSTOPPED(status));
ATF_REQUIRE(ptrace(PT_CONTINUE, fpid, (caddr_t)1,
SIGCONT) != -1);
wpid = waitpid(fpid, &status, 0);
REQUIRE_EQ(wpid, fpid);
ATF_REQUIRE(WIFEXITED(status));
REQUIRE_EQ(WEXITSTATUS(status), 42);
}