How to debug a child process which is already under debug - linux

I have two process (Linux ELF): process A is a main process and B is a child process (A uses fork() to create B). A also uses ptrace to trace the B (like some kind of sandbox) catching the B’s int 3 instruction.
I want to use GDB to debug process B. When I tried GDB to attach the child process B, it shows an error that B is already under debug. So do I have a way to debug the child process which is already under another “debugger”?
In my case, A and B have interactions, I cannot directly patch or rewrite the code in A to disable ptrace function.

So do I have a way to debug the child process which is already under another “debugger”?
No.
Having a child that is ptrace'd by its parent, with non-trivial interaction between the two, is one of the few effective anti-debugging techniques.
To debug B, you would have to run it without A sandboxing it, and would have to replicate the interaction between A and B by "emulating" what process A normally does to process B through GDB.

Related

How to determine the signal that terminated a QProcess with Qt4 on Linux?

I want to detect the QProcess I launched was terminated externally by either SIGKILL or SIGTERM. This is important in distinguishing between a crash (bug) and an external interference when I've written the process I'm launching myself.
I've tried registering watched processes through a slot connected to QProcess::started and setting a SIGCHLD handler (using sigaction) to capture the process status using waitpid. The issue is that waitpid clears the internal kernel data structure and even if I properly chain my handler to the one on the QProcess implementation, the latter isn't able to get the child status as any next calls to waitpid for that pid fail. Setting the process state to QProcess::ProcessState::NotRunning through QProcess::setProcessState avoids hanging on calls to waitForFinished in general, but there are corner cases which I couldn't manage to fix yet.
I was wondering if there isn't a better way to do this, other than modifying Qt's source code to store the status information somewhere.
Note: I know that crashes also terminate with a signal, which is SIGABRT. The main issue here is that a SIGKILL might tell me that the out of memory killer in Linux was the responsible for the process termination.
This is my code, friend.
QProcess* pExe = new QProcess(this);
connect(pExe, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(onOSRExit(int, QProcess::ExitStatus)));
pExe->setWorkingDirectory(QCoreApplication::applicationDirPath());
pExe->start("some.exe");
....
void CXXXXX::onOSRExit(int exitCode, QProcess::ExitStatus exitStatus)
{
}
The solution altering Qt's code under Qt 4, basically involves a simple modification to QProcessPrivate::waitForDeadChild():
if (qt_safe_waitpid(pid_t(pid), &exitStatus, WNOHANG) > 0) {
processManager()->remove(q);
crashed = !WIFEXITED(exitStatus);
- exitCode = WEXITSTATUS(exitStatus);
+ exitCode = crashed ? WTERMSIG(exitStatus) : WEXITSTATUS(exitStatus);
The signal will then be available on QProcess::exitCode() after QProcess::finished() has been emitted.
Note: Qt5 is using Thiago Macieira's forkfd, so this solution won't work.

DIFFERENT TASKS ASSIGNED TO DIFFERENT INSTANCES OF FORK() OF A PROCESS IN C

Can I assign different task to different instances of fork() of a process in C ?
like for example:
program.c has been forked 3 times
int main()
{
pid_t pid;
pid = fork();
pid = fork();
pid = fork();
}
now to every instance of fork() I want to do different thing, Can I do this? with forks ? or any other method if favorable? :)
PS: I am testing Real Time Linux and want to check the performance of the Context Switching through forks through Time Constraint.
You can use posix process..
posix_spawn( &Pid,ProgramPath.c_str(), & FileActions,& SpawnAttr,argv,envp);
Check its documentation here.
You always have to test the result of fork(2) (in particular, to handle error cases), and do different things for 0 result (successful in child process), positive result (successful in parent process), negative result (failure, so use perror). So according to that result you can do different things. Often you end up invoking execve(2) for the child process (when fork gives 0), and you usually setup things (e.g. for IPC thru pipe(7)-s) before calling fork.
So to assign a different task after a fork just execute different code according to result of fork
You should read Advanced Linux Programming. It has several chapters explaining all that (so I won't take the time to explain it here).
You could be interested in pthreads (implemented using clone(2) and futex(7), which you should not use directly unless you are implementing your thread library, which is not reasonable).
Try also to strace(1) several programs (including some shell and some basic commands). It will tell which syscalls(2) they are calling. See also intro(2).

Fork()-ing a new process

Fork()-ing a process will end up calling do_fork() inside kernel, making an exact copy of itself. When I read through books, it says that child of fork will call exec to create the new process.
example:
ls command on a shell, will create this way.
sh(Parent)
|
sh(Child)
|
ls(New Process)
But, I am not able to understand how & where the exec*() is called?
Because, All I can see is the shell(child) is what created in fork.
But, when and where will the new process be created/executed?
You have to exec() if you actually want a new program running in one of the processes (usually the child but not absolutely necessary). In your specific case where the shell executes ls, the shell first forks, then the child process execs. But it's important to realise that this is two distinct operations.
All fork() does is give you two (nearly) identical processes and you can then use the return code from fork() to decide if you're the parent (you get the positive PID of the child, or -1 if the fork() failed) or child (you get 0).
See this answer for a description on how fork() and exec() work together (under your control) and how they can be used without each other.
Similar to do_fork(), the exec stuff all boils down to calls to do_execve, located in exec.c.

Preventing threaded subprocess.popen from terminating my main script when child is killed?

Python 2.7.3 on Solaris 10
Questions
When my subprocess has an internal Segmentation Fault(core) issue or a user externally kills it from the shell with a SIGTERM or SIGKILL, my main program's signal handler handles a SIGTERM(-15) and my parent program exits. Is this real? or is it a bad python build?
Background and Code
I have a python script that first spawns a worker management thread. The worker management thread then spawns one or more worker threads. I have other stuff going on in my main thread that I cannot block. My management thread stuff and worker threads are rock-solid. My services run for years without restarts but then we have this subprocess.Popen scenario:
In the run method of the worker thread, I am using:
class workerThread(threading.Thread):
def __init__(self) :
super(workerThread, self).__init__()
...
def run(self)
...
atempfile = tempfile.NamedTempFile(delete=False)
myprocess = subprocess.Popen( ['third-party-cmd', 'with', 'arguments'], shell=False, stdin=subprocess.PIPE, stdout=atempfile, stderr=subprocess.STDOUT,close_fds=True)
...
I need to use myprocess.poll() to check for process termination because I need to scan the atempfile until I find relevant information (the file may be > 1 GiB) and I need to terminate the process because of user request or because the process has been running too long. Once I find what I am looking for, I will stop checking the stdout temp file. I will clean it up after the external process is dead and before the worker thread terminates. I need the stdin PIPE in case I need to inject a response to something interactive in the child's stdin stream.
In my main program, I set a SIGINT and SIGTERM handler for me to perform cleanup, if my main python program is terminated with SIGTERM or SIGINT(Ctrl-C) if running from the shell.
Does anyone have a solid 2.x recipe for child signal handling in threads?
ctypes sigprocmask, etc.
Any help would be very appreciated. I am just looking for an 'official' recipe or the BEST hack, if one even exists.
Notes
I am using a restricted build of Python. I must use 2.7.3. Third-party-cmd is a program I do not have source for - modifying it is not possible.
There are many things in your description that look strange. First thing, you have a couple of different threads and processes. Who is crashing, who's receinving SIGTERM and who's receiving SIGKILL and due to which operations ?
Second: why does your parent receive SIGTERM ? It can't be implicitly sent. Someone is calling kill to your parent process, either directly or indirectly (for example, by killing the whole parent group).
Third point: how's your program terminating when you're handling SIGTERM ? By definition, the program terminates if it's not handled. If it's handled, it's not terminated. What's really happenning ?
Suggestions:
$ cat crsh.c
#include <stdio.h>
int main(void)
{
int *f = 0x0;
puts("Crashing");
*f = 0;
puts("Crashed");
return 0;
}
$ cat a.py
import subprocess, sys
print('begin')
p = subprocess.Popen('./crsh')
a = raw_input()
print(a)
p.wait()
print('end')
$ python a.py
begin
Crashing
abcd
abcd
end
This works. No signal delivered to the parent. Did you isolate the problem in your program ?
If the problem is a signal sent to multiple processes: can you use setpgid to set up a separate process group for the child ?
Is there any reason for creating the temporary file ? It's 1 GB files being created in your temporary directory. Why not piping stdout ?
If you're really sure you need to handle signals in your parent program (why didn't you try/except KeyboardInterrupt, for example ?): could signal() unspecified behavior with multi threaded programs be causing those problems (for example, dispatching a signal to a thread that does not handle signals) ?
NOTES
The effects of signal() in a multithreaded process are unspecified.
Anyway, try to explain with more precision what are the threads and process of your program, what they do, how were the signal handlers set up and why, who is sending signals, who is receiving, etc, etc, etc, etc, etc.

