Discussion:
gdbstub initial code, v7
Oleg Nesterov
2010-08-30 18:58:50 UTC
Permalink
Changes:

- report signals. A bit more code changes than I expected.

- implement QPassSignals, trivial.

Note: $CSIG is not supported yet, and I am not sure I understand
how it should work. Next time...
Jan Kratochvil
2010-08-30 19:20:40 UTC
Permalink
Post by Oleg Nesterov
- report signals. A bit more code changes than I expected.
BTW not sure if it is already the right time for it but to keep ugdb on-par
with my linux-nat's re-post today (still not accepted in FSF GDB)
[0/9]#2 Fix lost siginfo_t
http://sourceware.org/ml/gdb-patches/2010-08/msg00480.html

ugdb should support qXfer:siginfo, currently accessible only via $_siginfo
print/set, though.


Thanks,
Jan
Jan Kratochvil
2010-08-31 07:20:48 UTC
Permalink
Post by Jan Kratochvil
Post by Oleg Nesterov
- report signals. A bit more code changes than I expected.
BTW not sure if it is already the right time for it but to keep ugdb on-par
with my linux-nat's re-post today (still not accepted in FSF GDB)
That's not true, this functionality needs no gdb/remote.c changes and its
correctnes relies just on ugdb (and it is probably not a problem for ugdb).
Post by Jan Kratochvil
ugdb should support qXfer:siginfo, currently accessible only via $_siginfo
print/set, though.
Still sure this feature should be also implemented one day.


Thanks,
Jan
Oleg Nesterov
2010-09-02 20:06:32 UTC
Permalink
Sorry for the delay, I was distracted. Trying to switch back to ugdb.
Post by Jan Kratochvil
Post by Jan Kratochvil
ugdb should support qXfer:siginfo, currently accessible only via $_siginfo
print/set, though.
Still sure this feature should be also implemented one day.
Yes sure. This should be simple, although I didn't expect qXfer
needs remote_escape_output() and x86_siginfo_fixup(). I assume
that qXfer:siginfo:read always mean Hg thread. It is not clear
to me what should ugdb report if there is no a valid siginfo.
linux_xfer_siginfo() return E01, but gdbserver uses SIGSTOP to
stop the tracee, so it always has something to report. But ugdb
stop the tracee somewhere else, not in get_signal_to_deliver()
path.

Likewise, it is not clear what should ugdb do if gdb sends
$CSIG in this case. But this all is minor, I think.

I was going to send v8 which implements qXfer:siginfo:read and
continue with signal, but (oh, as always) hit the unexpected
problems. To the point, I had to add printk's to utrace.c to
understand what is wrong. Hopefully tomorrow.

Oleg.
Jan Kratochvil
2010-09-03 06:40:08 UTC
Permalink
I assume that qXfer:siginfo:read always mean Hg thread.
It seems so.
It is not clear to me what should ugdb report if there is no a valid
siginfo. linux_xfer_siginfo() return E01, but gdbserver uses SIGSTOP to
stop the tracee,
I find error more appropriate in such case.
Likewise, it is not clear what should ugdb do if gdb sends
$CSIG in this case.
Currently GDB does not do anything special, that is if there is siginfo for
signal SIGUSR1 but one does $C0B (SIGSEGV) does ptrace reset the siginfo or is
left the SIGUSR1 siginfo for SIGSEGV?
But this all is minor, I think.
As this is being discussed for GDB I would find enough to just make $_siginfo
accessible without these details.


Thanks,
Jan
Roland McGrath
2010-09-03 19:59:06 UTC
Permalink
Post by Jan Kratochvil
Currently GDB does not do anything special, that is if there is siginfo for
signal SIGUSR1 but one does $C0B (SIGSEGV) does ptrace reset the siginfo or is
left the SIGUSR1 siginfo for SIGSEGV?
The kernel considers this sloppy behavior on the debugger's part. If
you inject a different signal, we expect you should PTRACE_SETSIGINFO
to something appropriate, or else that you really didn't care about
the bits being accurate. If the resumption signal does not match the
siginfo_t.si_signo, then the kernel resets the siginfo as if the
debugger had just used kill with the new signal (i.e. si_pid, si_uid
point to the ptracer).


Thanks,
Roland
Jan Kratochvil
2010-09-03 20:02:53 UTC
Permalink
Post by Roland McGrath
Post by Jan Kratochvil
Currently GDB does not do anything special, that is if there is siginfo for
signal SIGUSR1 but one does $C0B (SIGSEGV) does ptrace reset the siginfo or is
left the SIGUSR1 siginfo for SIGSEGV?
The kernel considers this sloppy behavior on the debugger's part. If
you inject a different signal, we expect you should PTRACE_SETSIGINFO
to something appropriate, or else that you really didn't care about
the bits being accurate. If the resumption signal does not match the
siginfo_t.si_signo, then the kernel resets the siginfo as if the
debugger had just used kill with the new signal (i.e. si_pid, si_uid
point to the ptracer).
OK, that seems to me as the best choice. Sorry I did not test/read it.


