Can lldb inspect what has been written to a file, or the data in an IPC mechanism it has generated/used, at a breakpoint? - lldb

Say with this simple code:
#include<stdio.h>
int main(int argc, char** argv){
printf("Hello World!\n");
return 0;
}
After stepping printf("Hello World!\n”); perhaps there’s a command to print that “Hellow World!\n” has been written to STDOUT.
And after return 0 perhaps there’s a command to see the exit codes generated and it will show 0.
Are there such commands or similar in lldb?

LLDB prints the exit status when a process exits:
(lldb) run
Process 76186 launched: '/tmp/a.out' (x86_64)
Process 76186 exited with status = 10 (0x0000000a)
and you can also access it with the SB API's:
(lldb) script lldb.process.GetExitStatus()
10
lldb doesn't have any special knowledge about all the ways a program might read or write data to a pipe, file handle, pty, etc... It also doesn't know how to interpose on file handles and tee-off the output. There's no particular reason it couldn't, but nobody has added that to date.
So you would have to build this yourself. If you know the API your code is using to read and write, you could use breakpoints to observe that - though that might get slow if you are observing a program that reads and writes a lot.

Related

How to make c programe as daemon in ubuntu?

Hi I am new to the linux environment. I am trying to create daemon process.
#include<stdio.h>
int main()
{
int a=10,b=10,c;
c=sum(a,b);
printf("%d",c);
return (0);
}
int sum(int a,int b)
{
return a+b;
}
I want to create daemon process of it. May i know how can do this? Any help would be appreciated. Thank you.
A daemon generally doesn't use its standard input and output streams, so it is unclear how your program could be run as a daemon. And a daemon program usually don't have any terminal, so it cannot use clrscr. Read also the tty demystified page, and also daemon(7).
I recommend reading some good introduction to Linux programming, like the old freely downloadable ALP (or something newer). We can't explain all of it here, and you need to read an entire book. See also intro(2) and syscalls(2).
I also recommend reading more about OSes, e.g. the freely available Operating Systems: Three Easy Pieces textbook.
You could use the daemon(3) function in your C program to run it as a daemon (but then, you are likely to not have any input and output). You may want to log messages using syslog(3).
You might consider job control facilities of your shell. You could run your program in the background (e.g. type myprog myarg & in your interactive shell). You could use the batch command. However neither background processes nor batch jobs are technically daemons.
Perhaps you want to code some ONC-RPC or JSONRPC or Web API server and client. You'll find libraries for that. See also pipe(7), socket(7)
(take several days or several weeks to read much more)
First find what are the properties of daemon process, as of my knowledge a daemon process have these properties:
Should not have any parent (it itself should be parent)
Process itself is a session leader.
Environment change to root.
File mode creating mask should be zero.
No controlling terminal.
All terminal should be removed
Should not be un-mounted .
Implement the code by considering above properties which is
int i=0;
int main()
{
int pid;
pid=fork();
if(pid!=0) {
/** you can add your task here , whatever you want to run in background **/
exit(0);
}
else
{
setsid();//setting sessions
chdir("/");//root.. should'nt beunmounted
umask(0);
close(0);//all terminal are removed
close(1);
close(2);
while(1)
{
printf("i = %d \n",i);
i++;
}
}
return 0;
}
or you can go through man page of daemon()
int daemon(int nochdir, int noclose);
I hope it helps.
Instead of writing the code to make the C program a daemon I would go with an already mature tool like supervisor:
http://supervisord.org/
I think this below will work
screen cmd arg1 arg2
You can also try
nohup cmd arg1

How to configure GDB in Eclipse such that all prcoesses keep on running including the process being debugged?

I am new in C programming and I have been trying hard to customize an opensource tool written in C according to my organizational needs.
IDE: Eclipse,
Debugger: GDB,
OS: RHEL
The tool is multi-process in nature (main process executes first time and spawns several child processes using fork() ) and they share values in run time.
While debugging in Eclipse (using GDB), I find that the process being debugged is only running while other processes are in suspended mode. Thus, the only running process is not able to do its intended job because the other processes are suspended.
I saw somewhere that using MI command in GDB as "set non-stop on" could make other processes running. I used the same command in the gdbinit file shown below:
Note: I have overridden above .gdbinit file with an another gdbinit because the .gdbinit is not letting me to debug child processes as debugger terminates after the execution of main process.
But unfortunately debugger stops responding after using this command.
Please see below commands I am using in the gdbinit file:
Commenting non-stop enables Eclipse to continue usual debugging of the current process.
Adding: You can see in below image that only one process is running while others are suspended.
Can anyone please help me to configure GDB according to my requirement?
Thanks in advance.
OK #n.m.: Actually, You were right. I should have given more time to understand the flow of the code.
The tool creates 3 processes first and then the third process creates 5 threads and keeps on wait() for any child thread to terminate.
Top 5 threads (highlighted in blue) shown in the below image are threads and they are children of Process ID: 17991
The first two processes are intended to initiate basic functionality of the tool and hence they just wait to get exit(0). You can see below.
if (0 != (pid = zbx_fork()))
exit(0);
setsid();
signal(SIGHUP, SIG_IGN);
if (0 != (pid = zbx_fork()))
exit(0);
That was the reason I was not actually able to step in these 3 processes. Whenever, I tried to do so, the whole main process terminated immediately and consequently leaded to terminate all other processes.
So, I learned that I was supposed to "step-into" threads only. And yes, actually I can now debug :)
And this could be achieved because I had to remove the MI command "set follow-fork-mode child". So, I just used the default " .gdbinit" file with enabled "Automatically debug forked process".
Thanks everyone for your input. Stackoverflow is an awesome place to learn and share. :)

