The invention relates to the field of software code debugging
In the field of computer science, the term “software”, “code”, or “software code” often refers to a collection of statements and/or declarations written in a programming language to specify actions to be performed by a processing device. The processing device may be a general purpose computer or a dedicated device that is directed to a specific activity or function.
Like any other development process for a complex design, it is important to ensure that the process for developing software involves adequate testing and verification of the performance and functionality of the software. For software in particular, it is quite common during the development process to discover errors or “bugs” in the programming code. Many different types of errors may occur in a software program. For example, such errors can be syntax errors, semantic errors, or logic errors. The syntax error occurs when code is written in a manner not allowed by the rules of the language, and is the one type of error that can be easily caught by a compiler or interpreter.
A semantic error occurs when the syntax of the code is correct, but the semantics or meaning is not what was intended. A logic error occurs when the algorithmic flow of the software does not perform or produce a result that is intended, even if the semantics or syntax of the coding is correct. Because the semantic and logic errors can occur even if the coding obeys the language (syntax) rules, semantic and logic errors cannot typically be identified by the compiler or interpreter. Therefore, a software developer will often need to engage in debugging activities to address errors that are semantic or logic in nature.
The debugging activity is typically performed to allow the programmer or test engineer to observe the run-time behavior of the software program and to determine the location, cause, environment, or effect of the errors. With the debugging process or using a debugging tool, one can examine the content of variables or memory, insert stopping points, and/or step through the execution of the program. Once the cause of the error is identified, the developer can then modify the code to correct the problem.
When an error is encountered in software code, there are two common approaches that are often taken to debug the: (a) the recompilation approach and (b) the interpreter approach.
In the recompilation approach, the erroneous software program is recompiled for debugging purposes, by introducing debugging information into the compiled code. Since, in the interests of maximal time and execution efficiency, the original executable from which the error was discovered is usually formed as compiled optimized executables that do not include debug information, the debug information needs to be added to accomplish the debugging goals of the programmer. This approach, however, is associated with some significant performance problems. First, this approach requires the time and expense of performing a recompilation of the software. In addition, the recompilation in debugging mode typically precludes compilation optimizations from being used in the recompiled code. This means that the recompiled code in debugging mode will execute slower and/or less efficiently than the original compiled code that does include the optimizations.
In the interpreter approach, an interpreter is used to execute the software program. The interpreter is a program that can execute source code directly without compilation, or can use an intermediate representation of the source code for execution purposes. In many cases, the interpreter allows the software to be executed interactively. The main advantage of the interpreter approach over the recompilation approach is that the interpreter approach avoids the time and expense of having to recompile the software code. The disadvantage of this approach is that software execution using an interpreter is usually much, much slower than software execution of compiled software.
Therefore, there is a need for an improved approach for debugging software which can retain the best benefits of the recompilation and interpreter approaches, but without the corresponding drawbacks.
The present invention provides an improved approach for debugging errors in software code. According to some embodiments of the invention, techniques are provided for performing on-the-fly switching from compiled to interpretive debugging for a software program. The test starts with compiled code, and when it needs to stop for debugging, the debugging occurs in interpretive mode. Once debugging has concluded, the execution can switch back to compiled mode. In this way, the debugging activities can achieve the speed and efficiency of using compiled optimized executables, while still being able to allow debugging without performing any recompilations.
Further details of aspects, objects, and advantages of the invention are described below in the detailed description, drawings, and claims. Both the foregoing general description and the following detailed description are exemplary and explanatory, and are not intended to be limiting as to the scope of the invention.
The present invention provides an improved approach for debugging errors in software code. According to some embodiments of the invention, techniques are provided for performing on-the-fly switching from compiled to interpretive debugging for a software program. The test starts with compiled code, and when it needs to stop for debugging, the debugging occurs in interpretive mode. Once debugging has concluded, the execution can switch back to compiled mode. In this way, the debugging activities can achieve the speed and efficiency of using compiled optimized executables, while still being able to allow debugging without performing any recompilations.
Section 102 represents the conventional interpreter approach to debugging, in which an interpreter is used without recompilation to debug the error. Even though this approach allows the software to be re-executed almost immediately without waiting for recompilation, the problem is that interpreted execution is much slower than compiled execution. This means that the interpreted execution will take much longer than X number of hours to reach the same point at which the error had occurred, before debugging can even begin. In addition, even though only a small portion of the code may contain an error that needs to be debugged, this approach requires the entire software to be run using the slow interpreter execution. The multiplier “[2 . . . 8]” represents the increased time needed to execute interpreted code as compared to the compiled code.
Section 104 represents the conventional recompilation approach for debugging, in which the software code is recompiled with debug information but without compiler optimizations. This approach requires the expense of an additional Y number of hours to perform the recompilation. Moreover, this approach results in a non-optimized executable that will take longer than X number of hours to execute to reach the point of the error, at which debugging can occur to address the originally identified error. The multiplier “[1.1 . . . 2]” represents the increased time needed to execute the un-optimized re-compiled code as compared to the optimized compiled code.
Section 106 represents execution of existing code with interactive debugging according to embodiments of the invention. In this approach, the existing compiled code with optimizations can be executed up to the point of the error, taking the same X number of hours as the original executable. When the point of the error is reached, however, the present embodiment switches to an interpretive mode to perform the interactive debugging. Once the debugging has finished, execution can resume for the compiled version of the code.
Therefore, the invention provides the best advantages of both the re-compilation and interpreted approaches without the drawbacks, where execution of the non-erroneous portions of the code can occur using the much faster optimized and compiled versions of the software. The debugging run can begin without taking the time and expense of performing a re-compilation. Instead, only upon the point of the error will debugging occur using an interactive interpretive mode. Once the point of error has passed, execution can resume using the optimized compiled version of the software.
The software 220 may be stored in a computer readable storage device 226. Computer readable storage device 226 comprises any combination of hardware and software that allows for ready access to the data that is located at the computer readable storage device 226. For example, computer readable storage device 226 could be implemented as computer memory operatively managed by an operating system. The computer readable storage device 226 could also be implemented as a storage system having storage on persistent and/or non-persistent storage. According to the present embodiment, the software 220 and debug results/reports 222 are placed into the computer readable storage device 226.
A debugger 218 may be used by users a user at user station 224 to debug software 220. The debugger 218 is utilized to perform an execution 206 of the software 220 using both compiled routine 240a and interpretive routines 240b. The compiled version of the software 220 is executed for the non-error portions of the execution run. However, at the points of error, the interpretive routines are executed to allow interactive debugging of the software 220.
According to some embodiments, the debugger 218 is enhanced with an ability to change the way method dispatching is performed. In this way, instead of calling the compiled routines 240a at a point of an error, the interpretive routines 240b will be used instead when the method is called. As the debugger 218 steps in a method, a breakpoint or a watch is inserted to initial the interpreted implementation of the method. This provides maximal visibility for the debugging functionality. As the debugger 218 leaves the method and breakpoints/watches are deleted, the compiled routine 240a can be used once again.
This inventive approach is quite different from an approach of hot-swapping two models (simulation and hardware) that exchange state information between them for debugging. In contrast, the present embodiment maintains a single model (a memory image with state information) and switches by calling either the compiled method or an interpreted one, or both accessing the same state information, intermixing execution of compiled and interpreted methods. This approach is also different from the technique often referred to as “Just In Time Compilation” (JIT), which starts with interpreted execution and over time compiles frequently visited code and substitutes. This is done for speed, and is only available for dynamic languages using byte-codes (such as Java™, Smalltalk, C#). In contrast the present invention (1) does not require a dynamic language (2) compiles off-line (3) does this for ease of debug, not performance.
At 306, configuration is performed so that the system can perform debugging using both compiled and interpretive portions. This configuration is performed to make sure that at the appropriate points in the execution of the software, the debugging process will correctly switch from one execution mode to the other.
At 308, debugging is performed by re-starting the execution using the compiled executable version of the software. However, upon reaching the point of the error, the interpretive version of the software is used to perform interactive debugging.
At 404, the compiled executable is loaded back into the system. In the present embodiment, it is the original, optimized, and compiled executable that is loaded at this point. This re-loading occurs for two reasons. First, the original executable is re-loaded so that an execution run can be started for debugging purposes. It is noted that since the original executable is being loaded, this means that re-compilation is not needed.
Second, the re-loading occurs so that, at 406, breakpoints can be established for the execution run. The breakpoints identify the points in execution at which a switch will occur from execution of the compiled executable to the interpreted version of the software. Therefore, the breakpoint should be defined before the point at which the error was encountered.
On a “break” (i.e., the breakpoint that is reached at the point of the error), the execution of the software is switched at 414 from the compiled version of the software to the interpreted version of the software. For object oriented languages such as Java™, C++, or ‘e’, a dispatch table can be modified to accomplish this action. When a method is called on object pointer, an address of a routine (routine pointer), which implements this method, is fetched from dispatch table. In an alternative approach, the debugger can implement the dispatch switching by changing the address globally inside loaded executables and libraries to the address of the interpreted version.
At 416, interactive debugging is performed. The interpreter is used to execute the interpreted version of the code portions corresponding to the error. Any suitable debugging activities may be performed at this stage.
On “continue” (i.e., after the point of the error), the execution is switched back to the compiled executable version of the software. If the dispatch table was modified to implement 414, then the original dispatch table entries are restored at this point. If hardcoded addresses was modified at 414, then that address is restored at this point.
The run is continued at 420 to proceed through the rest of the software execution. The above process is repeated upon encountering any additional breakpoints for previously identified errors that need to be debugged. Once the execution is finished, the process at 422 will exit.
To illustrate embodiments of the invention, reference will now be made to the example code portions shown in
At portion 510, breakpoint is established for the portion of the program that corresponds to the identified error. In particular, the breakpoint is established at the entry of the “a.f_i( )” statement in the software program, which was previously identified as corresponding to the error. It is noted that any suitable breakpoint syntax or mechanism may be employed within the scope of the invention, and the specific syntax shown here is for illustrative purposes only. The run is then started. Execution begins with the compiled optimized executable for the software. Each statement in the program is then executed using the compiled version of the software, up until the point of the breakpoint is reached.
At that point, at 512, the run is stopped on the break, at “step in”. The system at 514 changes to execution using the interpreted version of the software. Debugging can then proceed interactively using the interpreter.
Once execution reaches past the location of the error, on the “continue” at 516, a switch is made back to the compiled optimized executable. At 518, execution resumes with the compiled optimized executable version of the software. The execution run then continues until it is finished (unless there are any further breakpoints that need to be addressed).
As noted above, there are several approaches that can be taken to perform a switch between execution of compiled executable and interpreted executables. For example, for object oriented languages, methods are dispatched according to a virtual method table, or dispatch table, which is a data structure that bounds methods to an object instance in runtime. When a method is called on object pointer, an address of a routine (routine pointer), which implements this method, is fetched from dispatch table. If an address of a compiled routine is changed to an address of an interpreted routine, the latter will be used when this method is called for relevant object. Of course, interpreter must share the runtime environment with compiled code, including type system, memory management, etc.
At 604, a determination is made of the entry in the dispatch table that corresponds to the identified method. This entry in the dispatch table contains the pointer for the routines that will be executed upon a call of the method. Therefore, the pointer can be modified to point to the address of the interpreted routine if it is desired to switch to interpreted execution. The pointer can be modified to point to the address of the compiled routine if it is desired to switch to compiled execution. At 606, a determination is made whether the switch is from compiled execution to interpreted execution, or vice versa.
If the desired switch is upon encountering the breakpoint, then the switch is from the compiled execution to the interpreted execution. Therefore, at 610, the dispatch table entry is modified such that the address value points to the interpreted version of the executable routine.
If the desired switch is upon a “continue” after debugging has already occurred, then the switch is from the interpreted execution to the compiled execution. Therefore, at 608, the dispatch table entry is modified such that the address value points to the compiled version of the executable routine.
The top portion of the figure shows the situation when the dispatch table entry includes a pointer to the routine 704 corresponding to the fully optimized compiled routine for this method. Here, the pointer “rp2” is configured to include the address for routine 704. This situation corresponds to the scenario when the run has just started and the point of the error has not yet been reached. This situation also corresponds to the scenario after debugging has already occurred and the run is intended to execute with the compiled version of the executable.
The bottom portion of the figure shows the situation when the dispatch table entry is modified to include a pointer to the routine 706 corresponding to the interpreted routine for the method. Here, the pointer “rp2” is modified to include the address for routine 706. This situation corresponds to the scenario when the breakpoint has been encountered, and it is desired to execute in interpreted mode to perform interactive debugging.
Therefore, the routine pointer can be configured so that the desired implementation will be dispatched. If a switch from compiled implementation to interpreted implementation is desired, then the routine pointer is changed to include the address for the interpreted routine. If a switch from interpreted implementation to compiled implementation is desired, then the routine pointer is changed to include the address for the compiled routine.
In the case that the method or function is bound during compilation (as functions in C or non-virtual methods in C++) and is called using its address, and ‘hardwired’ in machine code, the debugger can still switch the dispatching by changing the address globally inside loaded executable and libraries to the address of the interpreted version. In other words, the method call in machine language can be configured to include the correct address pointer for the desired routine.
Instead of patching the whole executable, hardware or software breakpoint mechanism may be used: stop in machine code debugger when compiled routine is called and jump to execute the interpreted routine.
An interpreter for languages like C++, ‘e’, or C should be able to execute only some intermediate format (like AST), not source code directly line by line. It is preferred, but not necessary, to parse source code into such format before a debug run and save in a file to be loaded on start of debugging.
Therefore, what has been described is an improved method, system, mechanism, and program product for performing debugging.
System Architecture Overview
According to one embodiment of the invention, computer system 1400 performs specific operations by processor 1407 executing one or more sequences of one or more instructions contained in system memory 1408. Such instructions may be read into system memory 1408 from another computer readable/usable medium, such as static storage device 1409 or disk drive 1410. In alternative embodiments, hard-wired circuitry may be used in place of or in combination with software instructions to implement the invention. Thus, embodiments of the invention are not limited to any specific combination of hardware circuitry and/or software. In one embodiment, the term “logic” shall mean any combination of software or hardware that is used to implement all or part of the invention.
The term “computer readable medium” or “computer usable medium” as used herein refers to any medium that participates in providing instructions to processor 1407 for execution. Such a medium may take many forms, including but not limited to, non-volatile media and volatile media. Non-volatile media includes, for example, optical or magnetic disks, such as disk drive 1410. Volatile media includes dynamic memory, such as system memory 1408.
Common forms of computer readable media includes, for example, floppy disk, flexible disk, hard disk, magnetic tape, any other magnetic medium, CD-ROM, any other optical medium, punch cards, paper tape, any other physical medium with patterns of holes, RAM, programmable read only memory (PROM), erasable programmable read only memory (EPROM), FLASH-EPROM, any other memory chip or cartridge, or any other medium from which a computer can read.
In an embodiment of the invention, execution of the sequences of instructions to practice the invention is performed by a single computer system 1400. According to other embodiments of the invention, two or more computer systems 1400 coupled by communication link 1415 (e.g., local area network (LAN), public telephone switched network (PTSN), or wireless network) may perform the sequence of instructions required to practice the invention in coordination with one another.
Computer system 1400 may transmit and receive messages, data, and instructions, including program, e.g., application code, through communication link 1415 and communication interface 1414. Received program code may be executed by processor 1407 as it is received, and/or stored in disk drive 1410, or other non-volatile storage for later execution. Computer system 1400 may communicate through a data interface 1433 to a database 1432 on an external storage device 1431.
In the foregoing specification, the invention has been described with reference to specific embodiments thereof. It will, however, be evident that various modifications and changes may be made thereto without departing from the broader spirit and scope of the invention. For example, the above-described process flows are described with reference to a particular ordering of process actions. However, the ordering of many of the described process actions may be changed without affecting the scope or operation of the invention. The specification and drawings are, accordingly, to be regarded in an illustrative rather than restrictive sense.
Number | Name | Date | Kind |
---|---|---|---|
5764989 | Gustafsson et al. | Jun 1998 | A |
6009256 | Tseng et al. | Dec 1999 | A |
6249907 | Carter et al. | Jun 2001 | B1 |
6256752 | Blandy et al. | Jul 2001 | B1 |
6353923 | Bogle et al. | Mar 2002 | B1 |
6530075 | Beadle et al. | Mar 2003 | B1 |
6594783 | Dollin et al. | Jul 2003 | B1 |
6910206 | Nevill | Jun 2005 | B1 |
7134119 | Nevill | Nov 2006 | B2 |
7203926 | Bogle et al. | Apr 2007 | B2 |
7296257 | Dibble et al. | Nov 2007 | B1 |
7464373 | Yunt et al. | Dec 2008 | B1 |
7617084 | Koslow et al. | Nov 2009 | B1 |
7694278 | Pasumansky et al. | Apr 2010 | B2 |
7774172 | Yunt et al. | Aug 2010 | B1 |
7984304 | Waldspurger et al. | Jul 2011 | B1 |
8131523 | Yunt et al. | Mar 2012 | B1 |
8196107 | Stall et al. | Jun 2012 | B2 |
8271958 | Stall et al. | Sep 2012 | B2 |
8370816 | Farchi et al. | Feb 2013 | B2 |
8572578 | Stall | Oct 2013 | B2 |
8578339 | Day et al. | Nov 2013 | B2 |
8607199 | Kim et al. | Dec 2013 | B2 |
8677329 | Beretta et al. | Mar 2014 | B2 |
8745597 | Kandasamy et al. | Jun 2014 | B2 |
8776024 | Cabillic et al. | Jul 2014 | B2 |
8826244 | Kandasamy et al. | Sep 2014 | B2 |
20010005852 | Bogle et al. | Jun 2001 | A1 |
20020019976 | Patel et al. | Feb 2002 | A1 |
20020073375 | Hollander | Jun 2002 | A1 |
20020104077 | Charnell et al. | Aug 2002 | A1 |
20020108103 | Nevill | Aug 2002 | A1 |
20020108107 | Darnell et al. | Aug 2002 | A1 |
20020112227 | Kramskoy et al. | Aug 2002 | A1 |
20040015863 | McBrearty et al. | Jan 2004 | A1 |
20040210872 | Dorr et al. | Oct 2004 | A1 |
20040221272 | Wu et al. | Nov 2004 | A1 |
20060020921 | Pasumansky et al. | Jan 2006 | A1 |
20060064676 | Chavan | Mar 2006 | A1 |
20060164269 | Trimbell et al. | Jul 2006 | A1 |
20060253508 | Colton et al. | Nov 2006 | A1 |
20070157174 | Gebhardt et al. | Jul 2007 | A1 |
20070250819 | Fjeldstad et al. | Oct 2007 | A1 |
20080066059 | Pugh et al. | Mar 2008 | A1 |
20080263528 | Moore et al. | Oct 2008 | A1 |
20080276226 | Farchi et al. | Nov 2008 | A1 |
20090158257 | Xu et al. | Jun 2009 | A1 |
20090172632 | Kashai et al. | Jul 2009 | A1 |
20090254801 | Pressman et al. | Oct 2009 | A1 |
20090319999 | Stall et al. | Dec 2009 | A1 |
20100037213 | Meijer et al. | Feb 2010 | A1 |
20100146377 | Simonyi | Jun 2010 | A1 |
20100162212 | Stall et al. | Jun 2010 | A1 |
20100192134 | Arkhipov et al. | Jul 2010 | A1 |
20100313189 | Beretta et al. | Dec 2010 | A1 |
20110078651 | Ovadia et al. | Mar 2011 | A1 |
20110126176 | Kandasamy et al. | May 2011 | A1 |
20110265066 | Fee et al. | Oct 2011 | A1 |
20110296377 | Morozov et al. | Dec 2011 | A1 |
20110307872 | Stall | Dec 2011 | A1 |
20120047486 | Ashish et al. | Feb 2012 | A1 |
20120167052 | Fjeldstad et al. | Jun 2012 | A1 |
20120198424 | Kandasamy et al. | Aug 2012 | A1 |
20120304154 | Cabillic et al. | Nov 2012 | A1 |
20120331449 | Farchi et al. | Dec 2012 | A1 |
20140033183 | Brown | Jan 2014 | A1 |
20140282417 | Paveza et al. | Sep 2014 | A1 |
Entry |
---|
Victor Berman, “An update on IEEE P1647: The E system verification language”, 2005 IEEE, pp. 484-486; <http://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=01511984>. |
Stephen A. Edwards, “Design and Verification Languages”, Nov. 2004, Columbia Univerisyt, New York, New York, pp. 1-18; <http://www.cs.columbia.edu/techreports/cucs-046-04.pdf>. |
Hollander et al., “The e Language: A Fresh Separation of Concerns”, 2001 IEEE, pp. 41-50; <http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=911754>. |
Victor Berman, “IEEE P1647 E Language: Cadence Plans for Standardization and Integration in Incisive Verification Flow”, Jun. 2005, Cadence Design Systems, pp. 1-2; <http://www.cadence.com/newsletters/incisiveplatform/ieee—p1647elanguage.pdf>. |
Cai et al., “Debugging a High Level Language via a Unified Interpreter and Compiler Runtime Environment”, In proceedings of EACA'04, Universidad de Santander, Spain, Jul. 1-3, 2004, pp. 1-6; <http://www.csd.uwo.ca/˜moreno//Publications/CDMW-EACA-04.ps>. |
Jinlong Cai, “Debugging a High Level Language via a Unified Interpreter and Compiler Runtime Environment”, Aug. 2004, The University of Western Ontario, London, Ontario, Canada, pp. 1-84; <http://www.csd.uwo.ca/˜moreno/Publications/JinlongCai-MSThesis-2004.pdf.gz>. |
Seaton et al., “Debugging at Full Speed”, 2014 ACM, Dyla'14 Jun. 2014, Edinburgh, UK, pp. 1-13; <http://dl.acm.org/results.cfm?h=1&cfid=454254856&cftoken=51700954>. |
Hiser et al., “Techniques and Tools for Dynamic Optimization”, Apr. 2006 IEEE, IPDPS 2006, pp. 1-8; <http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=1639569>. |
Cai et al., “Debugging a High Level Language via a Unified Interpreter and Compiler Runtime Environment”, ISSAC 2004, Jul. 2004, University of Cantabria, Santander, Spain, pp. 1-6; <www.sigsam.org/issac/2004/poster-abstracts/abstract06.pd>. |
Xtreme-II “VPA for Scalable Performance”, 2004. |
Non-Final Office Action dated Aug. 29, 2013 for U.S. Appl. No. 13/189,436. |
“Methods, Part 1,” URL:http://www.asic-world.com/specman/methods1.html#Introduction—to—Methods, Aug. 1, 2013. |
“Methods, Part 2,” URL:http://www.asic-world.com/specman/methods2.html, Aug. 1, 2013. |
“Specman In One Day, Part I,” URL:http://www.asic-world.com/specman/specman—one—day1.html#Introduction, Mar. 20, 2011. |
“Specman In One Day, Part II,” URL:http://www.asic-world.com/specman/specman—one—day2.html, Aug. 1, 2013. |
“Specman In One Day, Part III,” URL:http://www.asic-world.com/specman/specman—one—day3.html, Aug. 1, 2013. |
“Specman In One Day, Part IV,” URL:http://www.asic-world.com/specman/specman—one—day4.html, Aug. 1, 2013. |
“Tips for HVL and HDL users with special emphasis on Specman-e, SystemVerilog and Questa” URL:http://www.specman-verification.com/?entry=entry091112-093154, Nov. 12, 2009. |
Final Office Action dated Mar. 28, 2014 for U.S. Appl. No. 13/189,436. |
Niklaus Wirth, “Compiler Construction” Nov. 2005. |
Non-Final Office Action dated Sep. 16, 2014 for U.S. Appl. No. 13/189,436. |