PRB: SymGetSymFromAddr Fails with Error 487


The SymGetSymFromAddr DbgHelp.dll API function fails with Error 487 (ERROR_INVALID_ADDRESS) when it cannot find the symbol name in its internal symbol list. This typically happens if SymGetSymFromAddr is called from a Microsoft Windows NT, Windows 2000, and Windows XP Service to find symbolic debugging information.


By default, the symbol information for a module is found using the Win32 process current directory. A Windows NT, Windows 2000, and Windows XP service process does not have the same default current directory as a non-service Win32 process.


This behavior is by design.

More Information

The symbol handler of DbgHelp.dll stores symbol information by module in an internal linked list. The symbol information is loaded during SymInitialize or SymLoadModule, not during the SymGetSymFromAddr function call. If SymGetSymFromAddr fails to find the symbol information in the internal linked list, it sets the last error information to 487 (ERROR_INVALID_ADDRESS) and returns FALSE.

When TRUE is passed for bInvade for SymInitialize, the symbol handler will enumerate all the loaded modules for the specified process and load the symbol information for each. If FALSE is specified for bInvade, the symbol handler skips this step. Consequently, SymInitialize executes faster if FALSE is passed for bInvade. Alternatively, an application can use SymLoadModule to load the symbol information for a specified module when needed. Then an application can use SymGetSymFromAddr to resolve a symbol name after the symbol information has been loaded.

DbgHelp.dll uses the symbol search path to locate the symbol file. Use SymGetSearchPath function to find the current set of paths used to locate the symbol file. By default, it returns the string (for example, ".;c:\winnt"). This means it will search the current directory of the process and then the system root directory. If _NT_SYMBOL_PATH or _NT_ALT_SYMBOL_PATH environment variables are set, the symbol file is located in the following order:
  1. Current Directory
  2. Environment Variable _NT_SYMBOL_PATH
  3. Environment Variable _NT_ALT_SYMBOL_PATH
  4. Environment Variable SYSTEMROOT
Many developers use DbgHelp.dll to add custom debugging code built into their applications. For most cases, the current directory of an application is the same as the directory of the executable image. However, Windows NT, Windows 2000, and Windows XP services are different -- the executable image is located in some directory and the current directory is %SystemRoot%\SYSTEM32. As a result, SymGetSymFromAddr commonly fails when called from a service that assumes DbgHelp.dll will find symbols in the directory of the executable image. So, while the same code succeeds when calling SymGetSymFromAddr from a Win32 console application, the code might fail when called from a service. A process might also change the current directory using the SetCurrentDirectory Win32 API or the _chdir C run-time library function.

With the Visual C/C++ product, the default symbol configuration is: create Microsoft Format symbols and strip them to be placed in a separate .pdb file. Typically, the .pdb file is located in the same directory as the executable image. The Visual C/C++ product embeds the absolute path to the .pdb file in the executable image. If the symbol handler cannot find the .pdb file at that location or if the .PDB file was moved to another directory, the .PDB file is located by using the search path described previously.


For more information about DbgHelp API see:

Platform SDK: Windows Base Services; Executables; PE Image Helper

For more information about creating PDB symbol files see the product documentation provided with Microsoft Visual C++ 32-bit Edition.

Id. de artículo: 189780 - Última revisión: 11/21/2006 - Revisión: 1