Introduction




Yüklə 56.03 Kb.
tarix28.02.2016
ölçüsü56.03 Kb.

Introduction


Unfortunately the z/TPF debugger, Performance Analyzer, Code Coverage Tool and so on cannot find and solve your code bugs. However, the z/TPF debugger and associated tools can help you locate and identify your code bugs. The key is to understand what features are available and to creatively use them together to diagnose your code bugs. How do you learn about the features of the debugger and associated tools?

  • Documentation is available at http://www-01.ibm.com/software/htp/tpf/. See the Fast links section on the lower left side for the following information:

    • TPFUG presentations – A debugger and TPF Toolkit update is often provided at each TPFUG to announce new features, provide education and so on. These presentations are usually given in the TPF Toolkit Task Force or the Development Tools Subcommittee.

    • Tools -> z/TPF Debugger ->Debugger for z/TPF Demo Movie – This demo movie was created several years ago to highlight the function that was available at that time. Even though this movie is out of date, the education delivered in this format has been found to be very useful and the core function described continues to exist today.

    • TPF Family Libraries -> Open Current Information Center -> z/TPF PUT -> Library -> Debugger User’s Guide – The Debugger User's Guide describes the essence of using the debugger and is a good source for what function is currently available.

    • Tools -> z/TPF Debugger ->z/TPF Redbook - z/TPF Application Modernization using Standard and Open Middleware Redbook. See appendices A-D for an in depth step by step discussion for using the TPF Toolkit, Debugger, Code Coverage Tool, and so on. This may be a good resource if you are new to the toolset.

    • Tools -> z/TPF Debugger - The practical education articles, of which this article is part, provide explanations of how to use various debugger features to address debugging situations.

    • Tools -> z/TPF Debugger - The developerworks Custom Communications Packages article provides an explanation of how to administer customer communication packages to address debugging situations.

  • The TPF Toolkit help that is found in the Help menu also provides information regarding the features that are available. Select the Help menu -> Help contents. Then select Debugging TPF Applications, Analyzing Code Coverage of TPF Applications, or Analyzing Performance of TPF Applications.

  • This set of documentation.

  • Experimentation – Experimenting with the tool is one of the best ways to understand how the tool works.

  • Ask IBM – You can open a PMR to ask your question or send an email to tpfqa@us.ibm.com with your question. If your question is involved enough or you have a large number of questions, ask to have conference call with the experts to get your questions answered.

The purpose of this documentation is to augment the information currently available in the Debugger User's Guide and TPF Toolkit help documents by describing the ways in which the debugger and associated tools can be used to solve problems. The approach of this documentation is to examine different situations and come up with ideas about how to use different features of the debugger to diagnose the problem.




Revision

Date

Description

0




Initial Publication

1

11/11/2014

TPF Registration Entry monitor











How do I register the debugger?


The first question you may be asking is why do I need to register the debugger? The z/TPF debugger is a remote debugger in that the debugger GUI (the TPF Toolkit) resides on your workstation while the application and debugger backend reside on the server. As such, the server (z/TPF in particular) needs to be told you want to debug your application.
The key to registering the debugger to debug your application is to understand your application. For example, it is ideal to know the answer to questions such as:
How is my entry control block (ECB) started? Is this ECB started by a CREMC, CRETC, TPF_fork, SWISC CREATE or so on? Is this ECB started by a pthread_create? Or is this ECB started from a communications terminal such as an incoming message on a line number, interchange address, and terminal address (LNIATA), internet protocol (IP) or logical unit (LU).
How does my application behave? Does it create ECBs such as CREMC or so on? Does it create threads? Are there events, lockcs, signals, waiting for user input (ZPAGE), waiting for responses from another system, or so on?
What part of my application do I need to debug? Does it call global constructors? Is a library malfunctioning or is the mainline path? Is a system function or macro not returning the expected result?
Where is the right spot in my application to start debugging so that you are close to the cause of the problem?
Maybe you don't know your application in this level of detail. Do you know a main entry point name, a library used, or so on?
The more you understand your application, the more effectively you will be able to register the debugger to debug the ECB you need to debug. Notice the language used in this introduction is centered on debugging an ECB or ECBs. Many tools such as ZSPER are program centric debugging tools, which means that the code trapped on is what is debugged regardless of which ECB executes that code. The z/TPF debugger is an ECB centric debugger which means that the ECB is debugged regardless of which code that ECB executes. This is an important distinction and may be a change in mindset to how you are used to debugging. As you think about starting the z/TPF debugger, always be thinking in terms of catching the right ECB that will execute the code you need to debug.

