Welcome to MSDN Blogs Sign in | Join | Help

Debugging Toolbox

Windbg scripts, debugging and troubleshooting tools to help you isolate software problems.
Special Command—Use lm* and Get All Details from Modules

Yet another basic and useful command: lm.

Hmmmmm… OK so you already know this command. Great! But do you know all of its variations?

Usually when we get used to a command we don’t try to explore its variations and sometimes one of these variations may give you the information you’re looking for!

 

Let’s start getting all the basic information from all modules with lm.

This command shows several columns or fields, each with a different title. Some of these titles have specific meanings:

  • module name is typically the file name without the file name extension. In some cases, the module name differs significantly from the file name.
  • The symbol type immediately follows the module name. This column is not labeled. If you have loaded symbols, the symbol file name follows this column.
  • The first address in the module is shown as start. The first address after the end of the module is shown as end. For example, if start is "faab4000" and end is "faab8000", the module extends from 0xFAAB4000 to 0xFAAB7FFF, inclusive.

lm

 

Displaying all modules:

 

 

 

lmo

 

Displaying only the loaded modules:

 

 

 

lmv

 

Displaying details for all modules:

 

 

 

lmv m <moduleName>

 

Displaying details for a specific module:

 

 

 

Tip: Use it whenever you see an offset from the call stack that doesn’t look normal.

The stack below was manually crafted, just to use as an example:

 

053ffd4c 7731b071 ntdll!KiFastSystemCallRet
053ffd74 004153e7 ntdll!RtlPcToFileHeader+0x45

053ffe38 0041528c mtgdi!CGDIThread+0xed900
053ffe90 5796d973 mtgdi!CRectThread+0xed973

053fff58 6aacdfd3 mfc90d+0x3c
053fff94 6aacdf69 MSVCR90D!beginthreadex+0x1F
053fffa0 76e63833 MSVCR90D!beginthreadex+0x1a
053fffac 7731a9bd kernel32!BaseThreadInitThunk+3b
053fffec 00000000 ntdll!LdrInitializeThunk

  

Whenever you see a long offset, like above, it means you have no symbols or there's a problem and the symbols don't match, so you cannot trust on the names of the method calls! Usually when you don't have symbols is because it's a third-party component, so you lmv m to get information like version, company name and more.

 

lme

 

Displays only modules that have a symbol problem. These symbols include modules that have no symbols and modules whose symbol status is C, T, #, M, or Export:

 

 

lm1m

 

Do you want to use the lm output in a .foreach loop? I’ve done this in a few of my scripts. To accomplish this, you should use lm1m to get just the module names:

 

  

Displaying modules based on a pattern:

 

lm m <pattern>

 

This is hot! Have you already wondered if it’s possible to get a module from a memory address or that starts with a specific letter? Yes, it is! Here’s the usage. I'm getting all modules that start with the letter "m":

 

 

 

lm a <address>

 

This is even cooler! I'm using an address to get the module:

 

 

 

Finally, this is my bonus for you: An lm variation using DML. You can click on the hyperlinks and get more information, including functions and data. Fantastic!

 

lmD

 

 

 

Here you can see scripts that use lm*.

Posted: Wednesday, April 16, 2008 7:09 PM by Roberto Farah

Comments

Marc Sherman said:

Hi,

Could you elaborate on the following:

"Tip: Use it whenever you see an offset from the call stack that doesn’t look normal."

I'm not sure what you mean since call stack addresses don't reside within a module.

thanks,

Marc

# April 17, 2008 9:50 AM

Roberto Farah said:

Marc, thanks for this observation. I changed the text based on your feedback.

# April 17, 2008 12:25 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Page view tracker