Screenshot instructions:
Windows
Mac
Red Hat Linux
Ubuntu
Click URL instructions:
Right-click on ad, choose "Copy Link", then paste here →
(This may not be possible with some types of ads)
From: Martin Schwidefsky <schwidefsky@de...> - 2005-04-28 13:04:25
|
Bodo Stroesser <bstroesser@...> wrote on 04/28/2005 11:54:17 AM: > > This patch is not good. !entryexit indicates that you want to change the trap > > indication on the first of the two calls of syscall_trace for a system call. The > > second condition is gprs[2] < 0 but that can be true for a normal system call as > > well, like sys_exit(-1). > Sorry, that's not right. At that point, gprs[2] holds the syscall number, while the > first argument of the syscall is in origgpr2. If the debugger sets the syscall number > to -1, which is an invalid syscall, changing trap to -1 will result in a changed > behavior only in case, that the debugger on the second syscall interception also sets > the syscall result to ERESTARTXXXXX (This again is modifying gprs[2]). ERESTARTXXXXX > normally would/could be handled by do_signal(), but with the patch it no longer will. > So, I think the patch doesn't hurt in normal cases, but does the trick for UML. Yes, your are right. gprs[2] holds the syscall number for the debugger to change. So (!entryexit & regs->gprs[2] < 0) translates to the debugger changed the guest system call to something illegal on the first of the two ptrace calls. So the patch doesn't hurt for normal, non-ptraced operation but it might hurt other users of ptrace. > > Independent from that it do not understand why you need it at all. If the > > uml host intercepted and invalidated the guest system call the system restart > > indication bit _TIF_RESTART_SVC shouldn't be set because the guest didn't > > execute a system call. > Let my explain a bit more. UML invalidates UML-user's syscalls on the host, processes > the syscall itself and inserts the result into gprs[2] on the second syscall > interception. For nearly all syscalls ERESTARTXXXXX is a result not returned to user, > but handled in UML kernel internally. But that's not true for sys_(rt_)sigreturn. > The "result" of those is the original contents of gpr2 of the interrupted routine, > which accidentally also might be ERESTARTXXXXXXX (BTW, that's the reason for > sys_(rt_)sigreturn setting trap to -1 also). We skip UML's syscall restart handling > in this case, but we need to skip it in the host, too. Ok, I think I've understood the problem now. What you are basically have is a process running in a UML guest that happens to have -ERESTARTXXX in grp2 when it gets interrupted. A signal is delivered and on return from that signal with sys_(rt_)sigreturn >another< signal might be pending and then do_signal gets confused because of -ERESTARTXXX in grp2. For normal, non-uml operation restore_sigregs resets regs->trap to -1 which avoids the confusion. With UML the host intercepts sys_rt_sigreturn and does whatever needs to be done for the guest >except< resetting regs->trap to -1. So the problem seems to be that you need a ptrace interface to do that. I don't think it is a good idea to kludge syscall_trace to reset regs->trap under some conditions. blue skies, Martin Martin Schwidefsky Linux for zSeries Development & Services IBM Deutschland Entwicklung GmbH |
From: Bodo Stroesser <bstroesser@fu...> - 2005-04-27 20:22:10
|
I'm sending this mail again, because unfortunately I didn't receive any reply. It was sent the first time at April, 5th. Regards, Bodo Hi, currently I'm porting UML to s390 31-bit. A first 2.6.11 UML system already is running in UML-SKAS0 mode, which normally should run on an unpatched host (no skas3-patch). To make UML build and run on s390, I needed to do these two little changes (the patches are copy and paste. I hope that doesn't hurt, since they are very small): 1) UML includes some of the subarch's (s390) headers. I had to change one of them with the following one-liner, to make this compile. AFAICS, this change doesn't break compilation of s390 itself. ============================================================================== --- linux-2.6.11.orig/include/asm-s390/user.h 2004-12-09 18:45:02.000000000 +0100 +++ linux-2.6.11/include/asm-s390/user.h 2004-12-09 18:48:11.000000000 +0100 @@ -10,7 +10,7 @@ #define _S390_USER_H #include <asm/page.h> -#include <linux/ptrace.h> +#include <asm/ptrace.h> /* Core file format: The core file is written in such a way that gdb can understand it and provide useful information to the user (under linux we use the 'trad-core' bfd). There are quite a number of ============================================================================== 2) UML needs to intercept syscalls via ptrace to invalidate the syscall, read syscall's parameters and write the result with the result of UML's syscall processing. Also, UML needs to make sure, that the host does no syscall restart processing. On i386 for example, this can be done by writing -1 to orig_eax on the 2nd syscall interception (orig_eax is the syscall number, which after the interception is used as a "interrupt was a syscall" flag only. Unfortunately, s390 holds syscall number and syscall result in gpr2 and its "interrupt was a syscall" flag (trap) is unreachable via ptrace. So I changed the host to set trap to -1, if the syscall number is written to a negative value on the first syscall interception. I hope, this adds what UML needs without changing ptrace visibly to other ptrace users. (This isn't tested on a 2.6 host yet, because my host still is a 2.4.21 SuSE. But I've adapted this change to 2.4 and tested, it works.) ============================================================================== --- linux-2.6.11.orig/arch/s390/kernel/ptrace.c 2005-04-04 18:57:38.000000000 +0200 +++ linux-2.6.11/arch/s390/kernel/ptrace.c 2005-04-04 19:01:51.000000000 +0200 @@ -726,6 +726,13 @@ ? 0x80 : 0)); /* + * If debugger has set an invalid syscall number, + * we prepare to skip syscall restart handling + */ + if (!entryexit && (long )regs->gprs[2] < 0 ) + regs->trap = -1; + + /* * this isn't the same as continuing with a signal, but it will do * for normal use. strace only continues with a signal if the * stopping signal is not SIGTRAP. -brl ============================================================================== It would be very helpful for me, if these changes could go into s390 mainline. If there is something wrong with them, please help me find a better solution. Regards, Bodo |
From: Martin Schwidefsky <schwidefsky@de...> - 2005-04-28 08:37:47
|
Bodo Stroesser <bstroesser@...> wrote on 04/27/2005 10:21:58 PM: > I'm sending this mail again, because unfortunately I didn't receive > any reply. It was sent the first time at April, 5th. Sorry, I put it on the to-do pile and promptly forgot about it. > currently I'm porting UML to s390 31-bit. Nice... > To make UML build and run on s390, I needed to do these two little > changes (the patches are copy and paste. I hope that doesn't hurt, > since they are very small): > > 1) UML includes some of the subarch's (s390) headers. I had to > change one of them with the following one-liner, to make this > compile. AFAICS, this change doesn't break compilation of s390 > itself. This one isn't a problem. I'll add it to the repository. > 2) UML needs to intercept syscalls via ptrace to invalidate the syscall, > read syscall's parameters and write the result with the result of > UML's syscall processing. Also, UML needs to make sure, that the host > does no syscall restart processing. On i386 for example, this can be > done by writing -1 to orig_eax on the 2nd syscall interception > (orig_eax is the syscall number, which after the interception is used > as a "interrupt was a syscall" flag only. > Unfortunately, s390 holds syscall number and syscall result in gpr2 and > its "interrupt was a syscall" flag (trap) is unreachable via ptrace. > So I changed the host to set trap to -1, if the syscall number is written > to a negative value on the first syscall interception. > I hope, this adds what UML needs without changing ptrace visibly to other > ptrace users. > (This isn't tested on a 2.6 host yet, because my host still is a 2.4.21 SuSE. > But I've adapted this change to 2.4 and tested, it works.) > > > ============================================================================== > --- linux-2.6.11.orig/arch/s390/kernel/ptrace.c 2005-04-04 18:57: > 38.000000000 +0200 > +++ linux-2.6.11/arch/s390/kernel/ptrace.c 2005-04-04 19:01:51. > 000000000 +0200 > @@ -726,6 +726,13 @@ > ? 0x80 : 0)); > > /* > + * If debugger has set an invalid syscall number, > + * we prepare to skip syscall restart handling > + */ > + if (!entryexit && (long )regs->gprs[2] < 0 ) > + regs->trap = -1; > + > + /* > * this isn't the same as continuing with a signal, but it will do > * for normal use. strace only continues with a signal if the > * stopping signal is not SIGTRAP. -brl > ============================================================================== This patch is not good. !entryexit indicates that you want to change the trap indication on the first of the two calls of syscall_trace for a system call. The second condition is gprs[2] < 0 but that can be true for a normal system call as well, like sys_exit(-1). It might even be true for user addresses if we really extent the virtual address space to full 64 bit one day (and the hardware can do it with a 5 level paging table). To change regs->trap to -1 with the current condition is definitly wrong. Independent from that it do not understand why you need it at all. If the uml host intercepted and invalidated the guest system call the system restart indication bit _TIF_RESTART_SVC shouldn't be set because the guest didn't execute a system call. blue skies, Martin Martin Schwidefsky Linux for zSeries Development & Services IBM Deutschland Entwicklung GmbH |
From: Bodo Stroesser <bstroesser@fu...> - 2005-04-28 09:54:24
|
Martin Schwidefsky wrote: > Bodo Stroesser <bstroesser@...> wrote on 04/27/2005 > 10:21:58 PM: >>1) UML includes some of the subarch's (s390) headers. I had to >> change one of them with the following one-liner, to make this >> compile. AFAICS, this change doesn't break compilation of s390 >> itself. > > > This one isn't a problem. I'll add it to the repository. Thank you! > > >>============================================================================== >>--- linux-2.6.11.orig/arch/s390/kernel/ptrace.c 2005-04-04 18:57: >>38.000000000 +0200 >>+++ linux-2.6.11/arch/s390/kernel/ptrace.c 2005-04-04 19:01:51. >>000000000 +0200 >>@@ -726,6 +726,13 @@ >> ? 0x80 : 0)); >> >> /* >>+ * If debugger has set an invalid syscall number, >>+ * we prepare to skip syscall restart handling >>+ */ >>+ if (!entryexit && (long )regs->gprs[2] < 0 ) >>+ regs->trap = -1; >>+ >>+ /* >> * this isn't the same as continuing with a signal, but it will do >> * for normal use. strace only continues with a signal if the >> * stopping signal is not SIGTRAP. -brl >>============================================================================== > > > This patch is not good. !entryexit indicates that you want to change the trap > indication on the first of the two calls of syscall_trace for a system call. The > second condition is gprs[2] < 0 but that can be true for a normal system call as > well, like sys_exit(-1). Sorry, that's not right. At that point, gprs[2] holds the syscall number, while the first argument of the syscall is in origgpr2. If the debugger sets the syscall number to -1, which is an invalid syscall, changing trap to -1 will result in a changed behavior only in case, that the debugger on the second syscall interception also sets the syscall result to ERESTARTXXXXX (This again is modifying gprs[2]). ERESTARTXXXXX normally would/could be handled by do_signal(), but with the patch it no longer will. So, I think the patch doesn't hurt in normal cases, but does the trick for UML. > It might even be true for user addresses if we really > extent the virtual address space to full 64 bit one day (and the hardware can do > it with a 5 level paging table). To change regs->trap to -1 with the current > condition is definitly wrong. > Independent from that it do not understand why you need it at all. If the > uml host intercepted and invalidated the guest system call the system restart > indication bit _TIF_RESTART_SVC shouldn't be set because the guest didn't > execute a system call. Let my explain a bit more. UML invalidates UML-user's syscalls on the host, processes the syscall itself and inserts the result into gprs[2] on the second syscall interception. For nearly all syscalls ERESTARTXXXXX is a result not returned to user, but handled in UML kernel internally. But that's not true for sys_(rt_)sigreturn. The "result" of those is the original contents of gpr2 of the interrupted routine, which accidentally also might be ERESTARTXXXXXXX (BTW, that's the reason for sys_(rt_)sigreturn setting trap to -1 also). We skip UML's syscall restart handling in this case, but we need to skip it in the host, too. > > blue skies, > Martin > > Martin Schwidefsky > Linux for zSeries Development & Services > IBM Deutschland Entwicklung GmbH Regards, Bodo |
From: Martin Schwidefsky <schwidefsky@de...> - 2005-04-28 13:04:25
|
Bodo Stroesser <bstroesser@...> wrote on 04/28/2005 11:54:17 AM: > > This patch is not good. !entryexit indicates that you want to change the trap > > indication on the first of the two calls of syscall_trace for a system call. The > > second condition is gprs[2] < 0 but that can be true for a normal system call as > > well, like sys_exit(-1). > Sorry, that's not right. At that point, gprs[2] holds the syscall number, while the > first argument of the syscall is in origgpr2. If the debugger sets the syscall number > to -1, which is an invalid syscall, changing trap to -1 will result in a changed > behavior only in case, that the debugger on the second syscall interception also sets > the syscall result to ERESTARTXXXXX (This again is modifying gprs[2]). ERESTARTXXXXX > normally would/could be handled by do_signal(), but with the patch it no longer will. > So, I think the patch doesn't hurt in normal cases, but does the trick for UML. Yes, your are right. gprs[2] holds the syscall number for the debugger to change. So (!entryexit & regs->gprs[2] < 0) translates to the debugger changed the guest system call to something illegal on the first of the two ptrace calls. So the patch doesn't hurt for normal, non-ptraced operation but it might hurt other users of ptrace. > > Independent from that it do not understand why you need it at all. If the > > uml host intercepted and invalidated the guest system call the system restart > > indication bit _TIF_RESTART_SVC shouldn't be set because the guest didn't > > execute a system call. > Let my explain a bit more. UML invalidates UML-user's syscalls on the host, processes > the syscall itself and inserts the result into gprs[2] on the second syscall > interception. For nearly all syscalls ERESTARTXXXXX is a result not returned to user, > but handled in UML kernel internally. But that's not true for sys_(rt_)sigreturn. > The "result" of those is the original contents of gpr2 of the interrupted routine, > which accidentally also might be ERESTARTXXXXXXX (BTW, that's the reason for > sys_(rt_)sigreturn setting trap to -1 also). We skip UML's syscall restart handling > in this case, but we need to skip it in the host, too. Ok, I think I've understood the problem now. What you are basically have is a process running in a UML guest that happens to have -ERESTARTXXX in grp2 when it gets interrupted. A signal is delivered and on return from that signal with sys_(rt_)sigreturn >another< signal might be pending and then do_signal gets confused because of -ERESTARTXXX in grp2. For normal, non-uml operation restore_sigregs resets regs->trap to -1 which avoids the confusion. With UML the host intercepts sys_rt_sigreturn and does whatever needs to be done for the guest >except< resetting regs->trap to -1. So the problem seems to be that you need a ptrace interface to do that. I don't think it is a good idea to kludge syscall_trace to reset regs->trap under some conditions. blue skies, Martin Martin Schwidefsky Linux for zSeries Development & Services IBM Deutschland Entwicklung GmbH |
From: Bodo Stroesser <bstroesser@fu...> - 2005-04-28 13:41:47
|
Martin Schwidefsky wrote: > So (!entryexit & regs->gprs[2] < 0) translates to the debugger changed the > guest > system call to something illegal on the first of the two ptrace calls. So > the > patch doesn't hurt for normal, non-ptraced operation but it might hurt > other > users of ptrace. I don't think, it hurts. If a debugger willingly sets the syscall number to -1, what would happen without the patch? The kernel will set the result -ENOSYS into grps[2]. So, even if trap still indicates a syscall and a signal is pending, no syscall restarting will be done. With the patch, a debugger would observe changed behavior of the kernel *only*, if it writes the syscall number to -1 on the first syscall interception and then writes the result to ERESTARTXXXXX on the second, while at the same time a signal is pending for the debugged process. I assumed, that non of the current users of ptrace exactly does this. If I'm wrong here, the patch *really* is bad. > Ok, I think I've understood the problem now. What you are basically have is > a process running in a UML guest that happens to have -ERESTARTXXX in grp2 > when it gets interrupted. A signal is delivered and on return from that > signal > with sys_(rt_)sigreturn >another< signal might be pending and then > do_signal > gets confused because of -ERESTARTXXX in grp2. This other signal must be pending on the *host*, in UML, this might be SIGVTALRM. > For normal, non-uml operation > restore_sigregs resets regs->trap to -1 which avoids the confusion. With > UML > the host intercepts sys_rt_sigreturn and does whatever needs to be done for > the guest >except< resetting regs->trap to -1. So the problem seems to be > that you need a ptrace interface to do that. I don't think it is a good > idea > to kludge syscall_trace to reset regs->trap under some conditions. My idea was to enable the existing ptrace interface to do what UML needs, without changing it in a way observable to other users of ptrace. I expected my patch to exactly do that, but maybe I missed something. Any better idea is welcome. Regards, Bodo |
From: Bodo Stroesser <bstroesser@fu...> - 2005-04-28 15:03:05
|
Bodo Stroesser wrote: > Martin Schwidefsky wrote: > >> So (!entryexit & regs->gprs[2] < 0) translates to the debugger changed >> the >> guest >> system call to something illegal on the first of the two ptrace calls. So >> the >> patch doesn't hurt for normal, non-ptraced operation but it might hurt >> other >> users of ptrace. > > I don't think, it hurts. If a debugger willingly sets the syscall number > to -1, what would happen without the patch? > The kernel will set the result -ENOSYS into grps[2]. So, even if trap > still indicates a syscall and a signal is pending, no syscall restarting > will be done. > With the patch, a debugger would observe changed behavior of the kernel > *only*, if it writes the syscall number to -1 on the first syscall > interception and then writes the result to ERESTARTXXXXX on the second, > while at the same time a signal is pending for the debugged process. > > I assumed, that non of the current users of ptrace exactly does this. > If I'm wrong here, the patch *really* is bad. Addendum: To avoid any conflicts as far as possible, the -1 written and checked as the syscall number to reset trap could be replaced by some magic value, which then should defined in asm/ptrace.h In terms of performance, any method, that allows to reset trap without an additional ptrace call, is fine. Bodo |
From: Martin Schwidefsky <schwidefsky@de...> - 2005-04-28 15:28:43
|
Bodo Stroesser <bstroesser@...> wrote on 04/28/2005 03:41:39 PM: > Martin Schwidefsky wrote: > > So (!entryexit & regs->gprs[2] < 0) translates to the debugger changed the guest > > system call to something illegal on the first of the two ptrace calls. So the > > patch doesn't hurt for normal, non-ptraced operation but it might hurt other > > users of ptrace. > I don't think, it hurts. If a debugger willingly sets the syscall number > to -1, what would happen without the patch? > The kernel will set the result -ENOSYS into grps[2]. So, even if trap > still indicates a syscall and a signal is pending, no syscall restarting > will be done. Why should the kernel set the result to -ENOSYS? If the debugger invalidated the system call, entry.S will just skip the system call and gprs[2] will keep the value that the debugger put there. But if regs->traps still indicates a system call and there is another signal pending do_signal will try to restart the system call. In case of sys_(rt_)return there is no system call anymore because the debugger = UML took care of it. That's why UML wants to have access to regs->traps. > With the patch, a debugger would observe changed behavior of the kernel > *only*, if it writes the syscall number to -1 on the first syscall > interception and then writes the result to ERESTARTXXXXX on the second, > while at the same time a signal is pending for the debugged process. In theory the debugger may want to intercept specific system calls and do magic things instead but still want to have the system call restarting to intercept it again after the (guest) signal has been delivered. You just don't know. > I assumed, that non of the current users of ptrace exactly does this. > If I'm wrong here, the patch *really* is bad. At least strace and gdb won't do it. > > Ok, I think I've understood the problem now. What you are basically have is > > a process running in a UML guest that happens to have -ERESTARTXXX in grp2 > > when it gets interrupted. A signal is delivered and on return from that signal > > with sys_(rt_)sigreturn >another< signal might be pending and then do_signal > > gets confused because of -ERESTARTXXX in grp2. > This other signal must be pending on the *host*, in UML, this might be > SIGVTALRM. Why on the host ?!? Now I'm really confused. I thought the problem is the regs->trap value in the guest system, how can a signal pending in the host have an effect on the guest? > > For normal, non-uml operation > > restore_sigregs resets regs->trap to -1 which avoids the confusion. With UML > > the host intercepts sys_rt_sigreturn and does whatever needs to be done for > > the guest >except< resetting regs->trap to -1. So the problem seems to be > > that you need a ptrace interface to do that. I don't think it is a good idea > > to kludge syscall_trace to reset regs->trap under some conditions. > My idea was to enable the existing ptrace interface to do what UML > needs, without changing it in a way observable to other users of ptrace. > I expected my patch to exactly do that, but maybe I missed something. > Any better idea is welcome. The patch does a very specific thing that UML needs, hardcoded into the ptrace interface. Who knows what kind of things other user of ptrace might need? I don't claim to know, and that is why I don't like to see this done in the syscall_ptrace function. Perhaps via peekusr/pokeuser interface but then trap should be a member of struct user. blue skies, Martin Martin Schwidefsky Linux for zSeries Development & Services IBM Deutschland Entwicklung GmbH |
From: Bodo Stroesser <bstroesser@fu...> - 2005-04-28 18:50:56
|
Martin Schwidefsky wrote: > Bodo Stroesser <bstroesser@...> wrote on 04/28/2005 > 03:41:39 PM: > > >>I don't think, it hurts. If a debugger willingly sets the syscall number >>to -1, what would happen without the patch? >>The kernel will set the result -ENOSYS into grps[2]. So, even if trap >>still indicates a syscall and a signal is pending, no syscall restarting >>will be done. > > > Why should the kernel set the result to -ENOSYS? If the debugger > invalidated > the system call, entry.S will just skip the system call and gprs[2] will > keep > the value that the debugger put there. You are right. I mixed it with i386, that has a separate field for the result, which is preloaded with -ENOSYS. On s390, the -1 written as the syscall number leads to entry.S calling nothing. If a signal is pending, do_signal() will interprete gprs[2] as syscall's result. Since -1 is -EPERM, no syscall restarting will be done, regardless the value of trap. The debugger would have to write gprs[2] with -1 on the first syscall interception *and* with ERESTARTXXXXX at the second syscall interception to see any changed behavior. > But if regs->traps still indicates a > system call and there is another signal pending do_signal will try to > restart > the system call. In case of sys_(rt_)return there is no system call anymore > because the debugger = UML took care of it. That's why UML wants to have > access to regs->traps. Yeah. >>>A signal is delivered and on return from that >>>signal >>>with sys_(rt_)sigreturn >another< signal might be pending and then >>>do_signal >>>gets confused because of -ERESTARTXXX in grp2. >> >>This other signal must be pending on the *host*, in UML, this might be >>SIGVTALRM. > > > Why on the host ?!? Now I'm really confused. I thought the problem is the > regs->trap value in the guest system, how can a signal pending in the host > have an effect on the guest? I think, your confusion results from the unclear terminology. UML is a full Linux, running as some user-space processes on the host. So, there can be signals pending in UML for the processes running in UML, but the host won't even know about that. On the other hand, there can be signals pending "in the host" for the user-space processes running on the host, that make up the UML. For example, UML intensely uses SIG(VT)ALRM as the analogue to host's timer interrupt. UML users never will "see" these signals. To make occur the problem, that results from host's unwanted syscall restarting, some condition must be met: 1) A process running in UML and having ERESTARTXXXXX in its GPR2 must be interrupted by a signal. As GPR2 never is ERESTARTXXXXX at the end of a "normal" syscall, this can happen only if a "interrupt" to UML (SIGVTALRM, SIGIO from the host to UML) hits this situation. 2) If interrupt processing in UML results in sending a signal in UML to the interrupted process (e.g. alarm timeout triggered) or if a signal already is pending in UML, UML starts the handler for the signal in the interrupted process. 3) The sighandler returns by calling sys_(rt_)sigreturn. 4) The ptracing process of UML intercepts that syscall and invalidates it. Then it does one further PTRACE_SYSCALL and waits, until the child reaches the second syscall interception. 5) UML runs its own sys_(rt_)sigreturn for the process, skips its own syscall restart processing and writes the registers of the child with the values, that result from sys_(rt_)sigreturn processing. Now GPR2 is loaded with ERESTARTXXXXXX again. 6) The child is resumed with PTRACE_SYSCALL. If a further signal is pending in the host for that child, the host runs do_signal(). As regs->trap still is set for a syscall, syscall restarting is processed in the host, the process in UML will fail. Obviously, this is a rare case. On i386, the syscall number is used as trap, so -1 can be written to it at the second interception to skip syscall restarting. Some months ago, UML/i386 did not yet use this, so I wrote a litte program, that made the problem happen. > > The patch does a very specific thing that UML needs, hardcoded into the > ptrace > interface. Who knows what kind of things other user of ptrace might need? I don't *know* this, too. But I still believe, that no current user of ptrace will see the difference, as very specific ptrace operations have to be done to trigger the change. If there really would be no user of ptrace doing things conflicting with the patch yet, there would be no reason to not insert the patch. AFAICS, the patch doesn't make any useful operation impossible. So future conflicts can be avoided by future users of ptrace. Additionally, the -1 could be replaced by -ENOSYS or even a special magic number. > I don't claim to know, and that is why I don't like to see this done in the > syscall_ptrace function. Perhaps via peekusr/pokeuser interface but then > trap should be a member of struct user. As trap could be added to struct user at the end of struct user only, this would result in an additional ptrace call in UML :-( Is it safe to increase size of struct user? What about software being recompiled partly (e.g. using a private lib which isn't recompiled; or the lib is recompiled, while the program isn't). So maybe an additional ptrace operation (PTRACE_SETTRAP?) would be better, but still we would need one more syscall in UML. Regards, Bodo |
From: Martin Schwidefsky <schwidefsky@de...> - 2005-04-29 11:48:45
|
Bodo Stroesser <bstroesser@...> wrote on 04/28/2005 08:50:44 PM: > 5) UML runs its own sys_(rt_)sigreturn for the process, skips its own > syscall restart processing and writes the registers of the child with > the values, that result from sys_(rt_)sigreturn processing. Now GPR2 > is loaded with ERESTARTXXXXXX again. > > 6) The child is resumed with PTRACE_SYSCALL. If a further signal is > pending in the host for that child, the host runs do_signal(). > As regs->trap still is set for a syscall, syscall restarting is > processed in the host, the process in UML will fail. That is what I was after, the additional signal that causes the problem is pending for the child, not for the ptrace father process. > Obviously, this is a rare case. On i386, the syscall number is used as > trap, so -1 can be written to it at the second interception to skip > syscall restarting. Some months ago, UML/i386 did not yet use this, so > I wrote a litte program, that made the problem happen. The rare cases are always the most complicated ones. To make UML work reliably this needs to get fixed. > > I don't claim to know, and that is why I don't like to see this done in the > > syscall_ptrace function. Perhaps via peekusr/pokeuser interface but then > > trap should be a member of struct user. > As trap could be added to struct user at the end of struct user only, this > would result in an additional ptrace call in UML :-( > > Is it safe to increase size of struct user? What about software being > recompiled partly (e.g. using a private lib which isn't recompiled; or the > lib is recompiled, while the program isn't). > So maybe an additional ptrace operation (PTRACE_SETTRAP?) would be better, > but still we would need one more syscall in UML. Yes, it is not a really good idea to add something to struct user. That will affect the dump format and debugging tools. So it would be an additional ptrace command like PTRACE_SETTRAP/PTRACE_GETTRAP. The only other solution I can think of is to be more specific about what the debugger can indicate to the debuggee what needs to be done after the first syscall_trace invocation. At the moment it is either 1) a valid system call number, execute the new syscall, or 2) an invalid system call number, skip the system call but don't change regs->traps and do system call restarting if another signal is pending If we use more specific error codes instead of just any invalid syscall number we could have e.g. this: 1) a vaild system call number, execute the new syscall, 2) -Exxx, skip the system call, store -1 to regs->trap and then continue with restarting system calls if another system call is pending. 3) -Eyyy, skip the system call but leave regs->trap intact so that a pending signal will restart the system call. But we really have to be very careful not to break either strace or gdb if we do this change. Probably it is much easier to introduce PTRACE_SET/GET_TRAP. blue skies, Martin Martin Schwidefsky Linux for zSeries Development & Services IBM Deutschland Entwicklung GmbH |
From: Bodo Stroesser <bstroesser@fu...> - 2005-04-29 12:47:58
|
Martin Schwidefsky wrote: > Yes, it is not a really good idea to add something to struct user. That will > affect the dump format and debugging tools. So it would be an additional ptrace > command like PTRACE_SETTRAP/PTRACE_GETTRAP. The only other solution I can think > of is to be more specific about what the debugger can indicate to the debuggee > what needs to be done after the first syscall_trace invocation. At the moment > it is either > 1) a valid system call number, execute the new syscall, or > 2) an invalid system call number, skip the system call but don't change > regs->traps and do system call restarting if another signal is pending > If we use more specific error codes instead of just any invalid syscall number > we could have e.g. this: > 1) a vaild system call number, execute the new syscall, > 2) -Exxx, skip the system call, store -1 to regs->trap and then continue > with restarting system calls if another system call is pending. Typo with<->without? Yes. That's what I suggested as a "special magic number". Only if that magic is written as syscall number at the first interception, syscall_trace() would modify regs->trap to -1. Currently my patch uses -1 as the magic number, but there might be better choices. > 3) -Eyyy, skip the system call but leave regs->trap intact so that a pending > signal will restart the system call. Not only -Eyyy, but all values unequal to "special magic number" could leave regs->trap intact. > > But we really have to be very careful not to break either strace or gdb if > we do this change. Probably it is much easier to introduce PTRACE_SET/GET_TRAP. It's easier for s390-kernel, but from UML's point of view, the magic number solution would be better. Anyway, if you decide not to allow the magic number, we have to find a way to use PTRACE_SETTRAP in UML without having to call it too often (Performance). Because of UML's splitting in kernel-obj and user-obj, this might be a bit tricky. BTW: I see no reason to implement PTRACE_GETTRAP, as PTRACE_SETOPTIONS/PTRACE_TRACESYSGOOD give us a way to distinguish between syscall interceptions and other SIGTRAPs. Regards, Bodo |