How do you determine the right ECB to debug?


If you are intimately familiar with your application, this probably won't be a question you're asking. But if you don't know your application, you need some way to familiarize yourself with you application and the debugger tools can help you. The Determining code path article discusses how to use the trace log, code coverage, and debugger tools to learn about the path of your code. For example, in the code coverage tool, you can use the wild card (*) to register modules such as j* (assuming your application package begins with j). Drive your application and see which modules (objects and functions too) are executed in the code coverage results. Or refer to the Problem Diagnosis article to learn how to beginning debugging when you have a reproducible dump.

Know what debugger tools are available and how they work


The second key to starting the debugger effectively is knowing what features the debugger has, how to use them, and what the limitations are. The balance of this article will take the approach of example oriented explanations of the registration features that are available. The z/TPF debugger has a wide range of registration options including:

  • Register by program name

  • Register by function name

  • Register by SVC

  • Register by system error

  • Register by CTEST

  • Register by user defined registration

We will also discuss the registration options and features:

  • TPF terminal

  • Conditional registration

  • Trace created entries

  • Trace global variable initialization

  • Debugging threaded applications

  • Tips for registering on shared test systems

  • Other registration tips



Register by program name


In the z/TPF environment, the traditional linkage is termed Enter/Back which refers to the use of the z/TPF macros ENTxC and BACKC. A dictate of this linkage and the structure of the z/TPF environment is that all programs (or modules in the debugger) must have a 4-character name. Over the generations of TPF, additional forms of linkage have evolved including C/C++ function calls, main entry points, TMSPC, PRLGC, libraries and so on. But the dictate that all modules (basic assembler language (BAL) shared objects (BSOs) and C shared objects (CSOs)) must be built with a 4-character name remains.
The register by program name feature takes advantage of this 4-character program naming dictate. When using register by program name, you specify the 4-character program name you want to debug. The first ECB that enters that program by nearly any linkage type will start the debugger. The exceptions are the system special linkage libraries such as CTAL, DATA modules or the TPFDF programs that use fast linkage, these modules cannot start the debugger. That first ECB claims the registration entry and any other ECB on the system can enter that program without interference from the debugger. The debugged ECB is put to sleep while the debugger awaits instructions from you and the system continues to run in the background.
The register by program name feature does support wild cards though at least the first character of the program name must be specified such as q*. The TPF terminal and conditional registration features function as filters as to which ECBs are candidates for starting the debugger when the registered program is entered (see TPF terminal and Conditional registration below).
You can specify multiple program names. Each program name specified is indicating a possible starting location for the debugger. This may be useful if you don't know which path the application ECB may take. This list of program names has no effect upon how a debugger session will behave once it is started (for example the list of program names registered will not limit which programs the debugger will allow you to debug during the life of your ECB). This list only affects when the debugger will start.
To create a debugger session for a known entry point of your application, do the following:
Start the TPF Toolkit, switch to the Remote System Explorer Perspective, and switch to the Remote Systems view. Expand your TPF connection, right click on the Debugger Subsystem and choose new-> New Session. Choose the Program registration type and add the program names to the list.

Figure : Register by program name


