How do I attach gdbserver to a process at startup? - c++

I am using gdbserver to debug a remote process. I am able to attach gdbserver to the process after it has launched and is waiting for input.
However, I want to attach gdbserver to the process while it is being launched. The process is launched via a shell script and I cannot change how this process is being launched i.e. I cannot modify the shell script to launch the process via a call to gdbserver.
How do I attach gdbserver to this process as soon as it launches?
Edit: I am able to create a wait loop at the start of main(). For example a loop which waits till it finds a file at a predetermined location :
#include <unistd.h>
int main() {
while( access("/home/username/CONTINUE", F_OK) == -1)
sleep(1);
/*
...all the rest of main()
*/
return 0;
}
We can attach gdbserver while the process is busy with this loop, set breakpoints as required and say touch /home/username/CONTINUE to exit the loop. But this requires us to be able to access the source code, compile the binary and place it on the target machine. I am looking for a better, easier way than this.

But this requires us to be able to access the source code1, compile the binary and place it on the target machine. I am looking for a better, easier way than this.
It looks like you are working on a linux / unix like remote operating system.
If you have admin access to the remote system, the simplest way I could think of is to rename the original executable, and replace that with a shell script named like the original executable, that starts the now renamed under control of gdbserver.
Something like (assumed executable /usr/bin/foo) at the target machine:
root:# cd /usr/bin
root:# mv foo foo_
root:# echo "#!/bin/sh\ngdbserver /dev/com1 foo_ foo.txt" > foo
root:# chmod a+x foo
As it says in the gdbserver man(1) page:
This tells gdbserver to debug foo_ with an argument of foo.txt, and
to communicate with GDB via /dev/com1. gdbserver now waits patiently
for the host GDB to communicate with it.
Another way I could think of without modifying the original process at all, could be a little program that monitors changes in the /dev/proc directory(ies), and attaches gdbserver at such event with the associated pid.
Though it's kind of luck then, if gdbserver is attached, before that process already schedules to main().
1You should have acces to the source code anyways for reasonable debugging with gdb. Though there are cases where you can just get with the (dis-)assembly code as well.

Related

Debugging multiprocess project with GDB

I'd like to to debug a multiprocess C++ project with GDB, specifically I'd like to know if there is a way to achieve the following
Attach multiple processes to a single instance of GDB while letting all the processes run
Setting up a breakpoint in the source code of one of the processes stops all the attached processes
The ideal solution would be something similar to what is offered by the Visual Studio debugger as described here.
At the moment I'm able to attach multiple processes to a GDB instance but then only the current selected inferior is executed while the others are stopped and waiting for a continue command.
In order to be able to run inferiors in the background, one needs to issue this gdb command
set target-async on
after start up and before running anything. With this option in effect, one ca issue
continue&
(or just c&) and this will send the inferior to the background, giving an opportunity to switch to run another one.
Stopping all inferiors at once is a bit more difficult. There is no built-in command for that. Fortunately gdb is scriptable and it is possible to attach a script to a breakpoint. Once the breakpoint is hit, the commands are executed. Put inferior n and interrupt commands in the script for each inferior. It is probably more convenient to do that from a Python script, something like
(gdb) python
>inf = gdb.inferiors()
>for i in inf:
> gdb.execute("inferior %d" % i.num)
> gdb.execute("interrupt")

Run Linux commands from Daemon

I need to run a linux command such as "df" from my linux daemon to know free space,used space, total size of the parition and other info. I have options like calling system,exec,popen etc..
But as this each command spawn a new process , is this not possible to run the commands in the same process from which it is invoked?
And at the same time as I need to run this command from a linux daemon, as my daemon should not hold any terminal. Will it effect my daemon behavior?
Or is their any C or C++ standard API for getting the mounted paritions information
There is no standard API, as this is an OS-specific concept.
However,
You can parse /proc/mounts (or /etc/mtab) with (non-portable) getmntent/getmntent_r helper functions.
Using information about mounted filesystems, you can get its statistics with statfs.
You may find it useful to explore the i3status program source code: http://code.stapelberg.de/git/i3status/tree/src/print_disk_info.c
To answer your other questions:
But as this each command spawn a new process , is this not possible to run the commands in the same process from which it is invoked?
No; entire 'commands' are self-contained programs that must run in their own process.
Depending upon how often you wish to execute your programs, fork();exec() is not so bad. There's no hard limits beyond which it would be better to gather data yourself vs executing a helper program. Once a minute, you're probably fine executing the commands. Once a second, you're probably better off gathering the data yourself. I'm not sure where the dividing line is.
And at the same time as I need to run this command from a linux daemon, as my daemon should not hold any terminal. Will it effect my daemon behavior?
If the command calls setsid(2), then open(2) on a terminal without including O_NOCTTY, that terminal might become the controlling terminal for that process. But that wouldn't influence your program, because your program already disowned the terminal when becoming a daemon, and as the child process is a session leader, it cannot change your process's controlling terminal.

How to restart Linux from inside a C++ program?

