Date: Tue, 24 Nov 1998 16:13:05 +1030 From: Greg Lehey <grog@lemis.com> To: Joel Ray Holveck <joelh@gnu.org> Cc: SysAdmin <sa@ns.online.samara.ru>, freebsd-hackers@FreeBSD.ORG Subject: Re: breakpoint on i/o in kernel Message-ID: <19981124161305.W63366@freebie.lemis.com> In-Reply-To: <86af1hn411.fsf@detlev.UUCP>; from Joel Ray Holveck on Mon, Nov 23, 1998 at 09:49:46PM -0600 References: <AAnyMMsCYR@ns.online.samara.ru> <19981123205619.Q430@freebie.lemis.com> <86iug6mcnq.fsf@detlev.UUCP> <19981124093537.R430@freebie.lemis.com> <86af1hn411.fsf@detlev.UUCP>
next in thread | previous in thread | raw e-mail | index | archive | help
On Monday, 23 November 1998 at 21:49:46 -0600, Joel Ray Holveck wrote: >>> I don't know what CPUs have instrumentation for this. >> All i386 architectures, in varying degrees. > > Since I wrote that message, I dragged out my Intel docs so I could > follow along with the rest of the class. > >>> (It might theoretically be possible with GDB using a semicomplex >>> series of isteps and tests, but it would slow down your system >>> possibly hundredfold.) >> The correct thing to do would be to implement I/O (and memory access) >> breakpoints, not kludge it. > > Memory access breakpoints are already implemented: > > watch addr,size > Set a watchpoint for a region. Execution stops when an attempt to modify > the region occurs. The size argument defaults to 4. If you specify a > wrong space address, the request is rejected with an error message. Last time I looked, watchpoints worked by tracing the program and only stopping if the condition was met. That makes it ridiculously slow, especially if you're debugging over a serial line. It also applies only for write access, not for read access. Here's the relevant part of the documentation for Lowbug (September 1992): 3.1.2 Breakpoints Up to four breakpoints can be set using the hardware breakpoint facility of the 386 architecture. These enable breakpoints to be set not only on instructions but also on memory read and memory write. To set a breakpoint, enter b addr [option [, option]] for a persistent breakpoint or B addr [option [, option]] for a temporary breakpoint The first form (persistent breakpoint) will create a breakpoint which will remain in effect until explicitly removed. The second form (temporary breakpoint) will create a breakpoint which will go away as soon as it is encountered. This form is useful to get to a certain point and then forget the breakpoint. It is also used internally by the leave command. addr is an expression which represents a symbolic address. This is the first byte of the address upon which the breakpoint will be set. options modify the breakpoint action. They can be any combination of: a action [; action] After encountering the breakpoint, the commands specified as action are executed. The commands may be any valid Lowbug command, including instructions to con- tinue execution. If this happens, there may be no indication that the breakpoint was hit. Breakpoint actions are executed for each breakpoint whose condition is fulfilled, in the order of the breakpoint number (which corresponds to the hardware breakpoint register). In particular, if two breakpoint conditions are valid at the same time, and the action of the first (i.e. lower numbered) breakpoint involves a return to the program, the second breakpoint will not be recognised, and its actions will not be executed. Note that action may consist of several subcommands, separated by semicolons (;). Since this is also the Lowbug command delimiter, some restrictions are imposed. Breakpoint subcommands are separated by commas. The action subcommand is taken to start immediately after the letter a and to continue to the next comma or to the end of the input line. If something is input like b _myioctl#23,al;&;v;b;c the commands b and c will be considered part of the action and will be executed when the breakpoint is encountered. In order to continue execution immediately, enter b _myioctl#23,al;&;v,b;c It is probably better, however, to never put further instructions behind a breakpoint instruction. i[f] condition Only stop program execution if the expression condition evaluates to non-zero. l expr The memory address monitored by the breakpoint starts at the address addr; it continues for 1, 2 or 4 bytes. This length defaults to 1, but may be specified by the l subcommand. Note that alignment rules are enforced by 80386 and 80486 hardware; a length of 2 implies that the high-order 31 address bits are the same. In addition, an instruction breakpoint may only have a length of 1, and in the case of a multi-byte opcode, it must be on the first byte. A length of 4 implies that the high-order 30 address bits are the same. Lowbug will reject combinations of start address and length which do not adhere to the length and alignment rules, but it cannot detect when an instruction breakpoint is set on other than the first byte of an instruction. p pid The breakpoint only applies to process pid. It will be ignored for others. t type Normally, a breakpoint occurs when an instruction starting at address addr is exe- cuted. The 80386 and 80486 hardware also support breakpoints which occur when memory reads or write are made at the specified location. This is specified with the t subcommand: type may be one of i (default), for instruction breakpoint, w, memory write - a breakpoint trap will occur after the memory write occurs; or m - memory read or write breakpoint. An breakpoint trap will occur after a data word is transferred to the memory location, a trap will not occur on an instruction fetch. Breakpoints slow the execution of the program minimally, since some of the internal pipelining of the chip must be turned off in order to get the correct address for the breakpoint return. In practice, this does not make much difference unless many "invisible" conditional breakpoints are executed. >> I look at it once, and the code turned my stomach. > > Was this for kdb, ddb, or kgdb? I don't know much about ddb. gdb. ddb is too limited to be of much use. > Going over its code, it appears that ddb uses the VMM to handle > watchpoints instead of using the processor's debugging > instrumentation. (This is fine with me, and more portable to boot.) The question is speed. > A quick review doesn't show any major problems implementing I/O > breakpoints. Is there any reason that the same entry mechanism to > enter ddb on a page fault couldn't also enter ddb on a debug > exception? If that's the case, then it would appear that all we need > to do is to write something to manage four I/O breakpoints and we've > got the basics. The main reason is that it's so slow as to be unusable. We have an alternative which *is* usable. > gdb already has some instrumentation for hardware breakpoints; it may > be extendable to allow for this sort of thing. I haven't looked into > that. It must be new, then. If you point me to it, I may take a look at it. >>> I generally recommend another method of debugging than I/O >>> breakpoints. >> >> That's a workaround, not a solution. I/O breakpoints are really >> useful. > > Yes, but they are also frequently misused. I myself used to be a > frequent debugger abuser, and would rely on the debugger instead of > thinking about the driver and knowing what's going on wrong. Sure, there's a certain tendency to do that. That doesn't make the tool bad, though. > And now I hope that I'm not starting a holy war. Who knows? :-) Greg -- See complete headers for address, home page and phone numbers finger grog@lemis.com for PGP public key To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19981124161305.W63366>