Lastly, start your application. When your application enters a program name that you have registered, the debugger will start.
The following is a quick introduction to the primary views of the z/TPF debugger:
The Debug view shows the current stack frame and allows you to perform related actions. The editor view shows your source file or disassembled code and allows you to monitor expressions, perform execute actions, create breakpoints and so on. The ECB Summary view is a z/TPF specific view that shows a variety of detail regarding the ECB being debugged. The variables view shows the local variables for the currently selected stack frame in the debug view. The breakpoints view allows you to set a variety of breakpoints. The modules view shows the modules the debugger currently has loaded information for and allows you to explore source and set breakpoints. The monitors view allows you to evaluate specific expressions that you enter. The memory view allows you to explore the contents of memory. The debug console allows you to issue commands directly to the debugger engine (issue help for the list of available commands). The debugger also provides a host of views of z/TPF specific data including the ECB, data levels, DECB, DETAC, ALASC, SW00SR (TPFDF), TPF Malloc, and Record Hold views. Use these features in conjunction with each other to explore the state and operation of your ECB to debug your application code.

Figure : z/TPF debugger


Register by function name


Suppose you have used trace log, ECB trace, code coverage, or the debugger to understand the path your application takes and discovered that a particular function is returning an incorrect value. Or suppose based on the output of your application, you know a particular function is not returning the correct value. You can register the debugger to start when an ECB enters that function.
To create a debugger session for a known function entry point of your application, do the following:
Start the TPF Toolkit, switch to the Remote System Explorer Perspective, and switch to the Remote Systems view. Expand your TPF connection, right click on the Debugger Subsystem and choose new-> New Session. Choose the Function registration type and specify the function name, module name and so on.
Function names can be specified as mangled names (compiler produced names as seen in listing, ZDMAP and so on). This is useful for debugging a particular overloaded C++ function. Suppose we have two member functions in the class IVALinkedList named erase.

int erase(IVALLElement *pos);

int erase(IVAValue value, TestAgainstElement *func);

If you register the function name erase, the debugger will start when either of these functions is called as well as any other function named erase defined outside of this class. In order to only start the debugger when the second version of erase above is called, register the compiler generated mangled named:

_ZN13IVALinkedList5eraseE8IVAValuePFP12IVALLElementRS0_S2_E

An alternative way to specify the erase function is to include the class and namespace name by use the :: operator, such as IVALinkedList::erase from our example here or MyNamespace::IVALinkedList::erase


Function names can be specified as demangled names such as dispHelp. Specify the function name just as you coded it without including parenthesis or parameters
Function names can be specified to include wildcards such as disp*. You can also specify wild cards for the namespace, class or function names such as I*::e*
Function names registered are always case sensitive.
The Module Name can also contain a wildcard (*). However, a CTL-10 is possible. It is highly recommend that you specify the module name because this will also reduce any performance impacts on the system.
Click OK and then register your session.

Figure : Function registration entry


Lastly, start your application. When your application enters the function name that you have registered, the debugger will start. That first ECB claims the registration entry and any other ECB on the system can enter that function without interference from the debugger. The debugger views and so on will function as described in register by program name.

Register by SVC


Suppose you have used trace log, ECB trace, code coverage, or the debugger to understand the path your application takes and discovered that a particular SVC macro is returning an incorrect value. Or suppose based on the output of your application, you know a particular SVC macro is not returning the correct value. You can register the debugger to start when an ECB issues an SVC macro of that type.
To create a debugger session for an SVC macro of your application, do the following:
Start the TPF Toolkit, switch to the Remote System Explorer Perspective, and switch to the Remote Systems view. Expand your TPF connection, right click on the Debugger Subsystem and choose new-> New Session. Choose the SVC macro registration type and specify the SVC macro name, module name and so on.
The SVC macro name cannot be a macro group name.
The program names can include wild card characters.
Click OK and then register your session.

Figure : SVC macro registration entry


