Thanks Chris, your reply helps a lot on my proposal draft. I am writing down my understanding inline marked [Alan] to confirm with you.<br><br>Regards,<br>Alan<br><br><div><span class="gmail_quote">2008/3/26, Chris Johns <<a href="mailto:chrisj@rtems.org" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">chrisj@rtems.org</a>>:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

<br>Yes this is correct. We need to flatten the argument list to a block of memory<br> to capture. The wrapper code generator will know all the details of the<br> function's signature so can determine the amount of stack used to hold<br>

 arguments. The variable argument functions such as printf are something I am<br> yet to figure out. This is part of the work.</blockquote><div><br>[Alan] I think it can determine the amount of stack required ONLY if we make the generator running together with the RTEMS to generate wrapper code, otherwise, the function signature itself can not figure out the required memory.<br>
<br>I guess most of the functions are not variable argument one. For variable one like printf, we could wrap as well as below, but I do not figure out how the wrapper code generator could generate it :)<br><br>#include <stdio.h><br>
#include <stdarg.h><br><br>int __wrap_printf(const char *template, ...)<br>{<br>    int iRet;<br>    va_list argp;<br>    va_start(argp, template);<br>    iRet = vprintf(template, argp);<br>    va_end(argp);<br>    return iRet;<br>
}<br> </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"> The capture engine's role changes a little when logging wrapped calls. When in<br>

 the context switch path performance is key while in the wrapped mode the<br> overhead of the block copy of arguments is something we know has to happen and<br> have to factor in.<br> <br> The example code above it is close. We need to decide if we log only once when<br>

 we have the return value with 2 time stamps (entry/exit). This lowers the<br> overheads down but complicates the data stream on the host side as nested<br> traced calls will appear before the current call.</blockquote><div>
<br>[Alan] I understand what you are talking about is, whether to log during both entry and exit, or to log during one of them only. Right? If so, that could be part of work to decide the option.<br></div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
 > I believe Chris has an idea where the trigger is actually in the capture<br>
 > engine and users can provide boolean expressions.  Greatly simplifies<br> > the logging.<br> <br> <br>We need generate some sort of id which is specific to a function's signature<br> and then have a way to match this with the running target image and finally<br>

 the resulting data. Once we have this the capture engine can handle the<br> trigger and filter processing keeping this code in one place.<br> <br> We may have the tool generate code that is compiled into the application to<br>

 handle static filters and triggers rather than a user interface. This code is<br> just making calls to the capture engine.</blockquote><div><br>[Alan] I understand the "static" here means, instead dynamically setting the trigger/filter during run-time, statically have the trigger/filter written into the code as pre-defined trigger/filter so that once trace is enabled, the static trigger/filter is enabled.<br>
</div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"> Let me explain. We could have a target that is connected to via TCP. The user<br>
 has wrapped a list of functions then interacts with the running target to set<br>
 filters and triggers dynamically in a series of runs to isolate a bug. The<br> second example is a system where the list of wrapped functions is generated<br> from the static filter and trigger commands which are also turned into target<br>

 code run during initialisation. Both systems use the same capture engine code.<br> <br><br> > Plus with the wrapping idea, you turn the wrapper completely off via<br> > ld arguments.  That part can be done manually or via a GUI to generate<br>

 > a file that is passed to the ld command line.<br> <br> <br>This is something we need to figure out. For example do I build my RTEMS<br> application as I do then say capture tool relink to be a traceable executable<br>

 or do users application build systems need to know what to do. The issue here<br> is how we manage or help the user with the build process when wrapping.</blockquote><div><br>[Alan] Are we going to  build the wrapper code into the RTEMS if the performance impact is acceptable? If so, why it is required for user application to know how to build the wrapper code in?<br>
</div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"> >> 2. Triggers are to be managed by the event ID.<br>
 <br> <br>I call "event ID" trace points. We can have system trace points like we<br> currently have in the capture enigine, function trace points (wrapped<br> functions) and user trace points where a user makes an explicit call.</blockquote>
<div><br>[Alan] about the user trace points here, do you mean user application could make an explicit call to capture engine in their application?<br></div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
 >><br> >> 3. I has no idea about the filter for these events. For existing task<br> >> related one, we could filter by priority, but how about the wrapped<br> >> one? Could you tell some example for me to consider?<br>

 >><br> > Based upon the id of the executing thread. Try this example:<br> ><br> > log all semaphore manager calls for thread 32.<br> > log all context switches<br> > log all malloc/free calls for thread 75.<br>

 ><br> > Start tracing after 10 seconds and log for 15 seconds.<br> <br> <br>The first examples are filters while the last one is a trigger. The way to<br> think about this is to consider a hardware logic analyser. You can filter the<br>

 signals you want to look at then you specify a trigger. Once triggered you<br> capture based on the filtering.<br> <br> The detail of the implementation is the way in which a user says "malloc" and<br> we match that to a specific trace point (id) which has a set of flags we check<br>

 against. The example filter:<br> <br><br>  log all semaphore manager calls for thread 32<br> <br> <br>is rather complex because we need to pattern match "rtems_semaphore_*" to find<br> all the calls and the id's then add the thread id to each trace point's<br>

 control data. The check of the thread id is similar to the "by" fields<br> currently in the capture control structure. The above could be written as:<br> <br>  filter rtems_semaphore_* from 32<br> <br> To filter another task as well run the command again with a new thread id.</blockquote>
<div><br>[Alan] That make sense, thank you! <br></div><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"> >> Regarding to other parts of the project, I understand as below, please<br>
 >> comment.<br> >> 1. Transmission of logged data to host<br> >><br> >>           o The first challenge of this part is to make the system and<br>
 >>             the log survive from high traffic.<br> >>           o The second challenge is to implement it in TCP while<br> >>             providing the flexibility for other transports in future.<br>

 >>           o The third challenge is to trade off minimizing the data to<br> >>             be sent across the network against the over-head to<br> >>             compress data.<br> >><br> > Right.  This is something to investigate and do the trade-offs in the<br>

 > early phase of the project.<br> <br> <br>We also need to handle the control data to manage dynamic triggers and filters.<br> <br></blockquote></div>[Alan] Yes, we should pass all the info host required to decode. Thanks again for your detailed explanation!<br>
<br>