11

My test case is so simple that I must be doing something very stupid. I wrote a simple source file test.c:

#include<stdio.h>

int main(int argc,char* argv[]){
    printf("1\n");
    printf("2\n");
    printf("3\n");
    return 0;
}

I compiled it with gcc -g test.c and started GDB with gdb a.out. Then I created a breakpoint in main with break main and ran it with run(also tried with start) - but GDB simply ignored my breakpoint!

This is the shell session of me trying to compile test.c and run GDB:

[idanarye@idanarye_lg gdbtest]$ gcc -g test.c
[idanarye@idanarye_lg gdbtest]$ gdb a.out
GNU gdb (GDB) 7.6.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/idanarye/gdbtest/a.out...done.
(gdb) break main
Breakpoint 1 at 0x40050f: file test.c, line 4.
(gdb) run
Starting program: /home/idanarye/gdbtest/a.out 
1
2
3
During startup program exited normally.
(gdb) 

What in the world am I doing wrong here?

I'm running a 64bit Arch Linux. My GCC version is 4.8.2.

UPDATE

Here is the result of disas main:

Dump of assembler code for function main:
   0x0000000000400500 <+0>:     push   %rbp
   0x0000000000400501 <+1>:     mov    %rsp,%rbp
   0x0000000000400504 <+4>:     sub    $0x10,%rsp
   0x0000000000400508 <+8>:     mov    %edi,-0x4(%rbp)
   0x000000000040050b <+11>:    mov    %rsi,-0x10(%rbp)
   0x000000000040050f <+15>:    mov    $0x4005c4,%edi
   0x0000000000400514 <+20>:    callq  0x4003e0 <puts@plt>
   0x0000000000400519 <+25>:    mov    $0x4005c6,%edi
   0x000000000040051e <+30>:    callq  0x4003e0 <puts@plt>
   0x0000000000400523 <+35>:    mov    $0x4005c8,%edi
   0x0000000000400528 <+40>:    callq  0x4003e0 <puts@plt>
   0x000000000040052d <+45>:    mov    $0x0,%eax
   0x0000000000400532 <+50>:    leaveq 
   0x0000000000400533 <+51>:    retq   
End of assembler dump. 

UPDATE

No idea how or why, but it works now. Probably a system update fixed it...