I have a Qt 4 GUI where I need to have a option in a drop-down menu that allows the user to choose to restart the computer. I realize this might seem redunant with the ability to restart the computer in other ways, but the choice needs to stay there. I've tried using system() to call the following:
a suid-root shell script
a non-suid shell script
a suid-root binary program
and all of them just cause reboot: must be superuser to be printed. Using system() to call reboot directly does the same thing. I'm not especially attached to using system() to do this, but it seemed like the most direct choice.
How can I reboot the system from the GUI?
The reboot function is described in the Linux Programmer's Manual. Under glibc, you can pass the RB_AUTOBOOT macro constant to perform the reboot.
Note that if reboot is not preceded by a call to sync, data may be lost.
Using glibc in Linux:
#include <unistd.h>
#include <sys/reboot.h>
sync();
reboot(RB_AUTOBOOT);
In Linux:
#define LINUX_REBOOT_CMD_POWER_OFF 0x4321fedc
sync();
reboot(LINUX_REBOOT_CMD_POWER_OFF);
Have you tried running a shell script, using gksudo? Something like
gksudo shutdown -r
With any luck, that should pull up a modal dialogue to get user credentials.
suid-ing shell scripts is just dangerous as already mentioned (which is why that didn't work).
I suspect that suid-ing the binary doesn't work because system spawns its subprocess with the user's actual uid and not the suid one, again for security reasons (it would let you substitute any binary for the one being called and run it as root).
You could put a copy of reboot in a location protected such that only users you want have permission to can execute it, and then suid-root THAT.
Alternately give them sudoer privilege to execute JUST the command you care about and system out to something like "ksh -c 'sudo reboot'"
This should do it on almost any linux system.
#include <unistd.h>
#include <sys/reboot.h>
int main () {
sync();
setuid(0);
reboot(RB_AUTOBOOT);
return(0);
}
Then just compile with gcc reboot.c -o reboot and do chmod a+s reboot on the binary. Then call reboot as any user and the system should reboot smoothly. The way you do this through your GUI varies, as in if your Desktop Environment was KDE for example, it's quite different than doing the same thing under Fluxbox.
In binary try to call
setuid (0);
before system() call.
how would you reboot the system from the command line on your system?
basically do
system( <however you wouuld do it from the command line> );

How to know if a process had been started but crashed in Linux

Consider the following situation: -
I am using Linux.
I have doubt that my application has crashed.
I had not enabled core dump.
There is no information in the log.
How can I be sure that, after the system restart my app was started, but now it is not running, because it has crashed.
My app is configured as a service, written in C/C++.
In a way: how can I get all the process/service names that have executed since the system start? Is it even possible?
I know, I can enable logging and start the process again to get the crash.
This feature is included in Linux Kernel. It's called: BSD process accounting.
Standard practice is to have a pid file for your daemon (/var/run/$NAME.pid), in which you can find its process id without having to parse the process tree manually. You can then either check the state of that process, or make your daemon respond to a signal (usually SIGHUP), and report its status. It's a good idea to make sure that this pid still belongs to your process too, and the easiest way is to check /proc/$PID/cmdline.
Addendum:
If you're only using newer fedora or ubuntu, your init system is upstart, which has monitoring and triggering capabilities built in.
As #emg-2 noted, BSD process accounting is available, but I don't think it's the correct approach for this situation.
I would recommend that you write the fact that you started out to some kind of log file, either a private one which get's overwritten on each start up or one via syslogd.
Also, you can log a timestamp heartbeat so that you know exactly when it crashed.
you probably can make a decoy, ie an application or shell script that is just a wrapper around the true application, but adds some logging like "Application started".
Then you change the name of your original app, and give the original name to your decoy.
As JimB mentions, you have the daemon write a PID file. You can tell if it's running or not by sending it a signal 0, via either the kill(2) system call or the kill(1) program. The return status will tell you whether or not the process with that PID exists.
Daemons should always:
1) Write the currently running instance's process to /var/run/$NAME.pid using getpid() (man getpid) or an equivalent command for your language.
2) Write a standard logfile to /var/log/$NAME.log (larger logfiles should be broken up into .0.log for currently running logs along with .X.log.gz for other logs, where X is a number with lower being more recent)
3) /Should/ have an LSB compatible run script accepting at least the start stop status and restart flags. Status could be used to check whether the daemon is running.
I don't know of a standard way of getting all the process names that have executed; there might be a way however to do this with SystemTap.
If you just want to monitor your process, I would recommend using waitid (man 2 wait) after the fork instead of detaching and daemonizing.
If your app has crashed, that's not distinguishable from "your app was never started", unless your app writes in the system log. syslog(3) is your friend.
To find your app you can try a number of ideas:
Look in the /proc filesystem
Run the ps command
Try killall appname -0 and check the return code

How do I stop execution in GDB without a breakpoint?

How do I stop a GDB execution without a breakpoint?
Just use a regular interrupt Ctrl-c will work just fine. GDB just forwards the SIGINT to the debugging process which then dies. GDB will catch the non-standard exit and break the process there, so you can still examine all the threads, their stacks and current values of variables. This works fine, though you would be better off using break points. The only time I find myself doing this is, if I think I've gotten into some sort of infinite loop.
GUI applications don't react to ^C and ^Break the way console applications do. Since these days most non-trivial projects tend to be GUI applications or libraries primarily used in GUI applications, you have two options:
Send SIGSTOP to the application from a separate terminal. This is cumbersome.
If you press ^C or ^Break on the GDB prompt, GDB will terminate but the application will remain running. You can then run GDB again to attach to it using the -p command-line switch. This loses debugger state.
In both cases, you might find this helpful: tasklist | grepProcessName| sed -e 's/ProcessName*\([0-9]*\).*/gdbModuleName-pid=\1/' > rungdb.sh You can modify this for use in shell scripts, makefiles or to send a signal instead of attaching GDB.
info threads will help you figure out which thread you want to look at. Then use threadThreadNumber to switch to it.
Start a shell, find the process ID using ps and send it SIGSTOP or SIGINT by using the kill command (e.g. kill -INT pid).
Just type BREAK without any arguments.
Break, when called without any arguments, break sets a breakpoint at the next instruction to be executed in the selected stack frame
Ctrl + Z seems to work for me (but only in some cases - I'm not sure why).