How to debug cgi program written in C and running in Apache2?

I have a complex cgi executable written in C, I configured in Apache2 and now it is running succesfully. How can I debug this program in the source code, such as set break points and inspect variables? Any tools like gdb or eclipse? Any tutorial of how to set up the debugging environment?
Thanks in advance!!
The CGI interface basically consists in passing the HTTP request to the executable's standard input and getting the response on the standard output. Therefore you can write test requests to files and manually execute your CGI without having to use Apache. The debugging can then be done with GDB :
gdb ./my_cgi
>> break some_func
>> run < my_req.txt
with my_req.txt containing the full request:
GET /some/func HTTP/1.0
Host: myhost
If you absolutely need the CGI to be run by Apache it may become tricky to attach GDB to the right process. You can for example configure Apache to have only one worker process, attach to it with gdb -p and use set follow-fork-mode child to make sure it switches to the CGI process when a request arrives.
I did this: in cgi main i added code to look for an existing file, like /var/tmp/flag. While existing, i run in a loop. Time enough to attach to cgi process via gdb. After then i delete /var/tmp/flag and from now I can debug my cgi code.
bool file_exists(const char *filename)
{
ifstream ifile(filename);
return ifile;
}
int cgiMain()
{
while (file_exists ("/var/tmp/flag"))
sleep (1);
...
your code
Unless FastCGI or SCGI is used, the CGI process is short-lived and you need to delay its exit to have enough time to attach the debugger while the process is still running. For casual debugging the easiest option is to simply use sleep() in an endless loop at the breakpoint location and exit the loop with the debugger once it is attached to the program.
Here's a small example CGI program:
#include <stdio.h>
#include <unistd.h>
void wait_for_gdb_to_attach() {
int is_waiting = 1;
while (is_waiting) {
sleep(1); // sleep for 1 second
}
}
int main(void) {
wait_for_gdb_to_attach();
printf("Content-Type: text/plain;charset=us-ascii\n\n");
printf("Hello!");
return 0;
}
Suppose it is compiled into cgi-debugging-example, this is how you would attach the debugger once the application enters the endless loop:
sudo cgdb cgi-debugging-example $(pgrep cgi-debugging)
Next you need to exit the infinite loop and wait_for_gdb_to_attach() function to reach the "breakpoint" in your application. The trick here is to step out of sleep functions until you reach wait_for_gdb_to_attach() and set the value of the variable is_waiting with the debugger so that while (is_waiting) exits:
(gdb) finish
Run till exit from 0x8a0920 __nanosleep_nocancel () at syscall-template.S:81
0x8a07d4 in __sleep (seconds=0) at sleep.c:137
(gdb) finish
Run till exit from 0x8a07d4 in __sleep (seconds=0) at sleep.c:137
wait_for_gdb_to_attach () at cgi-debugging-example.c:6
Value returned is $1 = 0
(gdb) set is_waiting = 0 # <<<<<< to exit while
(gdb) finish
Run till exit from wait_for_gdb_to_attach () cgi-debugging-example.c:6
main () at cgi-debugging-example.c:13
Once you are out of wait_for_gdb_to_attach(), you can continue debugging the program or let it run to completion.
Full example with detailed instructions here.
I'm not sure how to use gdb or other frontends in eclipse, but I just debugged my CGI program with gdb. I'd like to share something that other answers didn't mention, that CGIs usually need to read request meta-variables defined in RFC 3875#4.1 with getenv(3). Popular request variables in my mind are:
SCRIPT_NAME
QUERY_STRING
CONTENT_LENGTH
CONTENT_TYPE
REMOTE_ADDR
There variables are provided by http servers such as Apache. When debugging with gdb, we need to set these values by our own with set environment. In my case, there're only a few variables neededa(and the source code is very old, it still uses SCRIPT_URL instead of SCRIPT_NAME), so here's my example:
gdb cgi_name
set environment SCRIPT_URL /path/to/sub/cgis
set environment QUERY_STRING p1=v1&p2=v2
break foo.c:42
run
For me both solutions for debugging the CGI in gdb without web server presented above didn't work.
Maybe the second solution works for a GET Request.
I needed a combination of both, first setting the environment variables from rfc3875 (not sure if all of them are really neded).
Then I was able to pass only the params (not the compltete request) via STDIN from a file.
gdb cgi_name
set environment REQUEST_METHOD=POST
set environment CONTENT_LENGTH=1337
set environment CONTENT_TYPE=application/json
set environment SCRIPT_NAME=my.cgi
set environment REMOTE_ADDR=127.0.0.1
run < ./params.txt
With params.txt:
{"user":"admin","pass":"admin"}

coredump redirect to file

I am invoking make from my C program, which intern executes another program. I am redirecting both the standard out and standard error to a file. However, when the program run by make terminates due to segmentation fault, a core dump is generated and printed to the console (standard out) of the main program that is invoking make.
How can I get around this and not have the core dump show on the console?
The following is my code to invoke make :
int pid = fork();
if(pid==0){
dup2(make_logs, 1);
dup2(make_logs, 2);
close(make_logs);
execvp (args[0],args);
}
Where make_logs is the file opened using 'open'
Thanks
I would try to fix the core dump rather than suppressing the message, but the message about the segmentation fault is being generated by the shell (which detects the exit value of the child and recognize a core dump situation), so you can suppress it by installing your own program that handles the fork() and wait() rather than having the shell do the work.
To suppress the core dump, just use limit coredumpsize 0.
Sample of suppression (sloppy code; you should really be checking for errors):
#include <sys/types.h>
#include <sys/wait.h>
main( int argc, char **argv )
{
int pid;
if( (pid = fork() ) > 0 ) wait( 0 );
else if( pid == 0 ) {
execl( "program-that-cdumps", "program-that-cdumps", 0 );
perror("failed in execl");
} else perror("failed in fork");
}
Read core(5) and signal(7) man pages.
Compile all your programs with gcc -Wall -g. Then use
file core
to understand which binary dumped the core. It probably says something like core dump from foo to tell you that program foo dumped the core. Then, start a post mortem debugger on it:
gdb foo core
and use the common gdb commands (notably bt to backtrace, p to print, etc...).
The message dumped core is given by some shell (or perhaps by make when it is acting like a shell). I don't think that the core file is output to stdout (it is a big binary file).
If you wish to avoid the core (which IMHO is a bad idea, a core dump is a good symptom of something wrong), you could call the setrlimit(2) syscall with RLIMIT_CORE and a 0 limit after your fork and before the execvp. I believe you should not do that (or at least have some way of configuring that setrlimit is not called: sometimes you really need the core dump to debug the problem).
You should fix the problem which gives the core dump, not try to avoid the dumped core message!
If you run make on a user provided Makefile so that the core dump is from a user program, you really want to keep the user informed that a core did happen, so you should keep the core dumped message.

Stopping own process

The concerned code is very huge and hence i am sorry i cannot post it here. The issue is:- I wrote a small program as follows:
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<signal.h>
int main()
{
printf("\n Process id",getpid());
fflush(stdout);
if(kill(getpid(),SIGSTOP)!=0)
printf("\nError");
}
Upon running i get the following o/p:
Process id 2664
[1]+ stopped ./test_SIGSTOP
[Directory Path]$
Which is exactly what is expected. But in my actual program which i said is very huge...control comes to just above the kill call(I know it as I have print statements and fflushed them) and hangs without automatically stopping the process and appearence of the command prompt.
Would be gratefull for pointers.
Thank
You can attach a debugger to a running program and find out where/why it hangs. Also, the raise() function is more convenient to use. But first, use ps and inspect the process's flags to confirm its status (running / sleeping / stopped).

Resources