Error Code 18 after CreateProcess. Why?
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
using namespace std;
int main()
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si)); // macro fills a block of memory with zeros
ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);
BOOL create_proc = CreateProcess(L"c:\\windows\\system32\\cmd.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
//printf("Error (%d)\n", GetLastError());
if(!create_proc)
printf("CreateProcess failed (%d).\n", GetLastError());
// Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE );
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
//check
printf("Error (%d)\n", GetLastError());
return 0;
}
From here : https://msdn.microsoft.com/en-us/library/ms681382(v=vs.85).aspx
The seems your error code corresponds to,
ERROR_NO_MORE_FILES
18 (0x12)
There are no more files.
It could be permissions.
Related
I am getting unusual results while writing and reading from a pipe. The runtime error is Program terminated by signal: 13. I searched about this error and found that this error is due to there are no readers to read from pipe while i am reading from the pipe in the child process. Here is my code:
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#define BUFFER_SIZE 50
#define READ_END 0
#define WRITE_END 1
int main()
{
int pipe_fd[2];
pid_t pid;
pid = fork();
char message[BUFFER_SIZE] = "Greetings";
char read_message[BUFFER_SIZE];
if( pipe(pipe_fd) == -1)
{
perror("Error in creating the pipe \n");
exit(-1);
}
if(pid==-1)
{
perror("Error in creating the child! \n");
exit(-1);
}
if(pid==0) // Child process
{
close(pipe_fd[WRITE_END]);
read(pipe_fd[READ_END], read_message , BUFFER_SIZE);
printf("The message read by the child is: %s", read_message);
close(pipe_fd[READ_END]);
}
if(pid>0) // Parent process
{
close(pipe_fd[READ_END]); //Closing the read end of the pipe
write(pipe_fd[WRITE_END], message, BUFFER_SIZE); // Writing to pipe on write_end
close(pipe_fd[WRITE_END]);
}
return 0;
}
Any suggestions how to solve this runtime error?
You need to open your pipe before you fork a child process. Otherwise your processes aren't talking to the same pipe.
Thus move your pipe creation code above the fork() call as follows:
if( pipe(pipe_fd) == -1)
{
perror("Error in creating the pipe \n");
exit(-1);
}
pid_t pid;
pid = fork();
char message[BUFFER_SIZE] = "Greetings";
char read_message[BUFFER_SIZE];
if(pid==-1)
{
perror("Error in creating the child! \n");
exit(-1);
}
I'm trying to monitor syscalls for a binary using ptrace. The binary sleeps in pselect() and without ptrace, a SIGQUIT makes it return from pselect. The mask of blocked signals passed to pselect includes SIGQUIT.
When executed with ptrace, it exits from sys_pselect6 but not all the way out of glibc's pselect. What am I doing that prevents sys_pselect6 from exiting out to user code ?
Tracer:
#include <stdio.h>
#include <sys/ptrace.h>
#include <sys/reg.h>
#include <err.h>
#include <wait.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int pid = fork(), sys_in = 1, status;
if (pid == 0) {
if (ptrace(PTRACE_TRACEME, getppid(), NULL, NULL) < 0)
err(1, "TRACEME()");
execl("./child", "./child", NULL);
err(1, "execl()");
}
if (waitpid(pid, &status, 0) != pid) err(1, "wait()");
for (;; sys_in ^= 1) {
if (ptrace(PTRACE_SYSCALL, pid, NULL, NULL) < 0) err(1, "SYSCALL");
if (waitpid(pid, &status, 0) != pid) err(1, "wait()");
if (sys_in) {
long long sys_no = ptrace(PTRACE_PEEKUSER, pid, 8 * ORIG_RAX, NULL);
printf("syscall entry %lld\n", sys_no);
}
else printf("syscall exit\n");
}
return 0;
}
Child:
#include <stdio.h>
#include <sys/select.h>
#include <signal.h>
#include <err.h>
void handle_sigquit(int sig, siginfo_t* info, void *ctx)
{
}
int main()
{
sigset_t mask;
sigset_t orig_mask;
struct sigaction sa = {};
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handle_sigquit;
sigaction(SIGQUIT, &sa, NULL);
sigemptyset(&mask);
sigaddset(&mask, SIGQUIT);
if (sigprocmask(SIG_BLOCK, &mask, &orig_mask) < 0) err(1, "sigprocmask()");
pselect(0, NULL, NULL, NULL, NULL, &orig_mask);
warn("pselect()");
return 0;
}
ptrace(PTRACE_SYSCALL, pid, NULL, NULL)
Whenever your debugger gets a notification, you just assume that that notification is about a system call, and handle it accordingly. That is not the case.
Some of the notifications you receive using wait are for signals that your debugee has received. When those happen, the last NULL in your PTRACE_SYSCALL call eliminates, effectively masks, the signal from arriving at the debugee process.
When processing ptrace results, you need to check the signal that caused your debugger to wake up. At the very least, check if it's a SIGTRAP or something else. If it is something else, the best bet is to pass it on to the debugee process.
Check out this small program to see a simple way of doing it.
I need help with thread management inside cloned process.
The point is that I need to create and destroy threads inside a cloned process asynchronously (PTHREAD_CANCEL_ASYNCHRONOUS is set). Everything is fine if CLONE_VM is not set, but I need it because main and child process must share the same address space.
Below is an example that demonstrate the question. Being compiled with CLONE_VM flag the program hangs at pthread_join while without CLONE_VM everything is fine.
Are there any ways to deal with this problem?
P.S. Tried at Debian GNU/Linux versions 7,8 and unstable (kernels 3.2, 3.16, 4.0).
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <sched.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
/* Compile with # gcc -o pthread_test -lpthread pthread_test.c */
#define CLONE 1
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *thread_test(void *unused)
{
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_mutex_unlock(&mutex);
pause();
return NULL;
}
int test(void *unused)
{
void *status;
int r;
pthread_t thread;
pthread_mutex_lock(&mutex);
if ((r = pthread_create(&thread, NULL, thread_test, NULL)) != 0) {
printf("pthread_create returned %d\n", r);
exit(1);
}
pthread_mutex_lock(&mutex);
printf("cancelling thread\n");
r = pthread_cancel(thread);
printf("pthread cancel returned : %s(%d)\n", strerror(r), r);
printf("joining thread\n");
r = pthread_join(thread, &status);
printf("pthread_join returned : %s\n", strerror(r));
if (status == PTHREAD_CANCELED)
printf("child was canceled\n");
else
printf("child exit status is %u\n", (unsigned)status);
return 0;
}
int main(void)
{
#if CLONE
void *stack = (void *)malloc(16384);
if (clone(test, stack + 16383, CLONE_VM | CLONE_FS | CLONE_FILES, NULL) < 0) {
printf("clone failed\n");
exit(1);
}
waitpid(0, NULL, __WCLONE);
return 0;
#else
void *stack = (void *)malloc(16384);
if (clone(test, stack + 16383, /*CLONE_VM |*/ CLONE_FS | CLONE_FILES, NULL) < 0) {
printf("clone failed\n");
exit(1);
}
waitpid(0, NULL, __WCLONE);
return 0;
#endif
}
I am trying to simulate failure of write() system call.
I have read that return value -1 (in EAX) indicates error in system call and errno gives the exact reason for failure.
I am trying to intercept system call write() return -1 in EAX register and set the "errno" to some error value.
puts() internally uses write(), which is system call number 4.
If i do perror("Error:") in the child, it should show the error corresponding to "errno" which i would like to set.
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/reg.h> /* For constants ORIG_EAX etc */
#include <stdio.h>
#include <sys/user.h>
#include <errno.h>
int main()
{ pid_t child;
int status;
long orig_eax,eax,params[3];
int ret_val=-1,insyscall=0;
struct user_regs_struct regs;
child = fork();
if(child == 0) {
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execl("/home/kashi/Documents/2nd_Sem/MyPrgms/ptrace/ramana/write", "write", NULL);
//execl("/bin/ls","ls",NULL);
}
else {
while(1)
{
wait(&status);
if(WIFEXITED(status))
break;
orig_eax = ptrace(PTRACE_PEEKUSER,
child, 4 * ORIG_EAX, NULL);
if(orig_eax == 4)
{
ptrace( PTRACE_GETREGS, child, 0, ®s );
printf("Write called with %ld, %ld %ld\n",regs.ebx, regs.ecx,regs.edx);
if(insyscall == 0)
{
/* Syscall entry */
printf("In %d\n",insyscall);
insyscall = 1;
}
else
{
/* Syscall exit */
regs.orig_eax=-1;
**errno=11; //This errno should be set in the child process, how to do it?**
ptrace( PTRACE_SETREGS, child, 0, ®s );
eax = ptrace(PTRACE_PEEKUSER, child, 4 * ORIG_EAX, NULL);
printf("Write returned with %ld\n", eax);
insyscall = 0;
}
}
//printf("The child made a "
// "system call %ld\n", regs.orig_eax);
ptrace(PTRACE_SYSCALL, child, NULL, NULL);
}
}
return 0;
}
The tracee program (testwrite.c) is:
#include<stdio.h>
#include<unistd.h>
#include<sys/ptrace.h>
#include<signal.h>
#include<errno.h>
//int display(char *p);
int main()
{
printf("Hi Kashi\n");
perror("Error: ");
return 0;
}
output:
[kashi#localhost ramana]$ ./test.sh
In 0
Hi Kashi
Write returned with -1
In 0
**Error: : Success**
Write returned with -1
The perror("Error:") displays text message corresponding to "errno". I am not able to set this "errno" in child process, how can i do it?
Parent receives SIGPIPE sending chars to aborted child process through FIFO pipe.
I am trying to avoid this, using select() function. In the attached sample code,
select() retruns OK even after the child at the other end of pipe having been terminated.
Tested in
RedHat EL5 (Linux 2.6.18-194.32.1.el5)
GNU C Library stable release version 2.5
Any help appreciated. Thnak you.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/stat.h>
#include <unistd.h>
static void sigpipe_fct();
main()
{
struct stat st;
int i, fd_out, fd_in, child;
char buf[1024];
#define p_out "/tmp/pout"
signal(SIGPIPE, sigpipe_fct);
if (stat(p_out, &st) != 0) {
mknod(p_out, S_IFIFO, 0);
chmod(p_out, 0666);
}
/* start receiving process */
if ((child = fork()) == 0) {
if ((fd_in = open(p_out, O_RDONLY)) < 0) {
perror(p_out);
exit(1);
}
while(1) {
i = read(fd_in, buf, sizeof(buf));
fprintf(stderr, "child %d read %.*s\n", getpid(), i, buf);
lseek(fd_in, 0, 0);
}
}
else {
fprintf(stderr,
"reading from %s - exec \"kill -9 %d\" to test\n", p_out, child);
if ((fd_out = open(p_out, O_WRONLY + O_NDELAY)) < 0) { /* output */
perror(p_out);
exit(1);
}
while(1) {
if (SelectChkWrite(fd_out) == fd_out) {
fprintf(stderr, "SelectChkWrite() success write abc\n");
write(fd_out, "abc", 3);
}
else
fprintf(stderr, "SelectChkWrite() failed\n");
sleep(3);
}
}
}
static void sigpipe_fct()
{
fprintf(stderr, "SIGPIPE received\n");
exit(-1);
}
SelectChkWrite(ch)
int ch;
{
#include <sys/select.h>
fd_set writefds;
int i;
FD_ZERO(&writefds);
FD_SET (ch, &writefds);
i = select(ch + 1, NULL, &writefds, NULL, NULL);
if (i == -1)
return(-1);
else if (FD_ISSET(ch, &writefds))
return(ch);
else
return(-1);
}
From the Linux select(3) man page:
A descriptor shall be considered ready for writing when a call to an
output function with O_NONBLOCK clear would not block, whether or not
the function would transfer data successfully.
When the pipe is closed, it won't block, so it is considered "ready" by select.
BTW, having #include <sys/select.h> inside your SelectChkWrite() function is extremely bad form.
Although select() and poll() are both in the POSIX standard, select() is much older and more limited than poll(). In general, I recommend people use poll() by default and only use select() if they have a good reason. (See here for one example.)