📄 kernel-instrumentation.html
字号:
<!-- Copyright (C) 2003 Red Hat, Inc. --><!-- This material may be distributed only subject to the terms --><!-- and conditions set forth in the Open Publication License, v1.0 --><!-- or later (the latest version is presently available at --><!-- http://www.opencontent.org/openpub/). --><!-- Distribution of the work or derivative of the work in any --><!-- standard (paper) book form is prohibited unless prior --><!-- permission is obtained from the copyright holder. --><HTML><HEAD><TITLE>Kernel Instrumentation</TITLE><meta name="MSSmartTagsPreventParsing" content="TRUE"><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+"><LINKREL="HOME"TITLE="eCos User Guide"HREF="ecos-user-guide.html"><LINKREL="UP"TITLE="Debugging Techniques"HREF="debugging-techniques.html"><LINKREL="PREVIOUS"TITLE="Debugging Techniques"HREF="debugging-techniques.html"><LINKREL="NEXT"TITLE="Configuration and the Package Repository"HREF="configuration-and-the-package-repository.html"></HEAD><BODYCLASS="SECT1"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">eCos User Guide</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="debugging-techniques.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">Chapter 27. Debugging Techniques</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="configuration-and-the-package-repository.html"ACCESSKEY="N">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="KERNEL-INSTRUMENTATION">Kernel Instrumentation</H1><P><ICLASS="FIRSTTERM">Instrument buffers</I> can be used to find out how many events of a given type happened in the kernel during execution of a program.</P><P>You can monitor a class of several types of events, or you can just look at individual events. </P><P>Examples of <ICLASS="FIRSTTERM">events</I> that can be monitored are: </P><P></P><UL><LI><P>scheduler events </P></LI><LI><P>thread operations</P></LI><LI><P>interrupts </P></LI><LI><P>mutex operations </P></LI><LI><P>binary semaphore operations </P></LI><LI><P>counting semaphore operations </P></LI><LI><P>clock ticks and interrupts </P></LI></UL><P>Examples of fine-grained scheduler event types are: </P><P></P><UL><LI><P>scheduler lock</P></LI><LI><P>scheduler unlock</P></LI><LI><P>rescheduling</P></LI><LI><P>time slicing </P></LI></UL><P>Information about the events is stored in an <ICLASS="FIRSTTERM">event record</I>. The structure that defines this record has type <SPANCLASS="TYPE">struct Instrument_Record</SPAN>:</P><P>The list of records is stored in an array called <SPANCLASS="TYPE">instrument_buffer</SPAN>which you can let the kernel provide or you can provide yourselfby setting the configuration option <TTCLASS="LITERAL">CYGVAR_KERNEL_INSTRUMENT_EXTERNAL_BUFFER</TT>. </P><P>To write a program that examines the instrumentation buffers: </P><P></P><OLTYPE="1"><LI><P>Enable instrumentation buffers in the <SPANCLASS="PRODUCTNAME">eCos</SPAN> kernel configuration.The component macro is <TTCLASS="LITERAL">CYGPKG_KERNEL_INSTRUMENT</TT>.</P></LI><LI><P>To allocate the buffers yourself, enable the configurationoption <TTCLASS="LITERAL">CYGVAR_KERNEL_INSTRUMENT_EXTERNAL_BUFFER</TT>. </P></LI><LI><P>Include the header file <TTCLASS="FILENAME">cyg/kernel/instrmnt.h</TT>. <TABLEBORDER="5"BGCOLOR="#E0E0F0"WIDTH="70%"><TR><TD><PRECLASS="PROGRAMLISTING">#include <cyg/kernel/instrmnt.h></PRE></TD></TR></TABLE></P></LI><LI><P>The <SPANCLASS="STRUCTNAME">Instrumentation_Record</SPAN> structureis not published in the kernel header file. In the future therewill be a cleaner mechanism to access it, but for now you shouldpaste into your code in the following lines: </P><TABLEBORDER="5"BGCOLOR="#E0E0F0"WIDTH="70%"><TR><TD><PRECLASS="PROGRAMLISTING">struct Instrument_Record{ CYG_WORD16 type; // record type CYG_WORD16 thread; // current thread id CYG_WORD timestamp; // 32 bit timestamp CYG_WORD arg1; // first arg CYG_WORD arg2; // second arg};</PRE></TD></TR></TABLE></LI><LI><P>Enable the events you want to record using <TTCLASS="FUNCTION">cyg_instrument_enable()</TT>, and disable them later. Look at <TTCLASS="FILENAME">cyg/kernel/instrmnt.h</TT> and the examples below to see what events can be enabled. </P></LI><LI><P>Place the code you want to debug between the matchingfunctions <TTCLASS="FUNCTION">cyg_instrument_enable()</TT> and <TTCLASS="FUNCTION">cyg_instrument_disable()</TT>. </P></LI><LI><P>Examine the buffer. For now you need to look at the datain there (the example program below shows how to do that), and futureversions of <SPANCLASS="PRODUCTNAME">eCos</SPAN> will include a host-side tool to help you understandthe data. </P></LI></OL><DIVCLASS="EXAMPLE"><ANAME="AEN2358"><P><B>Example 27-2. Using instrument buffers</B></P><P>This program is also provided in the <TTCLASS="FILENAME">examples</TT> directory. </P><TABLEBORDER="5"BGCOLOR="#E0E0F0"WIDTH="70%"><TR><TD><PRECLASS="PROGRAMLISTING">/* this is a program which uses <SPANCLASS="PRODUCTNAME">eCos</SPAN> instrumentation buffers; it needs to be linked with a kernel which was compiled with support for instrumentation */#include <stdio.h>#include <pkgconf/kernel.h>#include <cyg/kernel/instrmnt.h>#include <cyg/kernel/kapi.h>#ifndef CYGVAR_KERNEL_INSTRUMENT_EXTERNAL_BUFFER# error You must configure eCos with CYGVAR_KERNEL_INSTRUMENT_EXTERNAL_BUFFER#endifstruct Instrument_Record{ CYG_WORD16 type; // record type CYG_WORD16 thread; // current thread id CYG_WORD timestamp; // 32 bit timestamp CYG_WORD arg1; // first arg CYG_WORD arg2; // second arg};struct Instrument_Record instrument_buffer[20];cyg_uint32 instrument_buffer_size = 20;int main(void){ int i; cyg_instrument_enable(CYG_INSTRUMENT_CLASS_CLOCK, 0); cyg_instrument_enable(CYG_INSTRUMENT_CLASS_THREAD, 0); cyg_instrument_enable(CYG_INSTRUMENT_CLASS_ALARM, 0); printf("Program to play with instrumentation buffer\n"); cyg_thread_delay(2); cyg_instrument_disable(CYG_INSTRUMENT_CLASS_CLOCK, 0); cyg_instrument_disable(CYG_INSTRUMENT_CLASS_THREAD, 0); cyg_instrument_disable(CYG_INSTRUMENT_CLASS_ALARM, 0); for (i = 0; i < instrument_buffer_size; ++i) { printf("Record %02d: type 0x%04x, thread %d, ", i, instrument_buffer[i].type, instrument_buffer[i].thread); printf("time %5d, arg1 0x%08x, arg2 0x%08x\n", instrument_buffer[i].timestamp, instrument_buffer[i].arg1, instrument_buffer[i].arg2); } return 0;}</PRE></TD></TR></TABLE></DIV><P>Here is how you could compile and run this program in the <TTCLASS="FILENAME">examples</TT> directory,using (for example) the MN10300 simulator target: </P><TABLEBORDER="5"BGCOLOR="#E0E0F0"WIDTH="70%"><TR><TD><PRECLASS="SCREEN">$ make XCC=mn10300-elf-gcc INSTALL_DIR=/tmp/ecos-work-mn10300/install instrument-testmn10300-elf-gcc -c -o instrument-test.o -g -Wall -I/tmp/ecos-work-mn10300/install/include \ -ffunction-sections -fdata-sections instrument-test.cmn10300-elf-gcc -nostartfiles -L/tmp/ecos-work-mn10300/install/lib -W1,--gc-sections -o \ instrument-test instrument-test.o -Ttarget.ld -nostdlib$ mn10300-elf-run --board=stdeval1 instrument-test</PRE></TD></TR></TABLE><DIVCLASS="EXAMPLE"><ANAME="AEN2367"><P><B>Example 27-3. Instrument buffer output</B></P><P>Here is the output of the <BCLASS="COMMAND">instrument-test</B> program. Notice that in little over 2 seconds, and with very little activity, and with few event types enabled, it gathered 17 records. In larger programs it will be necessary to select very few event types for debugging. </P><TABLEBORDER="5"BGCOLOR="#E0E0F0"WIDTH="70%"><TR><TD><PRECLASS="PROGRAMLISTING">Program to play with instrumentation bufferRecord 00: type 0x0207, thread 2, time 6057, arg1 0x48001cd8, arg2 0x00000002Record 01: type 0x0202, thread 2, time 6153, arg1 0x48001cd8, arg2 0x00000000Record 02: type 0x0904, thread 2, time 6358, arg1 0x48001d24, arg2 0x00000000Record 03: type 0x0905, thread 2, time 6424, arg1 0x00000002, arg2 0x00000000Record 04: type 0x0906, thread 2, time 6490, arg1 0x00000000, arg2 0x00000000Record 05: type 0x0901, thread 2, time 6608, arg1 0x48009d74, arg2 0x48001d24Record 06: type 0x0201, thread 2, time 6804, arg1 0x48001cd8, arg2 0x480013e0Record 07: type 0x0803, thread 1, time 94, arg1 0x00000000, arg2 0x00000000Record 08: type 0x0801, thread 1, time 361, arg1 0x00000000, arg2 0x00000000Record 09: type 0x0802, thread 1, time 548, arg1 0x00000001, arg2 0x00000000Record 10: type 0x0803, thread 1, time 94, arg1 0x00000000, arg2 0x00000000Record 11: type 0x0801, thread 1, time 361, arg1 0x00000001, arg2 0x00000000Record 12: type 0x0903, thread 1, time 513, arg1 0x48009d74, arg2 0x48001d24Record 13: type 0x0208, thread 1, time 588, arg1 0x00000000, arg2 0x00000000Record 14: type 0x0203, thread 1, time 697, arg1 0x48001cd8, arg2 0x480013e0Record 15: type 0x0802, thread 1, time 946, arg1 0x00000002, arg2 0x00000000Record 16: type 0x0201, thread 1, time 1083, arg1 0x480013e0, arg2 0x48001cd8Record 17: type 0x0000, thread 0, time 0, arg1 0x00000000, arg2 0x00000000Record 18: type 0x0000, thread 0, time 0, arg1 0x00000000, arg2 0x00000000Record 19: type 0x0000, thread 0, time 0, arg1 0x00000000, arg2 0x00000000</PRE></TD></TR></TABLE></DIV></DIV><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="debugging-techniques.html"ACCESSKEY="P">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="ecos-user-guide.html"ACCESSKEY="H">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="configuration-and-the-package-repository.html"ACCESSKEY="N">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Debugging Techniques</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="debugging-techniques.html"ACCESSKEY="U">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Configuration and the Package Repository</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -