Using gdb for fork() system call - c

I want to use gdb for looking into the various details of the fork() system call. To do this, I used one breakpoint at the fork() and from there onwards i am using step command but this way it is not working fine.
Can somebody explain me how to use gdb to look into every single step occuring during fork() system call?

Maybe you meant that you want to follow the child process instead of the parent once the fork is called? In that case:
If you want to follow the child
process instead of the parent process,
use the command set follow-fork-mode.
set follow-fork-mode mode
Set the debugger response to a program call of fork or vfork. A call
to fork or vfork creates a new
process. The mode argument can be:
parent: The original process is debugged after a fork. The child
process runs unimpeded. This is the
default.
child: The new process is debugged after a fork. The parent process runs
unimpeded.

If you want to see whats happening best if to look at the kernel code first, check it here.
I don't think you can single step through kernel from user space. You can use virtual server to do the debugging using KGDB. Check blog post here. Or you can use KGDB on main kernel.

Related

Wait for child exec

Short quesion:
I want wait in the parent for the child to be replaced with some exec call, not wait for terminate.
How can I do it?
(c language, linux platform)
Basile's answer is incorrect.
While it is true that there's no real way to wait for an exec after a call to fork(2), this is not the only way to create a child process. What you can do instead is use the vfork(2) call. This will block in the parent until the child calls either _exit or one of the exec functions.
Note that part of the reason this works the way it does is that the child process from vfork(2) does not, in fact, clone the entirety of the parent's address space. This means it is undefined behaviour to modify data in the child process before exec. If you need to do anything weird, you may be better off with for example using pause(2) and installing a signal handler for SIGUSR1 or some other signal of your choice, then using that signal immediately before the exec, or using some other IPC mechanism as mentioned above.
If you don't need to do anything special at all, and only want to call fork/exec right after one another, but want to be sure that execution of the child process has started, you can instead use posix_spawn(3), which should also start an external program immediately, effectively blocking the parent until after the exec.
You can't wait in a parent for the child to do some exec, except by having some convention about IPC, e.g. deciding to send something (in the child) on a pipe(7) just before the exec. You'll set up the pipe(2) before the fork(2). You might also use the Linux specific eventfd(2) for such IPC.
After the fork(2) and before any exec you are running (in the child process) the same code as the parent. So it is up to you to implement such conventional communications.
BTW, generally, the child process does not do a lot of things after the fork and before the exec, so waiting for the exec to happen is useless.... In the unlikely case an error happens -including failure of exec- you just _exit (usually with an exit code like 127).
You might consider ptrace(2) (with PTRACE_SYSCALL ...) but I would not do it that way.
Read Advanced Linux Programming and study the source code of some free software shells (sash or bash). Use also strace to understand what is happening in a shell.

Linux C code to start another process asynchronously

I am looking for C code to use on a Linux based system to start another process asynchronously. The second process should continue, even if the first ends. I've looked through the "fork" and "system" and "exec" options, but don't see anything that will spawn a peer process that's not communicating with or a child of the original process.
Can this be done?
Certainly you can. In the parent fork() a child, and in that child first call daemon() (which is an easy way to avoid setsid etc.), then call something from the exec family.
In Linux (and Unix), every process is created by an existing process. You may be able to create a process using fork and then, kill the parent process. This way, the child will be an orphan but still, it gets adopted by init. If you want to create a process that is not inherited by another, I am afraid that may not be possible.
You do a fork (man 2 fork) followed by an execl (man 2 execl)
For creates a new process of the same image as the calling process (so a perfect twin), where execl replaces one of the twins with a new image.
If you search google for "fork execl" you will find many text book examples -- including how to use correctly fork() and exec()
The most common fork-execl you will still have the new process associated to the terminal -- to create a perfect background process you need to create what is called a daemon process -- the template for that can be fornd in this answer here Creating a daemon in Linux

pthread fork and exec

I am using pthread_create() to create a thread and inside that thread i am using fork+execlp to load a new script.
But the problem is some time fork() call is fine but it is not executing the execlp call. So i have several process with the parent name is running and that is the reason some of the scripts are getting missed.
For example: If from my main program should execute 4 scripts.
I create 4 threads, and inside that i use fork+execlp to execute the scripts.
But when i see what are the scripts it is running, it only shows 3 scripts and one process iwth the parent name.
Can you please let me know what is the best way to deal with this situation?
It sounds like the execlp() call might be failing. If it succeeds, it never returns, so any return from execlp() indicates failure. Immediately after the call, you should call perror("execlp") to show the error, then _exit(1); to have the new child process exit.
When combining multiple threads with fork() make sure that you only execute only one fork in parallel. The pthreads method to do this is to lock a mutex with pthread_mutex_lock().
In the child, you will only have one thread -- the one that called fork(). Don't do anything but call async-signal-safe calls after the fork and before the exec.
See this SO question for more information.

