How to retrieve EIP/PC from DPC routine?

Hi,

Is there a way to retrieve/get the instruction pointer of the
interrupted thread/process in a DPC routine?

What I am trying to do is write a driver that queues a DPC every 10
milliseconds that periodically stores away the EIP and the
process/thread ID of the interrupted thread/process in a buffer. Any
other suggestions on how to possibly implement this are greatly
appreciated also.

Regards,

David “T”

You can only retrieve the USER mode registers set by inspecting the threads
KTRAP_FRAME.
You can however , retrieve the callers address using undcoumented function
RtlGetCallersAddress, but
neither wont help you , if I got right what you want do accomplish. DPC’s
are queued and retrieved
from a queue so your likely to get same addresses everywhere. Also, DPCs are
called into arbitrary
thread contexts.

What exaclty do you try to accomplish ?

----- Original Message -----
From: “David 'T”
To: “NT Developers Interest List”
Sent: Thursday, July 18, 2002 8:22 PM
Subject: [ntdev] How to retrieve EIP/PC from DPC routine?

> Hi,
>
> Is there a way to retrieve/get the instruction pointer of the
> interrupted thread/process in a DPC routine?
>
> What I am trying to do is write a driver that queues a DPC every 10
> milliseconds that periodically stores away the EIP and the
> process/thread ID of the interrupted thread/process in a buffer. Any
> other suggestions on how to possibly implement this are greatly
> appreciated also.
>
> Regards,
>
> David “T”
>
> —
> You are currently subscribed to ntdev as: xxxxx@rdsor.ro
> To unsubscribe send a blank email to %%email.unsub%%
>

I think he wants to do something like what VTune does - sample the current thread and
instruction pointer on a periodic basis. If I understood correctly, what he wants to know is
which arbitrary thread it is (that part is easy,) and what instruction was interrupted in
that arbitrary thread (that part ain’t so easy.)

-----Original Message-----
From: “Dan Partelly”
To: “NT Developers Interest List”
Date: Thu, 18 Jul 2002 20:28:47 +0300
Subject: [ntdev] Re: How to retrieve EIP/PC from DPC routine?

> You can only retrieve the USER mode registers set by inspecting the
> threads
> KTRAP_FRAME.
> You can however , retrieve the callers address using undcoumented
> function
> RtlGetCallersAddress, but
> neither wont help you , if I got right what you want do accomplish.
> DPC’s
> are queued and retrieved
> from a queue so your likely to get same addresses everywhere. Also,
> DPCs are
> called into arbitrary
> thread contexts.
>
> What exaclty do you try to accomplish ?
>
>
> ----- Original Message -----
> From: “David 'T”
> To: “NT Developers Interest List”
> Sent: Thursday, July 18, 2002 8:22 PM
> Subject: [ntdev] How to retrieve EIP/PC from DPC routine?
>
>
> > Hi,
> >
> > Is there a way to retrieve/get the instruction pointer of the
> > interrupted thread/process in a DPC routine?
> >
> > What I am trying to do is write a driver that queues a DPC every 10
> > milliseconds that periodically stores away the EIP and the
> > process/thread ID of the interrupted thread/process in a buffer. Any
> > other suggestions on how to possibly implement this are greatly
> > appreciated also.
> >
> > Regards,
> >
> > David “T”
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@rdsor.ro
> > To unsubscribe send a blank email to %%email.unsub%%
> >
>
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@hollistech.com
> To unsubscribe send a blank email to %%email.unsub%%

If he wants to sample on a periodic basis, and needs EIP , he should hook
the timer interrupt and fetch the interrupted’s thread EIP from the hardware
trap frame. I think there is no clean way for accompilshing this. Dont hook
the IDT directly whithout a good reason, and dont doit at all in a
commercial product, whatever reasons you might have. Watch out, each
processor on NT has its IDTR register loaded with a different IDT base
address, and the system does not give you any
routines to accomplish this. Youll have to come up with your own way.

Again, dont do something , except for your inhouse tools.

Dan

----- Original Message -----
From: “Mark Roddy”
To: “NT Developers Interest List”
Sent: Thursday, July 18, 2002 9:12 PM
Subject: [ntdev] Re: How to retrieve EIP/PC from DPC routine?