Lastly, start your application. When your application issues the registered SVC macro (the first issuing of the macro) in the programs that you have registered, the debugger will start. That first ECB claims the registration entry and any other ECB on the system can enter that function without interference from the debugger. The debugger views and so on will function as described in register by program name.

Register by system error


Register by system error name starts the debugger when the specified system error occurs and starts the debugger on the application at the location just prior to the location of the dump (as if the dump has not occurred yet). Register by system error is discussed in the Problem Diagnosis article. See that article for more information.

Figure : System error registration entry



Register by CTEST


Suppose you want to start the debugger at a specific location in your application and you are able to make and load a code change. You can code a call to the CTEST function in your application as ctest(NULL). The CTEST function is a user defined registration type (described in the next topic). However, calls to the CTEST function will also act as an unmodifiable breakpoint. Register by CTEST will start a debugger session when the CTEST function is called by any application.
When registering by CTEST, there are no parameters to register. If multiple people register for CTEST on a system, the registration entry behaves in a first come first served fashion. For example, suppose user A registers for CTEST, then user B registers for CTEST, and then user B starts the application with a CTEST function call coded. A debugger session will start for the application of user B on the registration entry and TPF Toolkit instance of user A because the registration entry of user A came first. As a result of this behavior, this function may not behave in a predictable fashion on shared test systems and it is not advisable to leave calls to the CTEST function in your application. However, the user defined registration can be used to overcome this shortcoming. The advantage of using register by CTEST over register by user defined is that CTEST is quick and easy to use while register by user defined is more involved to set up.
To create a debugger session for a CTEST in your application, do the following:
Start the TPF Toolkit, switch to the Remote System Explorer Perspective, and switch to the Remote Systems view. Expand your TPF connection, right click on the Debugger Subsystem and choose new-> New Session. Choose the IBM_CTEST registration type.
Click OK and then register your session.

Figure : Register by CTEST example


Lastly, start your application. When your application issues the function call to CTEST, the debugger will start. That first ECB claims the registration entry and any other ECB on the system can issue CTEST without interference from the debugger. The debugger views and so on will function as described in register by program name.

Register by user defined registration


Register by user defined allows you to start a debugger virtually anywhere under the conditions that you specify. Since the user determines the location that the debugger will start, the conditions that will be tested and how those conditions will be tested, there are limitless possibilities. The testing of your conditions occur in your application ECB and as a result you can test whatever you want; contents of variables, ECB contents, states, something in the debugger registration entry, something in system heap, whatever you can come up with. Comparison function can be local to the program, in some external program, in the CDBX user exits, a BSO entry point, a CSO entry point, or so on.
This registration type was designed to satisfy custom communication package requirements. Suppose your z/TPF system sends a message to another system to process the message. You can create a user defined registration type to catch a specific response from the external system based on your user ID, protocol ID, protocol parameters, and so on.
Or suppose you have a single entry point communications package where all requests are received and then the path diverges based on the request type (such as create, read, update, or delete). You can create a user defined registration type to test the request type, account numbers and other specific criteria to debug the ECB that will take the code path you need to debug without having to stop all other traffic running through that central program.
Another example for when to use the user defined registration support is when an application is entered thousands of times per second and you need to debug a specific ECB, maybe when a particular data level is 0. You can create a user defined registration type to test the contents of the data level and only start the debugger on the ECB that you need to debug regardless of the other traffic on the system
Or maybe you find yourself in an odd situation where a problem occurs when the value of i is a particular value, the value of j is a particular value, and the value of k is a particular value. However, you do not know how or when this condition occurs. You can create a user defined registration type to test the situational parameters of interest and wait for the debugger session to start when the condition occurs.
A tremendous advantage of user defined registration types is that the interface was defined to have minimal performance impacts such that the intercepts defined can be left in your production code for future testing points. Assembler and C/C++ interfaces are available.
A number of examples exist that give detailed instructions to create a user defined registration entry. See the Custom Communication Packages developerworks article, the z/TPF Application Modernization & ILOG Exploitation Redbook appendix C, the z/TPF Information Center at http://publib.boulder.ibm.com/infocenter/tpfhelp/current/topic/com.ibm.ztpf-ztpfdf.doc_put.cur/gtpd3/d3tusrdefreg.html