Thanks,
Jan
Roland McGrath
2010-09-03 20:10:23 UTC
Permalink
Post by Jan Kratochvil
OK, that seems to me as the best choice. Sorry I did not test/read it.
No need for you to do so. That's why you have kernel hackers to consult.

Thanks,
Roland
Oleg Nesterov
2010-09-03 23:09:57 UTC
Permalink
Post by Jan Kratochvil
Post by Oleg Nesterov
Likewise, it is not clear what should ugdb do if gdb sends
$CSIG in this case.
Currently GDB does not do anything special, that is if there is siginfo for
signal SIGUSR1 but one does $C0B (SIGSEGV) does ptrace reset the siginfo or is
left the SIGUSR1 siginfo for SIGSEGV?
The kernel changes siginfo->si_signo (and updates other fields). So
does ugdb.

But I meant another case, when the stopped tracee doesn't have siginfo.
Currently ugdb just sends this signal to tracee, and then it will be
reported to gdb. Not sure if this is right or not, I can change this.
(or perhap this doesn't matter, I dunno).

Oleg.
Roland McGrath
2010-09-10 10:14:52 UTC
Permalink
Post by Oleg Nesterov
But I meant another case, when the stopped tracee doesn't have siginfo.
Currently ugdb just sends this signal to tracee, and then it will be
reported to gdb. Not sure if this is right or not, I can change this.
(or perhap this doesn't matter, I dunno).
What do you mean by "doesn't have siginfo"? You mean non-signal stops?
What non-signal stops does ugdb report?


Thanks,
Roland
Oleg Nesterov
2010-09-10 18:29:03 UTC
Permalink
Post by Roland McGrath
Post by Oleg Nesterov
But I meant another case, when the stopped tracee doesn't have siginfo.
Currently ugdb just sends this signal to tracee, and then it will be
reported to gdb. Not sure if this is right or not, I can change this.
(or perhap this doesn't matter, I dunno).
What do you mean by "doesn't have siginfo"? You mean non-signal stops?
Yes.
Post by Roland McGrath
What non-signal stops does ugdb report?
(gdb) interrupt

ugdb sets "please stop" flag and does utrace_control(INTERRUPT). However,
in unlikely case the tracee can stop before ->report_signal() reporting
loop (especially in multitracing case). Or it can be already stopped
(note: this needs a separate discussion, currently ugdb intentionally
doesn't handle this case).

And. With the current implementation, even if the tracee stops after
ugdb_report_signal() was called, it doesn't setup ->t_siginfo.

IOW. If the tracee actually recieves a signal, then

- qXfer:siginfo:read works

- "signal SIG" works as expected (delivered to tracee)

Otherwise

- qXfer:siginfo:read reports E01

- "signal XX" means TXX report.

Once again, this can be changed (fixed?), but I am not sure this
should be changed.

Oleg.
Roland McGrath
2010-09-10 19:05:47 UTC
Permalink
Post by Oleg Nesterov
ugdb sets "please stop" flag and does utrace_control(INTERRUPT). However,
in unlikely case the tracee can stop before ->report_signal() reporting
I don't think this is the right thing to do. When the intent is explicitly
to interrupt, there is no reason to stop before the interruption is
complete, i.e. report_signal. If you only stop there, then you can always
process a signal injection with complete flexibility. The gdb model and
the remote protocol doesn't currently have any concept of requesting a stop
that is not an interruption.


Thanks,
Roland
Oleg Nesterov
2010-09-10 19:20:01 UTC
Permalink
Post by Roland McGrath
Post by Oleg Nesterov
ugdb sets "please stop" flag and does utrace_control(INTERRUPT). However,
in unlikely case the tracee can stop before ->report_signal() reporting
I don't think this is the right thing to do. When the intent is explicitly
to interrupt, there is no reason to stop before the interruption is
complete, i.e. report_signal.
This means that ugdb_report_quiesce() should never return UTRACE_STOP,
and that is all.

But what about multitracing? Suppose that "(gdb) interrupt" happens
just before, say, do_report_syscall_entry() and another engine wants
to stop. If ugdb_report_quiesce() doesn't return UTRACE_STOP, then
gdb will wait until another debugger resumes the tracee.

What do you think?
Post by Roland McGrath
If you only stop there, then you can always
process a signal injection with complete flexibility.
Yes, sure (again, currently ugdb does not injection a signal even
if the tracee was stopped in report_signal, but of course we can
change this).

Oleg.
Roland McGrath
2010-10-13 07:23:46 UTC
Permalink
Post by Oleg Nesterov
Post by Roland McGrath
Post by Oleg Nesterov
ugdb sets "please stop" flag and does utrace_control(INTERRUPT). However,
in unlikely case the tracee can stop before ->report_signal() reporting
I don't think this is the right thing to do. When the intent is explicitly
to interrupt, there is no reason to stop before the interruption is
complete, i.e. report_signal.
This means that ugdb_report_quiesce() should never return UTRACE_STOP,
and that is all.
I'm not sure about this.
Post by Oleg Nesterov
But what about multitracing? Suppose that "(gdb) interrupt" happens
just before, say, do_report_syscall_entry() and another engine wants
to stop. If ugdb_report_quiesce() doesn't return UTRACE_STOP, then
gdb will wait until another debugger resumes the tracee.
Yes, I do think that's a problem. We want gdb to report back promptly.
One possibility is to have report_quiesce notice its argument is
UTRACE_EVENT(SYSCALL_ENTRY) and roll back to before the syscall.
That is, it enables SYSCALL_ENTRY and SYSCALL_EXIT reporting, then
its report_syscall_entry uses UTRACE_SIGNAL_ABORT, report_syscall_exit
does syscall_set_return_value(-ERESTARTNOHAND, 0) and then returns
UTRACE_INTERRUPT. Now, we'll reenter a UTRACE_SIGNAL_REPORT callback
"before" the system call, and we can stop there without being in any
sticky situation.


Thanks,
Roland
Oleg Nesterov
2010-10-15 14:28:15 UTC
Permalink
Post by Roland McGrath
Post by Oleg Nesterov
Post by Roland McGrath
Post by Oleg Nesterov
ugdb sets "please stop" flag and does utrace_control(INTERRUPT). However,
in unlikely case the tracee can stop before ->report_signal() reporting
I don't think this is the right thing to do. When the intent is explicitly
to interrupt, there is no reason to stop before the interruption is
complete, i.e. report_signal.
This means that ugdb_report_quiesce() should never return UTRACE_STOP,
and that is all.
I'm not sure about this.
Ignoring the problems below, why?
Post by Roland McGrath
Post by Oleg Nesterov
But what about multitracing? Suppose that "(gdb) interrupt" happens
just before, say, do_report_syscall_entry() and another engine wants
to stop. If ugdb_report_quiesce() doesn't return UTRACE_STOP, then
gdb will wait until another debugger resumes the tracee.
Yes, I do think that's a problem. We want gdb to report back promptly.
One possibility is to have report_quiesce notice its argument is
UTRACE_EVENT(SYSCALL_ENTRY) and roll back to before the syscall.
That is, it enables SYSCALL_ENTRY and SYSCALL_EXIT reporting, then
its report_syscall_entry uses UTRACE_SIGNAL_ABORT, report_syscall_exit
does syscall_set_return_value(-ERESTARTNOHAND, 0) and then returns
UTRACE_INTERRUPT. Now, we'll reenter a UTRACE_SIGNAL_REPORT callback
"before" the system call, and we can stop there without being in any
sticky situation.
Well, but this doesn't look friendly to other engines...

And at first glance this looks a bit too hairy. And, this doesn't
cover another case: gdb asks to stop the tracee when it is already
stopped by another engine and sleeps in utrace_resume() path.

So, I think ugdb should be changed so that "signal SIG" always works
(without reporing this signal) even when the stopped tracee doesn't
have the signal context.

As for $_siginfo (qXfer:siginfo:read::), I do not know what ugdb
should do. Probably it can just report the all-zeroes siginfo or
report si_signo = SIGSTOP.

Oleg.

Frank Ch. Eigler
2010-09-03 14:17:26 UTC
Permalink
[...] To the point, I had to add printk's to utrace.c to understand
what is wrong. Hopefully tomorrow.
You might wish to try out systemtap for such purposes. It's easy to
insert printk-like tracing at almost any point; monitor variables for
changes, pretty-print structs, etc. No recompilation/reboot.

- FChE
Oleg Nesterov
2010-09-03 22:57:38 UTC
Permalink
Post by Frank Ch. Eigler
[...] To the point, I had to add printk's to utrace.c to understand
what is wrong. Hopefully tomorrow.
You might wish to try out systemtap for such purposes. It's easy to
insert printk-like tracing at almost any point; monitor variables for
changes, pretty-print structs, etc.
Probably I should try the new versions...

Last time I tried systemtap more than year ago. It didn't work for me
without the "properly installed" kernel/etc which I don't have. And,
I doubt I can insert the probe at the needed line without DEBUG_INFO.
Post by Frank Ch. Eigler
No recompilation/reboot.
CONFIG_KPROBE ;)

But anyway I agree, systemtap is the great tool.

Oleg.
Loading...