I want to get the content of Program Counter which is in the stack when timer interrupt occurs. Though I am using C in most of my program, but I konw i may need to use assembly to get program counter. However, i am not relly familiar with assembly. Anyone could help me? CPU is x64 and OS is ubuntu 14.04. tks!
Asked
Active
Viewed 229 times
0
-
I think the return address is on the stack for x86. What did the manual say when you read it? The interrupt return instruction should tell you what it does and from there you can figure out where the code was interrupted. – old_timer Apr 09 '18 at 04:01
-
@old_timer manual?what do you mean that? when interrupt occurs, the current PC is pushed on the stack before ISR start. I just don't know how to get the PC stored on the stack. Because I can not figure out where the PC stored on the stack and how to read the stack. – M.Shuai Apr 09 '18 at 04:17
-
2You mention Ubuntu Linux. Linux handles the low level interrupts, not user programs. Are you writing your own OS? – Michael Petch Apr 09 '18 at 04:38
-
Add whatever code you like to the ISR entry point to copy the interrupt return address somewhere else. – Peter Cordes Apr 09 '18 at 04:41
-
1the documentation for the instruction set, it tells you how the instructions work, where the program counter is stored, plus documentation on other instructions like stack pointer relative loads. the answers are all right there. – old_timer Apr 09 '18 at 04:43
-
(oops, that linked duplicate is asking about the `int 0x80` entry point, not for real interrupts like timers. Still, I think other entry points are in the same file, `entry.S`.) See also [Interrupt Handling, in *Understanding the Linux Kernel, 3rd Edition*](https://www.safaribooksonline.com/library/view/understanding-the-linux/0596005652/ch04s06.html) – Peter Cordes Apr 09 '18 at 04:47
-
1@MichaelPetch No, I am writing a user program not OS. Actually, I want to write a program like gprof to record the time each function costs by sampling. So I need to know the address of the running instruction periodically. – M.Shuai Apr 09 '18 at 05:00
-
@PeterCordes how can i read the interrupt return address? – M.Shuai Apr 09 '18 at 05:04
-
At the start of execution of an interrupt entry point, it's on the kernel stack as described by the x86 manuals. Modify your kernel to copy it wherever you like. – Peter Cordes Apr 09 '18 at 05:08
-
1simply checking the instructions periodically doesn't give you the correct function call time. If you know the address of the function why don't just call it directly and measure the time? – phuclv Apr 09 '18 at 05:17
-
If you're using Linux, use `perf record` to get the same functionality from performance counters, defaulting to the counter for `cycles`. You don't need to write your own. Also, this kind of profiling without stack backtraces is often not as useful as you might think. https://stackoverflow.com/questions/49182065/how-does-a-profiler-sample-a-running-programe/49197429#49197429, https://stackoverflow.com/questions/1777556/alternatives-to-gprof/1779343#1779343, and also https://stackoverflow.com/questions/375913/how-can-i-profile-c-code-running-in-linux/378024 – Peter Cordes Apr 09 '18 at 07:04
-
Related: [linux perf: how to interpret and find hotspots](https://stackoverflow.com/questions/7031210/linux-perf-how-to-interpret-and-find-hotspots/7032171#comment85963964_7032171) – Peter Cordes Apr 09 '18 at 07:04
-
@PeterCordes thanks, but this is a task to write a tool to analyze a program to find hotspots based on PC sampling. – M.Shuai Apr 09 '18 at 13:56
-
That's *exactly* what `perf record` / `perf report` does: it samples the PC every 50k clock cycles or whatever. The only reason not to just use `perf` would be if you're on virtualized hardware that doesn't have hardware performance counters available. You might want to check if `perf` does have a way to sample the PC based on some kind of timer other than HW performance counters. – Peter Cordes Apr 09 '18 at 19:00