Figure : Register by user defined registration example


The first ECB claims the registration entry and any other ECB on the system can execute the application code without interference from the debugger. The debugger views and so on will function as described in register by program name.


TPF Registration Entry monitor


TPF Toolkit provides a rich set of features that require connecting to a TPF system, such as the debugger, performance analyzer, and code coverage tools.

The registration entry monitor displays the status of a session - registered or not - within your TPF connections in the TPF Toolkit. This lets you know at a glance exactly which sessions are registered on the TPF system. This will highlight the registered sessions. Also, when you alter the registration properties, the registration will indicate that the session needs to be re-registered. The registration entry monitor can be used to auto fix IP address changes For example, when you connect through a VPN.

In this example, I have three entries registered. For one registration entry, I have modified the properties, and this needs to be re-registered:

To enable this feature, in the Windows Preferences, under Run/Debug, select the Debug Server. From here, you can select the “Enable TPF Registration Entry Monitor.” Here you can specify under “Monitor frequency” how often you would like the registration monitor to refresh. Select Update IP information in registered sessions to have the TPF system automatically update registration entries with a new IP address if your local workstation IP address changes.





TPF terminal


The TPF Terminal acts as a filter for which ECBs the debugger will consider starting a debugger session for register by Program, Function, SVC, and System error.
Trace by program

If the TPF Terminal name is set to * for the LNIATA, the debugger will not filter any ECBs by terminal type. The registration entries created this way will appear in the Trace by Program Table in the ZDDBG and ZDBUG displays. Use wildcard for the LNIATA for ECBs that are not being started from the z/TPF communications code after the registration entry is made. There are some program instances where you must register with * for the LNIATA such as debugging ECBs created by CRETC, CREMC, SWISC create, tpf_fork and so one (see trace created entries below). There may be other circumstances where register with * for the LNIATA must be used (proprietary communications protocols, and so on). The drawback of this type of registration is that the first ECB that meets the requirements of your registration will start the debugger session and it may not be the ECB you need to debug; such as situations where the code you want to debug is being entered very frequently, shared test systems where multiple users are generating traffic and so on. The user defined registration type discussed above can provide a viable solution for debugging these situations. Despite the limitations, using * for the LNIATA is probably the most common way to register the debugger.


Figure : Registration with * as the LNIATA for the TPF Terminal


Trace by Terminal

Specifying a specific TPF Terminal can be a useful feature. The TPF Terminal will be used to filter which ECBs are candidates for debugging with this registration entry. For example, suppose you are testing on a shared test system and driving traffic from LNIATA 4E0000. If you specify the TPF Terminal as LNIATA 4E0000, only the ECBs started from your LNIATA will be candidates for debugging with your registration entry.


The registration entries created this way will appear in the Trace by Terminal Table in the ZDDBG and ZDBUG displays.
When specifying the TPF Terminal as an LNIATA you can specify a wild card for the IATA or the TA such as 01* and 0101*. If the TPF Terminal is specified as an IP, the entire IP address must be specified. If an LU is specified, the LU must be in the format of NETID.LU, .LU, or simply as LU.
The trace by terminal registration type has the following limitations

  • The way trace by terminal works is that when an ECB is created by communications code, it calls the tpf_flag_for_debug system function. The tpf_flag_for_debug system function examines the ECB type, the communications details and looks for trace by terminal registration entries on the system that are a match. If a match is found, that registration entry is saved in the process block of the application. Then the application code is executed. As such, application code that programmatically fills in EBROUT does not qualify as a candidate for trace by terminal debugging. Custom communication packages can call the tpf_flag_for_debug system function such that trace by terminal registration functions as expected (for example, TN3270 support). See the Custom Communications Packages developerworks article for more information.

  • This type of registration will only work for ECBs created from z/TPF communications code. As such, ECBs created by CRETC, CREMC, SWISC create, tpf_fork and so on cannot be debugged using a registration entry of this type (see trace created entries below and trace by program above).

  • Suppose you have a long running ECB, then you register based on an LNIATA that the ECB was previously started from, the ECB hits the condition to start the debugger, but the debugger doesn’t start. Since the ECB was started prior to the debugger registration, that ECB cannot be debugged based on the terminal information.