> I think he wants to do something like what VTune does - sample the current
thread and
> instruction pointer on a periodic basis. If I understood correctly, what
he wants to know is
> which arbitrary thread it is (that part is easy,) and what instruction was
interrupted in
> that arbitrary thread (that part ain’t so easy.)
>
> -----Original Message-----
> From: “Dan Partelly”
> To: “NT Developers Interest List”
> Date: Thu, 18 Jul 2002 20:28:47 +0300
> Subject: [ntdev] Re: How to retrieve EIP/PC from DPC routine?
>
> > You can only retrieve the USER mode registers set by inspecting the
> > threads
> > KTRAP_FRAME.
> > You can however , retrieve the callers address using undcoumented
> > function
> > RtlGetCallersAddress, but
> > neither wont help you , if I got right what you want do accomplish.
> > DPC’s
> > are queued and retrieved
> > from a queue so your likely to get same addresses everywhere. Also,
> > DPCs are
> > called into arbitrary
> > thread contexts.
> >
> > What exaclty do you try to accomplish ?
> >
> >
> > ----- Original Message -----
> > From: “David 'T”
> > To: “NT Developers Interest List”
> > Sent: Thursday, July 18, 2002 8:22 PM
> > Subject: [ntdev] How to retrieve EIP/PC from DPC routine?
> >
> >
> > > Hi,
> > >
> > > Is there a way to retrieve/get the instruction pointer of the
> > > interrupted thread/process in a DPC routine?
> > >
> > > What I am trying to do is write a driver that queues a DPC every 10
> > > milliseconds that periodically stores away the EIP and the
> > > process/thread ID of the interrupted thread/process in a buffer. Any
> > > other suggestions on how to possibly implement this are greatly
> > > appreciated also.
> > >
> > > Regards,
> > >
> > > David “T”
> > >
> > > —
> > > You are currently subscribed to ntdev as: xxxxx@rdsor.ro
> > > To unsubscribe send a blank email to %%email.unsub%%
> > >
> >
> >
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@hollistech.com
> > To unsubscribe send a blank email to %%email.unsub%%
>
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@rdsor.ro
> To unsubscribe send a blank email to %%email.unsub%%
>

Mark and Dan,

Both of you are correct in what I’m trying to do. For Win2k, the timer
is hooked at vector 0x30 (I’ll need to verify later what it is for WinXP
but I’ll assume at the moment it’s the same - please correct me if I’m
wrong).
How then would you suggest collecting that data? I would like to get
away from touching the IDT and would like this to be portable for Win2K,
XP, and future versions without using inline assembly.
I thought it would be a cleaner implementation using the KeSetTimerEx()
API and access the EIP from my registered DPC routine.
Or is there a way for me to connect directly to that vector using
IoConnectInterrupt(). This is an application driver, and from looking at
the DDK, this API seems to be geared more towards real hardware.
Thank you for your help.

David “T”

>> is hooked at vector 0x30

this holds true only for single CPU systems. IRQ handling in SMP on IA32 is
managed by the local apic, and it uses a completly different scheme. Refere
to Intel manuals, programing the local apic topic, to understand the issue.

> IoConnectInterrupt()

IoConntectInterrupt wont let you connect to timer interrupt.

> be portable for Win2K, XP, and future versions without using inline
assembly.

safe IDT hooking , especially in SMP is hard to accomplish. Almost all safe
schemes I know can break compatibility in future Nt versions, except one,
but which I profoundly dislike.

> KeSetTimerEx()

Unfortunatley , you wont gain much using this API. the timer DPC routine is
fired into an arbitrary thread context , leaving you very few chanches to
access the thread’s registers, as they where at interrupt time.

Kernel mode profiling is almost imposible to write whithout intrusive
routines. Your safest bet is still interrupt hooking, or using advanced
profiling techniques with the help of the local apic. As for how to collect
the data, I would suggest a circular buffer.

----- Original Message -----
From: “David 'T”
To: “NT Developers Interest List”
Sent: Thursday, July 18, 2002 11:48 PM
Subject: [ntdev] Re: How to retrieve EIP/PC from DPC routine?

> Mark and Dan,
>
> Both of you are correct in what I’m trying to do. For Win2k, the timer
> is hooked at vector 0x30 (I’ll need to verify later what it is for WinXP
> but I’ll assume at the moment it’s the same - please correct me if I’m
> wrong).
> How then would you suggest collecting that data? I would like to get
> away from touching the IDT and would like this to be portable for Win2K,
> XP, and future versions without using inline assembly.
> I thought it would be a cleaner implementation using the KeSetTimerEx()
> API and access the EIP from my registered DPC routine.
> Or is there a way for me to connect directly to that vector using
> IoConnectInterrupt(). This is an application driver, and from looking at
> the DDK, this API seems to be geared more towards real hardware.
> Thank you for your help.
>
> David “T”
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@rdsor.ro
> To unsubscribe send a blank email to %%email.unsub%%
>

Dan,