Idan Arye
  • 12,402
  • 5
  • 49
  • 68
  • 2
    "What in the world am I doing wrong here?" -- you appear to be doing everything correctly. What does `disas main` at `(gdb)` prompt say? – Employed Russian Dec 28 '13 at 02:21
  • 1
    Very odd – you say `start` does _not_ stop the debugger at the first line of main? Can you try, in GDB, `b *&main` (to disable GDB's prologue scanning), and if that does not work `b *&start`? `start` or `_start` is the entry point of the entire application. Since the instruction at that address is the first one that is run, a breakpoint there _must_ be hit or else your debugger setup has a serious problem. – Iwillnotexist Idonotexist Dec 28 '13 at 02:25
  • @EmployedRussian I've updated the question with the results of `disas main`. @IwillnotexistIdonotexist `b &*main` doesn't work either. `b *&start` complains that `No symbol "start" in current context`, and `b *&_start` sets the breakpoint but doesn't break on it(just like with `main`). – Idan Arye Dec 28 '13 at 02:48
  • The message `During startup program exited normally.` is also anomalous, the correct one being `Program exited normally.`. It suggests GDB failed to insert a bkpt in `main()` or the traced program's call to `ptrace(PT_TRACE_ME, 0, 0, 0)` failed, the program thus ran without being stopped, and it exited while GDB was only expecting it to start up and stop at `exec()`. Can you run `gdb` under `strace` while doing your example and `grep` `strace`'s log for any failed `ptrace()` calls? – Iwillnotexist Idonotexist Dec 28 '13 at 02:54
  • You'd do so with something similar to `strace -f -o syscall.txt gdb ./a.out`. – Iwillnotexist Idonotexist Dec 28 '13 at 03:05
  • @IwillnotexistIdonotexist I grepped it for `ptrace` and got `5765 ptrace(PTRACE_TRACEME, 0, 0, 0) = -1 EPERM (Operation not permitted)`, so I've tried running `gdb` with `sudo` and it worked! Any idea why? `a.out` was created by the same user that runs `gdb`, and it has read and execute permissions for everyone... – Idan Arye Dec 28 '13 at 03:21
  • @Idan Arye I have literally no idea! Could you post up `ls -l \`which gdb\` ./a.out` ? – Iwillnotexist Idonotexist Dec 28 '13 at 03:22
  • @IwillnotexistIdonotexist It gives `-rwxr-xr-x 1 idanarye users 7797 Dec 28 04:52 ./a.out` and `-rwxr-xr-x 1 root root 5206304 Aug 31 07:10 /usr/bin/gdb`. Can it be because `gdb` belongs to root? – Idan Arye Dec 28 '13 at 03:27
  • 2
    @Idan Arye We're past the limits of my knowledge here but perhaps this link might help (http://askubuntu.com/questions/41629/after-upgrade-gdb-wont-attach-to-process). Apparently some kernel hardening's been going on with the inadvertent effect of crippling GDB debugging. – Iwillnotexist Idonotexist Dec 28 '13 at 03:40
  • @Idan Arye Did it work? If it did I could move my comments into an answer. – Iwillnotexist Idonotexist Dec 28 '13 at 03:47
  • @IwillnotexistIdonotexist Thanks. That answer doesn't work(I think it solves a different problem), but at least I'm on the right track. I'll try reinstalling GDB tomorrow - maybe it'll set the permissions right. At any rate, you can post what we have as an answer so I can accept it once we solve this. – Idan Arye Dec 28 '13 at 03:50
  • @IdanArye If you `#include `, can you give me the return value of `prctl(PR_GET_DUMPABLE, 0, 0, 0, 0)` from within the debugged app? According to the [man page](http://man7.org/linux/man-pages/man2/prctl.2.html), a process must be _dumpable_ in order for `ptrace` to work. – Iwillnotexist Idonotexist Dec 29 '13 at 03:22
  • @IwillnotexistIdonotexist It's `1`. – Idan Arye Dec 29 '13 at 19:56
  • Ah. So dumpability isn't the problem. Even wierder. Will search some more. – Iwillnotexist Idonotexist Dec 29 '13 at 19:57

3 Answers3

4

(curated from comments)

You do not appear do be doing anything wrong; It appears to be GDB's fault.

The message During startup program exited normally. is anomalous, the correct one being Program exited normally.. It suggests GDB failed to insert a breakpoint in main() or the traced program's call to ptrace(PT_TRACE_ME, 0, 0, 0) failed. The program thus ran without being stopped, and it exited while GDB was only expecting it to start up and stop at exec(). Can you run gdb under strace while doing your example and grep strace's log for any failed ptrace calls?

You would do so with strace -f -o syscall.txt gdb ./a.out.

As of right now a stop-gap measure appears to be to run GDB as root.

Iwillnotexist Idonotexist
  • 13,297
  • 4
  • 43
  • 66
  • Reinstalling GDB didn't work. Since it's a permissions problem, I've started a [question on Unix&Linux](http://unix.stackexchange.com/questions/106912/permission-denied-for-ptrace-under-gdb) – Idan Arye Dec 28 '13 at 18:00
0

I encountered a similar problem and in my case the thing was that my program was forking itself. So basically, my code looked like this:

#include <string>
#include <iostream>
#include "func.hpp"

using namespace std;

int main(int argc, char **argv)
{
        if(argc <3)
        {
          printf("\n %s IP PORT\n",argv[0]);
          printf("e.g. %s 10.32.129.77 6379\n",argv[0]);
          printf("\n Going to run on the default server and port\n");
          string command{argv[0]};
          command+=" 10.32.129.77 6379";
          printf("\nCommand: %s\n",command.c_str());
          system(command.c_str());
          exit(0);
        }

func();
}

I was creating a breakpoint where "func" function was being called. However, I unknowingly wasn't passing the correct arguments and as a result my program forked itself with correct arguments. So basically "func" was now being called from the child process and as it turns out gdb doesn't set the breakpoints at the child process and that's why the breakpoint was not being hit.

Vishal Sharma
  • 1,670
  • 20
  • 55
-2

I had this same problem. It was intermittent and drove me nuts. Then I found I did a dumb thing. I had been running the program from the command line, and it had a bunch of arguments.

So, I copied the command line with the mouse-copy-paste buffer.

Then started: gdb Program

Then did: break man

Then did: -PASTE-FROM-MOUSE-

It never stopped, until I realized that I had pasted too much of the command line: "--option=c ... |& tee LOG"

It looked like an intermittent problem, until I realized it was a brain bug. Hope this helps someone. The command line redirect - did something in GDB, no clue what (other than ignore breakpoints).

Doug Royer
  • 67
  • 5