Tutorial: Debugging OLE Client-Server Combinations
ID: q117558
|
The information in this article applies to:
-
The Visual Workbench Integrated Debugger
-
Microsoft Visual C++ for Windows, 16-bit edition, version 1.5
SUMMARY
When building object linking and embedding (OLE) servers, you may want to
debug them in the context of being activated by an OLE container or to
debug both the container and the server at the same time. The "Tutorial" in
the "MORE INFORMATION" section, below, shows you how to debug and set
breakpoints in an OLE server when the main debuggee is an OLE container.
Because Windows NT does not allow hard-mode debugging, and because you
cannot run CodeView under Windows NT, you cannot perform simultaneous OLE
client-server debugging using Visual C++, version 1.5, on Windows NT.
However, you can still debug clients and servers under Windows NT as single
applications on a standalone basis using the integrated debugger.
MORE INFORMATION
This tutorial guides you through a simple debugging session using the
samples that come with Visual C++:
Tutorial
- Build debug versions of the Microsoft Foundation Classes (MFC) samples
in the following directories:
- \MSVC\MFC\SAMPLES\CONTAIN\STEP2
- \MSVC\MFC\SAMPLES\SCRIBBLE\STEP7
- Run the SCRIBBLE.EXE file, built in step 1, to update the Windows
registry to point to this executable file.
- From File Manager, choose Run from the File menu and type REGEDIT in the
Command Line field. When REGEDIT comes up, double-click the SCRIB File
Type entry to verify that the path points to the debug version of
SCRIBBLE.EXE you just built. If not, modify the path accordingly.
- Load the OLE container project into the Visual C++ Workbench. If you are
debugging an SDI server application, you should set the Program
Arguments line of the Debug Options dialog box to "/Embedding" or
"/Automation" so that the debugger can launch the server application as
though it were launched from a container. Starting the container from
Program Manager or File Manager now causes the container to use the
instance of the server started in the debugger.
- Choose Debug from the Options menu and enter the full path to the debug
version of the OLE server in the Additional DLLs field (be sure to
include the .EXE extension). This tells the debugger to load the
symbolic debug information for the server.
NOTE: This path must exactly match the path to the server entered in the
Windows system registry. If it does not, attempts to debug the OLE
server will fail. You can check or modify the path in the registry by
using the REGEDIT tool provided with Windows.
- While in the Visual C++ Debug dialog box, also choose the hard-mode
button. This is just as important as the path-matching requirement
mentioned earlier. If you try to debug in soft mode, the OLE lightweight
remote procedure call (LRPC) mechanism will most likely cause unexpected
behavior. For example, if you have breakpoints set in the server[ASCII 146]s
initialization code, when the first breakpoint is hit the server will
stop in the debugger before it is completely "created". The container[ASCII 146]s
call to OleCreate() will continue to run, eventually timing out and
returning FALSE because the item was not properly created. You will then
get a Message Box stating "Failed to create object. Make sure the object
is entered in the system registry." Once you have received this message,
a copy of the server is left stranded in memory, and subsequent attempts
to debug it will fail (i.e. breakpoints will be missed). Restarting
Windows will remove the server from memory and allow you to start a
fresh debug session.
- Open CONTAIN\STEP2[ASCII 146]s CONTRVW.CPP file and set a breakpoint on line 168.
- Open SCRIBBLE\STEP7[ASCII 146]s SCRIBBLE.CPP file and set a breakpoint on line 68.
- Press F5 to start the CONTAIN.EXE file. In the CONTAIN main menu, choose
Insert New Object from the Edit menu.
- From the resulting Object Type list, choose SCRIB File Type and choose
the "OK" button. At this point, the debugger should have stopped at your
breakpoint in the SCRIBBLE.CPP file. You can now debug the SCRIBBLE
server.
NOTE: We could have set the breakpoint anywhere, including within the
SCRIBBLE class constructors.
- Press F5 again. The SCRIBBLE server continues its initialization, and
then control returns to CONTAIN.EXE. The debugger should stop at the
breakpoint in the CONTRVW.CPP file.
- Step through CONTRVW's code, using F8 to see the embedded SCRIBBLE
object become active.
- Press F5 to continue running the SCRIBBLE.EXE file, activated in place
within the CONTAIN.EXE file. If you do not readily see CONTAIN.EXE on
your screen, you may need to switch focus to CONTAIN.EXE manually. You
can also arrange Visual C++ and CONTAIN.EXE so that their windows do not
overlap.
- Close the CONTAIN.EXE file.
When debugging OLE clients and servers simultaneously, remember that if
both the client and the server(s) were statically linked using the MFC
libraries, there will be at least two copies of MFC code in memory (perhaps
more if you have nested embedded objects supplied by different servers).
Therefore, if you set a breakpoint in MFC library code through its sources
in \MSVC\MFC\SRC, you may get unexpected behavior. For example, if you set
a breakpoint within AfxOleInit() in file \MSVC\MFC\SRC\OLEINIT.CPP, the
debugger may not be able to tell whether you want to break at the
breakpoint under the following conditions:
- When the container's InitInstance calls AfxOleInit()
-or-
- When the server's InitInstance calls AfxOleInit()
-or-
- When the container's and server's InitInstances both call AfxOleInit()
Therefore, the breakpoint may not occur in the place that you want.
To tell the debugger where you want it to break, you must use the context
operator to specify in which module the breakpoint should be set. For the
AfxOleInit example just mentioned, you could use the following expression
to set the breakpoint in the server:
{,oleinit.cpp,server.exe} AfxOleInit
This expression names the source file and module (in memory) where the
debugger inserts the int 3 that sets the breakpoint. If the Integrated
Development Environment (IDE) debugger is used, you need to type this
expression into the Location field in the dialog box you get from choosing
Breakpoints from the Debug menu. (The above breakpoint has AfxOleInit as
the location, which causes a break on the opening brace of AfxOleInit. A
line number can just as well be used in this case.) If Codeview is used,
type the expression into the Location field in the dialog box you get from
choosing Breakpoints from the Data menu.
- Set a breakpoint at AfxOleInit in the SCRIBBLE server as described
above.
- Restart the CONTAIN.EXE file and observe that this breakpoint is only
hit when the SCRIBBLE.EXE file calls AfxOleInit, not when CONTAIN.EXE calls
AfxOleInit.
As an alternative, CodeView for Windows allows you to differentiate between
multiple module copies by choosing Open Module from the File menu. Use this
command to select in which module you want to set the breakpoint (CodeView
lists all copies of each of the MFC modules in memory).
The Visual C++ IDE debugger is somewhat limited in its ability to handle
complex debugging sessions, such as containers calling multiple servers. If
you find you are experiencing problems, try using CodeView instead.
If you want to use CodeView for Windows as the debugger, load debugging
information for your servers and/or DLLs by running the following command
(without quotes) from the Program Manager or by choosing Run from the File
Manager File menu:
"CVW <options, if any> [/Loleserver.exe] oleclient.exe"
The square brackets indicate that the enclosed parameter can be specified 0
or more times, allowing you to load (/L) symbolic information for several
servers or DLLs (or both). Unless the OLE client, server(s), and DLLs
reside in the current directory (or in the directories listed in the PATH
environment or in the Windows directories), the full path to these files is
needed on the command line above this command.
REFERENCES
For more information, please read the "Debugging OLE Applications" section
(pages 136 to 141) in the "Visual C++, version 1.5, OLE 2.0 Classes"
manual.
For more detailed information on the syntax and use of the context
operator, please refer to chapter 4 of the "Codeview Debugger User's
Guide".
In addition, Visual C++, version 1.5, supplies a variety of utilities in
the OLE 2.01 Toolkit. These are designed to help you test and debug your
OLE applications. For more information on these tools, please refer to the
"Tools" section of the OLE 2.01 Toolkit Release Notes (open the icon in the
Toolkit program group).
Additional query words:
kbinf 1.50
Keywords : kb16bitonly
Version :
Platform :
Issue type :
|