Then how would you suggest synchronizing access to the buffer from a
separate dispatch routine or dpc, if we try to queue one in the ISR, that’s
trying to flush the buffer, from the ISR?
I’ve read that acquiring spinlocks in an ISR is wrong. But, if we’re
going the IDT route, as you suggested, we’re bypassing the OS and IRQLs no
longer apply to the routine I attached to vector 0x30. So, it may be the
case that the ISR and dispatch routines can be simultaneously manipulating
the buffer. Or do you suggest using two buffers, one for reading and one
for writing?
I just want to try to do the right thing and minimize problems I’m not
aware of. I’m in the process of rearchitecting some code and I’m just
wondering what possibilities are out there. My driver knowledge is somewhat
limited, so I appreciate your assistance in answering my questions.

Thanks,

David “T”


MSN Photos is the easiest way to share and print your photos:
http://photos.msn.com/support/worldwide.aspx

You can use spinlocks at IRQL > DISPATCH , internals of
KeSynchronizeExecution is a good example. Only that you cant use
KeAcquireSpinLock(), this specific API always associates a spin lock with
DISPATCH level. You might use KeAcquireSpinLockRaiseToSynch(). Even if you
hook directly the IDT , IRQLs do apply. Dont forget , the whole concept of
IRQL is mapped on IA32 SMP machines directly to the local APIC. Of course ,
since you hook in IDT directly , the IRQL wont be raised to the current
level of the interrupt to be processed , but can be any lower value, not
only passive, and the interrupt arbitration will still be in effect.
Depending what are your final goals, and how complex is your tool, you can
take multiple paths, going as far as using IPIs to stall all processors but
the one processing the interrupt. Many debuggers use such techniques

----- Original Message -----
From: “David Thanairongroj”
To: “NT Developers Interest List”
Sent: Friday, July 19, 2002 12:31 AM
Subject: [ntdev] Re: How to retrieve EIP/PC from DPC routine?

> Dan,
>
> Then how would you suggest synchronizing access to the buffer from a
> separate dispatch routine or dpc, if we try to queue one in the ISR,
that’s
> trying to flush the buffer, from the ISR?
> I’ve read that acquiring spinlocks in an ISR is wrong. But, if we’re
> going the IDT route, as you suggested, we’re bypassing the OS and IRQLs no
> longer apply to the routine I attached to vector 0x30. So, it may be the
> case that the ISR and dispatch routines can be simultaneously manipulating
> the buffer. Or do you suggest using two buffers, one for reading and one
> for writing?
> I just want to try to do the right thing and minimize problems I’m not
> aware of. I’m in the process of rearchitecting some code and I’m just
> wondering what possibilities are out there. My driver knowledge is
somewhat
> limited, so I appreciate your assistance in answering my questions.
>
> Thanks,
>
> David “T”
>
> _________________________________________________________________
> MSN Photos is the easiest way to share and print your photos:
> http://photos.msn.com/support/worldwide.aspx
>
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@rdsor.ro
> To unsubscribe send a blank email to %%email.unsub%%
>

Careful there …

I believe that if you are running the Verifier and/or a checked build, you
will get a fault in KeAcquireSpinLockAt/FromDpcLevel if you are above
DISPATCH_LEVEL.


Gary G. Little
xxxxx@broadstor.com
xxxxx@inland.net

“Dan Partelly” wrote in message news:xxxxx@ntdev…
>
> You can use spinlocks at IRQL > DISPATCH , internals of
> KeSynchronizeExecution is a good example. Only that you cant use
> KeAcquireSpinLock(), this specific API always associates a spin lock with
> DISPATCH level. You might use KeAcquireSpinLockRaiseToSynch(). Even if you
> hook directly the IDT , IRQLs do apply. Dont forget , the whole concept of
> IRQL is mapped on IA32 SMP machines directly to the local APIC. Of course
,
> since you hook in IDT directly , the IRQL wont be raised to the current
> level of the interrupt to be processed , but can be any lower value, not
> only passive, and the interrupt arbitration will still be in effect.
> Depending what are your final goals, and how complex is your tool, you can
> take multiple paths, going as far as using IPIs to stall all processors
but
> the one processing the interrupt. Many debuggers use such techniques
>
> ----- Original Message -----
> From: “David Thanairongroj”
> To: “NT Developers Interest List”
> Sent: Friday, July 19, 2002 12:31 AM
> Subject: [ntdev] Re: How to retrieve EIP/PC from DPC routine?
>
>
> > Dan,
> >
> > Then how would you suggest synchronizing access to the buffer from a
> > separate dispatch routine or dpc, if we try to queue one in the ISR,
> that’s
> > trying to flush the buffer, from the ISR?
> > I’ve read that acquiring spinlocks in an ISR is wrong. But, if we’re
> > going the IDT route, as you suggested, we’re bypassing the OS and IRQLs
no
> > longer apply to the routine I attached to vector 0x30. So, it may be
the
> > case that the ISR and dispatch routines can be simultaneously
manipulating
> > the buffer. Or do you suggest using two buffers, one for reading and
one
> > for writing?
> > I just want to try to do the right thing and minimize problems I’m not
> > aware of. I’m in the process of rearchitecting some code and I’m just
> > wondering what possibilities are out there. My driver knowledge is
> somewhat
> > limited, so I appreciate your assistance in answering my questions.
> >
> > Thanks,
> >
> > David “T”
> >
> > _________________________________________________________________
> > MSN Photos is the easiest way to share and print your photos:
> > http://photos.msn.com/support/worldwide.aspx
> >
> >
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@rdsor.ro
> > To unsubscribe send a blank email to %%email.unsub%%
> >
>
>
>
>

