Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Non-Root Process Backtrace of Itself?
When one of my daemon workers faults I would like to automatically
get a backtrace using gdb in Linux. Unfortunately if that process is
not root ptrace returns EPERM because the worker was setuid/setgid to
"nobody". So when the code faults and I run my "backtrace" script in
the signal handler it chokes.

Is there any way for a non-root process to backtrace itself?

Thanks,
Mike

Report this thread to moderator Post Follow-up to this message
Old Post
Michael B Allen
12-22-04 02:00 PM


Re: Non-Root Process Backtrace of Itself?
Michael B Allen <mba2000@ioplex.com> writes:

> When one of my daemon workers faults I would like to automatically
> get a backtrace using gdb in Linux. Unfortunately if that process is
> not root ptrace returns EPERM because the worker was setuid/setgid to
> "nobody". So when the code faults and I run my "backtrace" script in
> the signal handler it chokes.

Your description of what you are doing is self-inconsistent:
- if the *parent* is trying to invoke gdb on the child, then EPERM
is expected, but what does this have to do with the signal handler?
- if the child invokes gdb on itself in its signal handler, then
there should be no problem with EPERM (gdb will also run as
"nobody"), and that is how you probably should solve this problem.

Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.

Report this thread to moderator Post Follow-up to this message
Old Post
Paul Pluzhnikov
12-22-04 09:04 PM


Re: Non-Root Process Backtrace of Itself?
Michael B Allen wrote:

> Is there any way for a non-root process to backtrace itself?

You could consider using __builtin_return_address instead.

See the GCC_DumpStack function in stacktrace.c in

http://home1.stofanet.dk/breese/debug/debug.tar.gz

--
mail1dotstofanetdotdk

Report this thread to moderator Post Follow-up to this message
Old Post
Bjorn Reese
12-22-04 09:04 PM


Re: Non-Root Process Backtrace of Itself?
On Wed, 22 Dec 2004 11:25:41 -0500, Paul Pluzhnikov wrote:
 
>
> Your description of what you are doing is self-inconsistent: - if the
> *parent* is trying to invoke gdb
<nope>
> - if the child invokes gdb on itself in its signal handler, then
>   there should be no problem with EPERM (gdb will also run as "nobody"),
>   and that is how you probably should solve this problem.

No. This is what I'm doing but I'm seeing ptrace return EPERM. If you
ptrace on a process that started out as "user" then ptraceing as that user
will work. But an exe that started out as "root" and then setuid/setgid
to "nobody" is inherently different and "nobody" cannot ptrace it even
though it is also "nobody".

Mike

Report this thread to moderator Post Follow-up to this message
Old Post
Michael B Allen
12-23-04 02:13 AM


Re: Non-Root Process Backtrace of Itself?
On Wed, 22 Dec 2004 13:19:31 -0500, Bjorn Reese wrote:

> Michael B Allen wrote:
> 
>
> You could consider using __builtin_return_address instead.
>
> See the GCC_DumpStack function in stacktrace.c in
>
>    http://home1.stofanet.dk/breese/debug/debug.tar.gz

I just wrote a simple test proggie and it faults:

Program received signal SIGSEGV, Segmentation fault.
0x08048a69 in GCC_DumpStack () at stacktrace.c:257
257               p = __builtin_return_address(6);

Can I use this fn as is or do I need to actually understand what
__builtin_return_address actually is?

Also, I was hoping I could get the backtrace inside the sighandler
after getting SEGV. But won't this just print the stack of the signal
handler? Can I change it to print the stack of the process that faulted?

Mike

Report this thread to moderator Post Follow-up to this message
Old Post
Michael B Allen
12-23-04 02:13 AM


Re: Non-Root Process Backtrace of Itself?
Michael B Allen wrote:

> Program received signal SIGSEGV, Segmentation fault.
> 0x08048a69 in GCC_DumpStack () at stacktrace.c:257
> 257               p = __builtin_return_address(6);
>
> Can I use this fn as is or do I need to actually understand what
> __builtin_return_address actually is?

You will notice from the boiler-plate that the code is quite old.
It used to work, but apparently __builtin_return_address has changed
semantics in the meantime.

I ran the program and got the same crash as you. I can make it work
if I change the line

p = __builtin_return_address(0);

to

p = __builtin_frame_address(0);
if (p)
p = __builtin_return_address(0);

and similar for all other __builtin_return_address lines.

> Also, I was hoping I could get the backtrace inside the sighandler
> after getting SEGV. But won't this just print the stack of the signal
> handler? Can I change it to print the stack of the process that faulted?

It outputs the entire stack, not just the stack of the signal handler.
I get the following output (CrashHandler is the SIGSEGV signal handler)

[0] 0x08049443 <StackTrace + 0xb> T
[1] 0x0804948d <CrashHandler + 0x1b> T
[2] 0x420275c8 ???
[3] 0x080494ac <Crash + 0x15> T
[4] 0x0804952d <main + 0x7c> T
[5] 0x42015574 ???
[6] 0x08048729 <_start + 0x21> T

--
mail1dotstofanetdotdk

Report this thread to moderator Post Follow-up to this message
Old Post
Bjorn Reese
12-24-04 02:06 PM


Re: Non-Root Process Backtrace of Itself?
On Fri, 24 Dec 2004 07:07:01 -0500, Bjorn Reese wrote:

> Michael B Allen wrote:
> 
>
> You will notice from the boiler-plate that the code is quite old. It
> used to work, but apparently __builtin_return_address has changed
> semantics in the meantime.
>
> I ran the program and got the same crash as you. I can make it work if I
> change the line
>
>    p = __builtin_return_address(0);
>
> to
>
>    p = __builtin_frame_address(0);
>    if (p)
>      p = __builtin_return_address(0);
>
> and similar for all other __builtin_return_address lines.
>

Still faults for me anyway:

Program received signal SIGSEGV, Segmentation fault.
0x08048aaf in GCC_DumpStack () at stacktrace.c:264
264               p = __builtin_return_address(6);
(gdb) bt
#0  0x08048aaf in GCC_DumpStack () at stacktrace.c:264
#1  0x0804962f in fn0 (i=10) at t.c:7
#2  0x0804964c in fn1 (i=11) at t.c:14
#3  0x0804966c in fn2 (i=11) at t.c:19
#4  0x0804969a in main () at t.c:25
#5  0x42017499 in __libc_start_main () from /lib/i686/libc.so.6

If I cut down the ADDRESSLIST_SIZE to 6 it sort of works:

$ ./t
[0] 0x0804937b ???
[1] 0x08049398 ???
[2] 0x080493b8 ???
[3] 0x080493e6 ???
[4] 0x42017499 ???
[5] 0x08048741 ???

I removed 'static' from GCC_DumpStack, added a prototype to stacktrace.h,
and compiled as follows:

$ gcc -Wall -W -g -DUSE_BUILTIN -c -o stacktrace.o stacktrace.c
stacktrace.c: In function `GCC_DumpStack':
stacktrace.c:225: warning: unused variable `pname'
$ gcc -Wall -W -g stacktrace.o -o t t.c

I also tried:

$ gcc -Wall -W -g -DUSE_BUILTIN stacktrace.c -o t t.c
stacktrace.c: In function `GCC_DumpStack':
stacktrace.c:225: warning: unused variable `pname'

No difference.

$ gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs
gcc version 2.96 20000731 (Red Hat Linux 7.3 2.96-110)

Is there any documentation on this __builtin_return_address thing?

Thanks,
Mike

Report this thread to moderator Post Follow-up to this message
Old Post
Michael B Allen
12-25-04 08:56 AM


Re: Non-Root Process Backtrace of Itself?
Michael B Allen wrote:

> If I cut down the ADDRESSLIST_SIZE to 6 it sort of works:

Well, the problem is detecting the top of the call stack, so
lowering ADDRESSLIST_SIZE will only avoid the crash if you
know that your call stack is more than 6 frames deep.
__builtin_return_address ought to return 0 in that case, but
instead it simply crashes.

> [0] 0x0804937b ???

It does not resolve the symbols. Is nm in your path?

> gcc version 2.96 20000731 (Red Hat Linux 7.3 2.96-110)

Ah, the old version of gcc could be the problem.

> Is there any documentation on this __builtin_return_address thing?

Yes, it is a built-in function of gcc, so you can find the
description in 'info gcc' (at least in later versions of gcc.)

--
mail1dotstofanetdotdk

Report this thread to moderator Post Follow-up to this message
Old Post
Bjorn Reese
12-25-04 01:55 PM


Re: Non-Root Process Backtrace of Itself?
Bjorn Reese wrote: 
>
>
> Ah, the old version of gcc could be the problem.

According to my readings (just some googling over the last 24 hours or
so) __buildin_return_address() is not guaranteed to return 0 when
reaching stack top due to limitations of certain architectures, and
supposedly x86 is one of those.

--
Henry Townsend

Report this thread to moderator Post Follow-up to this message
Old Post
Heny Townsend
12-26-04 08:57 AM


Re: Non-Root Process Backtrace of Itself?
Heny Townsend wrote:

> According to my readings (just some googling over the last 24 hours or
> so) __buildin_return_address() is not guaranteed to return 0 when
> reaching stack top due to limitations of certain architectures, and
> supposedly x86 is one of those.

Yes, this is why I suggested the __builtin_frame_address() workaround.
However, that only works if (according to the documentation) "the
first frame pointer is properly initialized by the startup code";
however one achieves that...

Another workaround could be to iterate through the call stack until
we find an address inside the main() function. The could be done
by adding the following two lines (marked by +) in GCC_DumpStack()

if ((p) && (i < ADDRESSLIST_SIZE))
{
syms[i].realAddress = (unsigned long)p;
syms[i].closestAddress = 0;
syms[i].name[0] = (char)0;
syms[i].type = ' ';
+	  if ((p > (void *)main) && (p < (void *)main_end))
+	    break; /* for */

This solution requires a pointer to the end of the main function.
I did this by adding an "void main_end(void) {}" immediately after
the main function. Better solutions are most welcome.

--
mail1dotstofanetdotdk

Report this thread to moderator Post Follow-up to this message
Old Post
Bjorn Reese
12-26-04 08:56 PM


Sponsored Links




Last Thread Next Thread Next
Pages (2): [1] 2 »
Search this forum -> 
Post New Thread

Unix Programming archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 08:16 AM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.