Microsoft KB Archive/189780

{|
 * width="100%"|

PRB: SymGetSymFromAddr Fails with Error 487

 * }

Q189780

-

The information in this article applies to:


 * Microsoft Win32 Application Programming Interface (API), used with:
 * the operating system: Microsoft Windows NT 4.0

-

SYMPTOMS
The SymGetSymFromAddr ImageHlp.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 Windows NT Service to find symbolic debugging information.

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

STATUS
This behavior is by design.

MORE INFORMATION
The symbol handler of ImageHlp.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.

ImageHlp.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 ImageHlp.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 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 Windows NT service that assumes ImageHlp.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 Windows NT 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.