Conditional registration


Suppose you have a function or program that is entered 100 times for a single ECB and you need to debug that function or program when a particular value is stored in the data level. You can use conditional registration to test on program or function entry if CE1CR0 not equal 0. Or if the parameter in R2 equal 0.
Conditional registration functions as an additional filter for ECBs that are candidates for debugging. This condition is examined at the time the debugger is testing if your application is a candidate for debugging and you may need to take this into consideration when registering a condition. Care must be used when setting the values to be tested. For example, when using conditional registration in general, the condition testing occurs after the stack frame has been pushed for the function that was just entered. For registration by function, you may be able to use this to test parameters but it will require reading the listing to know how to do it.
In order for conditional registration to work, UCST must be loaded to the system with debug information available.
Example conditions that can be tested are:

  • A given ECB field contains a particular value

  • A register contains a particular value


Figure : Registration with conditional registration.


Trace created entries


Suppose you have an application that creates an ECB with a CREMC macro and you need to debug both the parent and child ECBs at the same time.
The trace created entries option indicates to the debugger that you are interested in debugging ECBs that will be created from the initial parent ECB you debug. This support is for created ECBs in the z/TPF system created by CREMC, CREDC, SWISC create, tpf_fork, or so on. CRETC and pthread_create (see threaded debugging below) are not supported.

Figure : Registration with trace created entries


At the time that the create event occurs, you will be prompted to decide what action they want to take. The new enhanced event support allows you to choose what action should be performed on the parent (stop, continue, and so on) and child (debug or do not debug) ECBs separately. The dialog box also shows where the create event occurred. If you choose to debug the created child, an additional debugger session is created for the child ECB. This additional debugger session is a completely separate instance of the debugger for the child ECB but the same registration entry is used for both debugger sessions. The registration entry remains in use until all debugger sessions exit.

Figure : ECB create event occurred in the debugger


NOTE: Since there are two independent debugger sessions (one for the parent and one for the child), you can debug and control each ECB completely independent of each other. Use the Debug view to switch between ECBs.

Figure : Parent and child debugger sessions



Trace global variable initialization


Suppose you have an application that creates a global C++ object and you need to debug the constructor that is called when that global object is instantiated. By default, the debugger runs the application past all global initialization since many coding artifacts generate global initialization without the user knowing, the source line that the compiler associates with global initialization is usually cryptic, and many users don't realize they are debugging global initialization code and think the debugger isn't working correctly.
Trace Global variable initialization function indicates to the debugger that you want to be able to debug global variable initialization functions such as global constructors. As you step through the global initialization code, your application may appear to execute seemingly random pieces of code in different objects in your program. Keep using step into until you are debugging the code you are interested in debugging. The debugging experience may be more obvious if the application is built with the -O0 compiler option.

Figure : Registration with trace global


Debugging threaded applications