how to efficiently debug processess created by fork()

I want to know whether there is any way to debug (using gdb) both child and parent processes simultaneously. I know the command used to change processes to child one. But that is not the solution I am looking for, as this method only has control of either the child or the parent. I am looking for simultaneous execution steps of both child and parent.
For instance, say the child is executing the a'th step in program b, while the parent is executing the c'th step in program d.
It seems that stepping through the processes of both parent and child is necessary. Is there any way to do this, and if so, how might I go about doing it?
I want to know whether there is any way to debug(using gdb) both child and parent processes simultaneously.
Yes, there is. Documentation here and here. If you are on Linux, you'll want to
(gdb) set detach-on-fork off
Regarding ctt's comment, it's not hard to do with gdb, as I've just found out. I found this resource, which works for both ddd and gdb:
Using gdb/ddd to debug child processes
If you have tried to debug a child process using ddd, you may have
noticed that ddd steps into the parent (and not the child) after the
call to fork(). It is possible to debug the child as well, but it
requires a special procedure. Since the child is a seperate process,
it will require a second debugger window, and we will make use of
gdb's ability to "attach" to a process which is already running.
Before you start, you must do the following:
Make sure your call to fork() assigns a value to some variable so you
can read it easily, e.g. pid = fork().
Make sure you place a sleep() statement in the child as the first line
of code after the fork(), e.g. sleep(60) [make the sleep() long
enough for step 4 below ...]. The sleep() statement can be removed once
debugging is complete. [You only need to do this if you need to attach to the child process right away.]
Compile your program with the "-g" option set, e.g. gcc myProg.c -o myProg -g
Now you are ready to start:
Start 2 copies of ddd [or gdb] in the background, like ddd myProg & ddd myProg & [or for gdb, start gdb as normal (e.g. gdb myProg) in two separate terminals]. It is important that the two copies being running concurrently.
Pick (arbitrarily) one window to be the "parent" and set a breakpoint
after the call to fork() (but not in any code the child will be
executing ... that is, set the breakpoint somewhere in the parent's
code ... if you set the breakpoint in the child's code, DDD will kill
the child as soon as it is created!).
Run the parent to the breakpoint. Note the value returned by fork(),
i.e. the process ID of the child.
In the "child" window, type "attach " in the gdb console window
where is the child's process ID. Note: the gdb console is found
at the bottom of the ddd window; this is where you can type commands
directly to gdb.
Set a breakpoint in the child after the sleep() statement, and click
on "cont" (in the popup "Command Tool" window) to allow the child to
continue execution to the breakpoint.
You will also need to type c or continue in the child gdb after you attach. Use print pid to see the value of pid.
If you have a process that kicks off a different process, then start the child gdb passing in the name of the child process. Ex. if program a kicks off program b, you want one terminal with gdb a (parent gdb) and one with gdb b (child gdb). In this case, you run from the gdb a terminal (it is no longer arbitrary).
This answer was more helpful to me because I'm using an older version of gdb, for which set detach-on-fork off wasn't working as I expected. This way you also don't have to suspend the process(es) you're not currently debugging, which may be required for some purposes.

Fork, Parent and child process

In C, is it possible to have the forked() process alive indefinitely even after the parent exits?
The idea of what I am trying to do is, Parent process forks a child, then exits, child keeps running in background until another process sends it a kill signal.
Yes, it is definitely possible to keep the child alive. The other responders are also correct; this is how a "daemon" or background process runs in a Linux environment.
Some call this the "fork off and die" approach. Here's a link describing how to do it:
http://wiki.linuxquestions.org/wiki/Fork_off_and_die
Note that more than just fork()-ing is done. File descriptors are closed to keep the background process from tying up system resources, etc.
Kerrek is right, this exactly the way how every daemon is implemented. So, your idea is perfect.
There is a daemon library function which is very easy to use for that.
The daemon() function call is not without limitations if you want to
write a well-behaved daemon. See On Starting Daemons
for an explanation.
Briefly: A good daemon should only background when it is ready to field requests, but do its setup under its own PID and print startup errors

Resources