How can a process kill itself?

#include<stdlib.h>
#include<unistd.h>
#include<signal.h>
int main(){
pid_t pid = fork();
if(pid==0){
system("watch ls");
}
else{
sleep(5);
killpg(getpid(),SIGTERM); //to kill the complete process tree.
}
return 0;
}
Terminal:
anirudh#anirudh-Aspire-5920:~/Desktop/testing$ gcc test.c
anirudh#anirudh-Aspire-5920:~/Desktop/testing$ ./a.out
Terminated
for the first 5 secs the output of the "watch ls" is shown and then it terminates because I send a SIGTERM.
Question: How can a process kills itself ? I have done kill(getpid(),SIGTERM);
My hypothesis:
so during the kill() call the process switches to kernel mode. The kill call sends the SIGTERM to the process and copies it in the process's process table. when the process comes back to user mode it sees the signal in its table and it terminates itself (HOW ? I REALLY DO NOT KNOW )
(I think I am going wrong (may be a blunder) somewhere in my hypothesis ... so Please enlighten me)
This code is actually a stub which I am using to test my other modules of the Project.
Its doing the job for me and I am happy with it but there lies a question in my mind how actually a process kills itself. I want to know the step by step hypothesis.
Thanks in advance
Anirudh Tomer
Your process dies because you are using killpg(), that sends a signal to a process group, not to a process.
When you fork(), the children inherits from the father, among the other things, the process group. From man fork:
* The child's parent process ID is the same as the parent's process ID.
So you kill the parent along with the child.
If you do a simple kill(getpid(), SIGTERM) then the father will kill the child (that is watching ls) and then will peacefully exit.
so during the kill() call the process switches to kernel mode. The kill call sends the SIGTERM to the process and copies it in the process's process table. when the process comes back to user mode it sees the signal in its table and it terminates itself (HOW ? I REALLY DO NOT KNOW )
In Linux, when returning from the kernel mode to the user-space mode the kernel checks if there are any pending signals that can be delivered. If there are some it delivers the signals just before returning to the user-space mode. It can also deliver signals at other times, for example, if a process was blocked on select() and then killed, or when a thread accesses an unmapped memory location.
I think it when it sees the SIGTERM signal in its process tables it first kills its child processes( complete tree since I have called killpg() ) and then it calls exit().
I am still looking for a better answer to this question.
kill(getpid(), SIGKILL); // itself I think
I tested it after a fork with case 0: and it quit regular from separate parent process.
I don't know if this is a standard certification method ....
(I can see from my psensor tool that CPU usage return in 34% like a normal program code with
a counter stopped ) .
This is super-easy in Perl:
{
local $SIG{TERM} = "IGNORE";
kill TERM => -$$;
}
Conversion into C is left as an exercise for the reader.

Resources