Suppose you need to debug an application that uses threads (threads are created by using the pthread_create interface). Threads on the z/TPF system are different than created ECBs. Thread ECBs share their process block, stack area, malloc, and so on with each other.
The z/TPF debugger supports debugging of threaded applications. It is similar yet significantly different from debugging created ECBs as described above.

  • You do not need to set the trace created entries check box in the registration entry.

  • When you begin debugging any thread in a threaded application, the debugger will attempt to stop all threads.

  • When a thread is created by your debugged application the debugger will immediately stop that thread from running and present it to you. You will not be prompted to know if you want to debug the thread. This is because this is the only opportunity for the debugger to reliably stop your thread and all threads in the process must be presented. You can immediately set it running if you do not wish to debug it.

  • Actions performed on one thread affect the other threads such as terminating a thread will cause the entire process to immediately exit, causing one thread to dump will cause the process to exit (depending upon z/TPF settings, and so on.

  • Threads in the debugger are managed by a single debugger instance unlike the one for one architecture used by created ECBs. This changes slightly how the contents of the debug view look and behave.

One advantage of the z/TPF debugger implementation is that you can control each thread independent of the others. As such, you can deliberately cause application timing situations to occur that may be difficult to recreate otherwise. This is good because you can debug those scenarios to ensure your application behaves correctly. It can also be a problem if you are not experienced if you inadvertently cause a bad state to occur.


One key to debugging a threaded application is to make the debug view the center of your debugging experience. Make sure you click on the thread you are interested in performing an action on before performing that action.

Figure : Debugging a threaded application



Tips for registering on shared test systems


Registering on a shared test system can present a number of challenges some of which have been discussed throughout this article. Among the concerns is defining a registration entry in which you debug the application started by someone else or starting your application which is debugged by the registration entry of someone else. A key to debugging in this environment is to define a registration entry and starting your application so that only you can debug your application (if possible). It is equally important for other users on the system to do the same. Here are some tips for working in this environment:

  • Use the trace by terminal feature by specifying a TPF Terminal instead of using * for the LNIATA when registering the debugger and have the traffic of each individual started from a different LNIATA.

  • Use conditional registration to differentiate ECB from ECB. For example test against a unique value in the ECB such as EBROUT or so on.

  • User Defined Registration can work well for these situations. You can define a field to test to be the ID of a user and as part of your application traffic embed the ID of the user in the ECB so that you can test against it.

  • Every registration type allows you to pass in a user token. As part of your application traffic embed the ID of the user in the ECB. And every registration trace by program type of registration calls user exit UCCDBTS in cusr.cpy for verification that a debugger session can be started on that ECB. In UCCDBTS you can code a test to compare the user token in the IPROG entry to the ID of the user embedded in the application. Or instead of embedding the ID of the user in the application, you can equate the user token passed in on the registration entry with the IP address or another user unique feature in ECB. You can do a very similar sort of user token comparison for trace by terminal in the tpf_terminal_user_exit in cdbuxt.c.

  • Another common problem in debugging on a shared test system is debugging code that someone else loaded. While the debugger cannot know if you are debugging the right code, it does show you which loadset your code was loaded in the debug view in each stack frame. If something is not behaving properly, confirm that you are debugging your code.

  • Similarly, if your system supports it, use selective activation (see the ZOLDR ACTIVATION documentation for more information). The debugger will work in selectively activated programs without making any accommodations.

Other registration tips


Now that you understand better how debugger registration works, you can manipulate your application and debugger registrations to debug under a wide array of situations. As such, you can do things such as this TPF 4.1 tip that emulates user defined registration:

  • Find a location you want to start a debugger session. Code any tests you want to perform or so on that you want to use to limit the debugger starting (like an ECB filter). Then call some dummy program like QZZ1 (ENTRC, direct function call to QZZ1(), and so on). Code your dummy program to do nothing. Build and load the code. Register your dummy program and generate the desired traffic. When the debugger starts on your dummy program, hit step return to return to the caller. Debug as normal. But do not leave the call in your production code. This method can be used to debug a particular instance of a program that is started many times per second, start the debugger under a particular circumstances, or so on.



Conclusion


In this article we've discussed the registration features available in the z/TPF debugger from the perspective of what features are available and how they can be used under specific circumstances. Much of what has been discussed here also applies to the performance analyzer and the code coverage tool registration.


Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©azrefs.org 2016
rəhbərliyinə müraciət

    Ana səhifə