Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

We are trying to implement the debugger program which will takes either PID or Program name as input and Invoke the gdb by using PID. Below is two small programs are written, Not able to figure out what is the exact problem here... after passing PID, it shows 5000+ instructions are executed as a result.

Debug.c

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <signal.h>
#include <syscall.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/reg.h>
#include <sys/user.h>
#include <unistd.h>
#include <errno.h>


/* Print a message to stdout, prefixed by the process ID
*/
void procmsg(const char* format, ...)
{
    va_list ap;
    fprintf(stdout, "[%d] ", getpid());
    va_start(ap, format);
    vfprintf(stdout, format, ap);
    va_end(ap);
}


void run_target(const char* programname)
{
    procmsg("target started. will run '%s'\n", programname);

    /* Allow tracing of this process */
    if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
        perror("ptrace");
        return;
    }

    /* Replace this process's image with the given program */
    execl(programname, programname, 0);
}


void run_debugger(pid_t child_pid)
{
    int wait_status;
    unsigned icounter = 0;
    procmsg("debugger started\n");

    /* Wait for child to stop on its first instruction */
    wait(&wait_status);

    while (WIFSTOPPED(wait_status)) {
        icounter++;
        struct user_regs_struct regs;
        ptrace(PTRACE_GETREGS, child_pid, 0, &regs);
        unsigned instr = ptrace(PTRACE_PEEKTEXT, child_pid, regs.eip, 0);

        procmsg("icounter = %u.  EIP = 0x%08x.  instr = 0x%08x\n",
                    icounter, regs.eip, instr);

        /* Make the child execute another instruction */
        if (ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0) < 0) {
            perror("ptrace");
            return;
        }

        /* Wait for child to stop on its next instruction */
        wait(&wait_status);
    }

    procmsg("the child executed %u instructions\n", icounter);
}


int main(int argc, char** argv)
{
    pid_t child_pid_attach;

    if (argc < 2) {
        fprintf(stderr, "Expected a program name as argument\n");
        return -1;
    }
sscanf(argv[1],"%d",&child_pid_attach);

//Attaching to running process
if(ptrace(PTRACE_ATTACH,child_pid_attach,0,0)<)
{
perror("ptrace");
return;
}
else
{
printf("%d",child_pid_attach);
}
    if (child_pid_attach== 0)
        run_target(argv[1]);
    else if (child_pid_attach > 0)
        run_debugger(child_pid_attach);
    else {
        perror("fork");
        return -1;
    }

ptrace(PTRACE_DETACH,child_pid_attach,0,0);
    return 0;
}

The above program has been used to debug the process that is created by the following program (i.e sum of two numbers). test.c

#include<stdio.h>
void main()
{
int a, b, c;
scanf("%d", &a);
scanf("%d", &b);
printf("\n Sum of Two Numbers is:");
c=a+b;
printf("%d",c);
}

First, we are running ./test and then checking its pid. As a next step we are running ./Debug [pid]. As a result of the above execution, it is displaying that Child process has executed 5000+ instructions and it is printing the same instructions all the time.

Please do let me know if there is any other way to do it and do let me know how to read the data of another process. In this case "How can I read the data (values of variables) of process that is created by ./test?".

share|improve this question
    
What is wrong with just using gdb? What would you like to happen when you give a program name? That it attaches to some process running that program, launch the program to debug it? If you really have some use case that hasn't been considered by the gdb developers, maybe you should discuss it with them (after possibly clarifying the proposal here). –  vonbrand Jan 24 '13 at 16:43
add comment

1 Answer 1

Actually, this is correct behavior.

Below is a quote from here:

The answer is very interesting. By default, gcc on Linux links programs to the C runtime libraries dynamically. What this means is that one of the first things that runs when any program is executed is the dynamic library loader that looks for the required shared libraries. This is quite a lot of code – and remember that our basic tracer here looks at each and every instruction, not of just the main function, but of the whole process.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.