Garry,

I was very carefull when I wrote my sentence. I quote “Only that you cant
use KeAcquireSpinLock(),” “might use KeAcquireSpinLockRaiseToSynch()”
This later API is a powerfull one, it will spin on DISPATCH, but will
acquire the lock at SYNCH level. It will not triger verifier, for it is
intended to be used this way. The spin lock object has nada importance in
this scenario. The IRQL at which is acquired does.

“Gary G. Little” wrote in message
news:xxxxx@ntdev…
>
> Careful there …
>
> I believe that if you are running the Verifier and/or a checked build, you
> will get a fault in KeAcquireSpinLockAt/FromDpcLevel if you are above
> DISPATCH_LEVEL.
>
> –
> Gary G. Little
> xxxxx@broadstor.com
> xxxxx@inland.net
>
> “Dan Partelly” wrote in message
news:xxxxx@ntdev…
> >
> > You can use spinlocks at IRQL > DISPATCH , internals of
> > KeSynchronizeExecution is a good example. Only that you cant use
> > KeAcquireSpinLock(), this specific API always associates a spin lock
with
> > DISPATCH level. You might use KeAcquireSpinLockRaiseToSynch(). Even if
you
> > hook directly the IDT , IRQLs do apply. Dont forget , the whole concept
of
> > IRQL is mapped on IA32 SMP machines directly to the local APIC. Of
course
> ,
> > since you hook in IDT directly , the IRQL wont be raised to the current
> > level of the interrupt to be processed , but can be any lower value, not
> > only passive, and the interrupt arbitration will still be in effect.
> > Depending what are your final goals, and how complex is your tool, you
can
> > take multiple paths, going as far as using IPIs to stall all processors
> but
> > the one processing the interrupt. Many debuggers use such techniques
> >
> > ----- Original Message -----
> > From: “David Thanairongroj”
> > To: “NT Developers Interest List”
> > Sent: Friday, July 19, 2002 12:31 AM
> > Subject: [ntdev] Re: How to retrieve EIP/PC from DPC routine?
> >
> >
> > > Dan,
> > >
> > > Then how would you suggest synchronizing access to the buffer from a
> > > separate dispatch routine or dpc, if we try to queue one in the ISR,
> > that’s
> > > trying to flush the buffer, from the ISR?
> > > I’ve read that acquiring spinlocks in an ISR is wrong. But, if
we’re
> > > going the IDT route, as you suggested, we’re bypassing the OS and
IRQLs
> no
> > > longer apply to the routine I attached to vector 0x30. So, it may be
> the
> > > case that the ISR and dispatch routines can be simultaneously
> manipulating
> > > the buffer. Or do you suggest using two buffers, one for reading and
> one
> > > for writing?
> > > I just want to try to do the right thing and minimize problems I’m
not
> > > aware of. I’m in the process of rearchitecting some code and I’m just
> > > wondering what possibilities are out there. My driver knowledge is
> > somewhat
> > > limited, so I appreciate your assistance in answering my questions.
> > >
> > > Thanks,
> > >
> > > David “T”
> > >
> > > _________________________________________________________________
> > > MSN Photos is the easiest way to share and print your photos:
> > > http://photos.msn.com/support/worldwide.aspx
> > >
> > >
> > >
> > > —
> > > You are currently subscribed to ntdev as: xxxxx@rdsor.ro
> > > To unsubscribe send a blank email to %%email.unsub%%
> > >
> >
> >
> >
> >
>
>
>
>

Are you planning to do some kind of kernel profiling ? Did you try using
kernrate ? Sampling EIP from a DPC may give you the wrong thread/process
today and in the future.


Nar Ganapathy
Windows Core OS group
This posting is provided “AS IS” with no warranties, and confers no rights.

“David 'T” wrote in message news:xxxxx@ntdev…
>
> Hi,
>
> Is there a way to retrieve/get the instruction pointer of the
> interrupted thread/process in a DPC routine?
>
> What I am trying to do is write a driver that queues a DPC every 10
> milliseconds that periodically stores away the EIP and the
> process/thread ID of the interrupted thread/process in a buffer. Any
> other suggestions on how to possibly implement this are greatly
> appreciated also.
>
> Regards,
>
> David “T”
>
>