C/C++ gdb seems to need to run as root

When I'm running as root, using gdb (GNU gdb version 6.1.1 [FreeBSD]) is straightforward. Example:
Code:
root:/u/home/tmp# cat 1.c
#include <stdio.h>
void spain(void) {printf("got to spain\n");}
int main(void) { spain(); return 0; }
root:/u/home/tmp# cc -g -Wall -Werror 1.c -o 1
root:/u/home/tmp# 1
got to spain
root:/u/home/tmp# gdb 1
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "amd64-marcel-freebsd"...
(gdb) b main
Breakpoint 1 at 0x40075f: file 1.c, line 3.
(gdb) b spain
Breakpoint 2 at 0x400740: file 1.c, line 2.
(gdb) run
Starting program: /u/home/tmp/1

Breakpoint 1, main () at 1.c:3
3  int main(void) { spain(); return 0; }
Current language:  auto; currently minimal
(gdb) c
Continuing.

Breakpoint 2, spain () at 1.c:2
2  void spain(void) {printf("got to spain\n");}
(gdb) c
Continuing.
got to spain

Program exited normally.
(gdb) quit
root:/u/home/tmp#
But when I do the same thing as non-root, gdb can't seem to plant breakpoints:
Code:
home:~/tmp$ cat 1.c
#include <stdio.h>
void spain(void) {printf("got to spain\n");}
int main(void) { spain(); return 0; }
home:~/tmp$ cc -g -Wall -Werror 1.c -o 1
home:~/tmp$ 1
got to spain
home:~/tmp$ gdb 1
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "amd64-marcel-freebsd"...
(gdb) b main
Breakpoint 1 at 0x40075f: file 1.c, line 3.
(gdb) b spain
Breakpoint 2 at 0x400740: file 1.c, line 2.
(gdb) run
Starting program: /u/home/tmp/1

Program received signal SIGTRAP, Trace/breakpoint trap.
0x0000000800602420 in ?? ()
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x000000080060b214 in ?? ()
(gdb) c
Continuing.

Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb) quit
home:~/tmp$
How do I get gdb to run as non-root? (Setting /usr/bin/gdb as suid root doesn't fix the problem.)

(Side note: I tried to use "gdb" as a tag, but the software insisted on making the tag "gdbe", whatever that is.)
 
You might get some mileage from the following link: http://unix.stackexchange.com/questions/15911/can-gdb-debug-suid-root-programs
In particular the comment:

If you need to debug the program when it's not started by root, start the program outside Gdb, make it pause in some fashion before getting to the troublesome part, and attach the process inside Gdb (at 1234 where 1234 is the process ID).

Another answer on that page has an example of pausing a program to attach to it.

 
Clear and interesting, but the question remains: how does someone who does not have root privileges on a FreeBSD system plant breakpoints in a C program using gdb?
 

SirDice

Administrator
Staff member
Administrator
Moderator
Works fine on 9.3:
Code:
dice@maelcum:~/test % cc -g -Wall -Werror test.c -o test
dice@maelcum:~/test % 
dice@maelcum:~/test % gdb test
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "amd64-marcel-freebsd"...
(gdb) b main
Breakpoint 1 at 0x400604: file test.c, line 3.
(gdb) b spain
Breakpoint 2 at 0x4005f4: file test.c, line 2.
(gdb) run
Starting program: /usr/home/dice/test/test 

Breakpoint 1, main () at test.c:3
3	int main(void) { spain(); return 0; }
(gdb) c
Continuing.

Breakpoint 2, spain () at test.c:2
2	void spain(void) {printf("got to spain\n");}
(gdb) c
Continuing.
got to spain

Program exited normally.
(gdb) quit
dice@maelcum:~/test %
And on 10.3:
Code:
dice@williscorto:~/test> cc -g -Wall -Werror test.c -o test
dice@williscorto:~/test> gdb test
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "amd64-marcel-freebsd"...
(gdb) b main
Breakpoint 1 at 0x40075f: file test.c, line 3.
(gdb) b spain
Breakpoint 2 at 0x400740: file test.c, line 2.
(gdb) run
Starting program: /usr/home/dice/test/test 

Breakpoint 1, main () at test.c:3
3	int main(void) { spain(); return 0; }
Current language:  auto; currently minimal
(gdb) c
Continuing.

Breakpoint 2, spain () at test.c:2
2	void spain(void) {printf("got to spain\n");}
(gdb) c
Continuing.
got to spain

Program exited normally.
(gdb) quit
So I'd say it's a local problem. Not sure what to look for though.
 
If the program that you are debugging has a different UID than what yours is, or if it's a SUID binary, then you need to run gdb as root. If the owner ID and your ID are the same, then there should be no issue. The problem you are running into is that you compiled the program as root, and then are trying to debug it as a user. As root, run the chown(8) command to change the owner to the correct user and you should be fine.
 
If the owner ID and your ID are the same, then there should be no issue.
Unfortunately, "should" isn't "is". As the original post shows, I compile the program and debug it as the same user. To emphasize this, I just now reran the failure, inserting who and ls commands for verification:
Code:
home:~/src/main/timesh/tmp$ cat 1.c
#include <stdio.h>
void spain(void) {printf("got to spain\n");}
int main(void) { spain(); return 0; }
home:~/src/main/timesh/tmp$ cc -g -Wall -Werror 1.c -o 1
home:~/src/main/timesh/tmp$ who am i
home  May  4 12:36
home:~/src/main/timesh/tmp$ ls -l 1
-rwx------  1 home  home  8629 2016-05-04 12:36:30 1
home:~/src/main/timesh/tmp$ 1
got to spain
home:~/src/main/timesh/tmp$ gdb 1
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "amd64-marcel-freebsd"...
(gdb) b main
Breakpoint 1 at 0x40075f: file 1.c, line 3.
(gdb) b spain
Breakpoint 2 at 0x400740: file 1.c, line 2.
(gdb) run
Starting program: /u/home/src/main/timesh/tmp/1

Program received signal SIGTRAP, Trace/breakpoint trap.
0x0000000800602420 in ?? ()
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x000000080060b214 in ?? ()
(gdb) c
Continuing.

Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb) quit
home:~/src/main/timesh/tmp$
 

SirDice

Administrator
Staff member
Administrator
Moderator
Well, it's actually breaking, as you can see by the first trap. It seems it's not being handled correctly so it doesn't show the source and correct addresses. It then continues at some address which results in a segmentation fault. But that's probably because it's trying to continue from the wrong place.
 
You may have a legitimate bug, or there is something unique with your configuration. I just tried it on my system (i386 platform on 10.3) and it is working fine. At this point, I don't know. You can probably try the mailing list to see if anyone there has seen something like this before, or post a possible bug on the gdb mailing lists.
 
SirDice and Maelstorm had it right. It's a local issue. I run with ssh-agent sitting on top of the login shell, and that breaks gdb. Since I actually only need that wrinkle for one "user" on my system, I've changed the password file(s) to reflect this; gdb now works just fine for all other users. For that one user, the only C or C++ code I run is well-seasoned; everything else is Perl or LISP or some such.
 
Top