📄 trace.cxx
字号:
//{{{ Banner //============================================================================//// trace.cxx//// Host side implementation of the infrastructure trace facilities.////============================================================================//####COPYRIGHTBEGIN####// // ----------------------------------------------------------------------------// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.//// This file is part of the eCos host tools.//// This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version.// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details.// // You should have received a copy of the GNU General Public License along with// this program; if not, write to the Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//// ----------------------------------------------------------------------------// //####COPYRIGHTEND####//============================================================================//#####DESCRIPTIONBEGIN####//// Author(s): bartv// Contact(s): bartv// Date: 1998/12/07// Version: 0.01// Purpose: To provide a host-side implementation of the eCos tracing// facilities.////####DESCRIPTIONEND####//============================================================================//}}}//{{{ #include's // Make sure that the host-side extensions get prototyped// as well. Note that the tracing code needs to interact// with the assertion facilities to set up an appropriate// callback.#define CYG_DECLARE_HOST_ASSERTION_SUPPORT#include "pkgconf/infra.h"#include "cyg/infra/cyg_type.h"#include "cyg/infra/cyg_ass.h"// Without this #define the tracing enums and prototypes are// not visible.#define CYGDBG_USE_TRACING#include "cyg/infra/cyg_trac.h"// The standard C++ string class is used extensively#include <string>// Add a few C headers#include <cctype>#include <cstring>#include <cstdio>//}}}//{{{ Description // -------------------------------------------------------------------------// The tracing macros end up calling one of the following routines://// void cyg_tracenomsg(cyg_uint32 what, char* fn, char* file, cyg_uint32 line)// void cyg_tracemsg( ..., char* msg)// void cyg_tracemsg2( ..., CYG_ADDRWORD arg0, CYG_ADDRWORD arg1 )// void cyg_tracemsg4( ..., CYG_ADDRWORD arg0, CYG_ADDRWORD arg1, ... )// void cyg_tracemsg6( ..., CYG_ADDRWORD arg0, CYG_ADDRWORD arg1, ... )// void cyg_tracemsg8( ..., CYG_ADDRWORD arg0, CYG_ADDRWORD arg1, ... )//// For the 2/4/6/8 variants the msg argument is essentially a printf()// style format string. However the intention is that the implementation// of the trace code can delay doing the formatting until the trace// information is actually needed (with obvious consequences for// generated strings). Such an implementation would significantly // reduce the overheads associated with tracing, and is what is implemented// here.//// CYG_ADDRWORD is likely to be either "int" or the platform-specific// 64 bit data type: it should be big enough to hold either a pointer// or any normal integral type. This causes problems on machines which// have e.g. 32 bit int and 64 bit long: any 32 bit quantities will// have been converted to 64 bit quantities in the calling code, and// it is no longer possible to just pass the format string to sprintf().// Instead what amounts to a re-implementation of sprintf() is needed// here.//// The basic implementation of this trace code is as follows://// 1) a static array of data structures to hold the trace data. The// size can be configured. There is a current index into this// array.//// 2) the various trace functions simply update this array and the// counter.//// 3) all of the trace functions also check a static to see whether// or not it is necessary to install a trace handler. This cannot// be done by means of a static object due to constructor priority// ordering problems.//// 4) the callback function does all the hardware of the formatting// etc.//}}}//{{{ Types and statics // ----------------------------------------------------------------------------// A data structure rather than a class is used to hold the trace data.// This guarantees that the array gets put in the bss section and is properly// zeroed. A "valid" field in the structure can be checked when dumping the// array.typedef struct trace_entry { bool valid; cyg_uint32 what; cyg_uint32 line; char* fn; char* file; char* msg; CYG_ADDRWORD data[8];} trace_entry;#ifndef CYGNUM_INFRA_TRACE_VECTOR_SIZE# define CYGNUM_INFRA_TRACE_VECTOR_SIZE 2048#endifstatic trace_entry tracevec[CYGNUM_INFRA_TRACE_VECTOR_SIZE];static volatile int trace_index = 0;// Forward declaration of the callback function, for convenience.static void trace_callback(void (*)(const char*));// Has the callback been installed yet?static bool callback_installed = false;//}}}//{{{ The trace functions themselves // ----------------------------------------------------------------------------// The functions that get called by the trace macros. Typically these work// as follows://// 1) read and increment the trace index. This makes tracing marginally usable// in multi-threaded systems.//// 2) invalidate the entry that is about to be updated. Again this helps a bit// with multi-threaded systems.//// 3) fill in all the fields as per the command-line arguments, zeroing// unused fields.//// 4) set the valid flag to true, which means the contents can now be output.//// This is by no means sufficient to guarantee that a call to dump the trace// vector in some other thread can work safely, but it may help a little bit.extern "C" voidcyg_tracenomsg(char* fn, char* file, cyg_uint32 line){ int i = trace_index; tracevec[i].valid = false; trace_index = (trace_index + 1) % CYGNUM_INFRA_TRACE_VECTOR_SIZE; tracevec[i].what = cyg_trace_trace; tracevec[i].fn = fn; tracevec[i].file = file; tracevec[i].line = line; tracevec[i].msg = 0; tracevec[i].data[0] = 0; tracevec[i].data[1] = 0; tracevec[i].data[2] = 0; tracevec[i].data[3] = 0; tracevec[i].data[4] = 0; tracevec[i].data[5] = 0; tracevec[i].data[6] = 0; tracevec[i].data[7] = 0; tracevec[i].valid = true; if (!callback_installed) { cyg_assert_install_failure_callback("Trace", &trace_callback); callback_installed = true; }}extern "C" voidcyg_tracemsg(cyg_uint32 what, char* fn, char* file, cyg_uint32 line, char* msg){ int i = trace_index; tracevec[i].valid = false; trace_index = (trace_index + 1) % CYGNUM_INFRA_TRACE_VECTOR_SIZE; tracevec[i].what = what; tracevec[i].fn = fn; tracevec[i].file = file; tracevec[i].line = line; tracevec[i].msg = msg; tracevec[i].data[0] = 0; tracevec[i].data[1] = 0; tracevec[i].data[2] = 0; tracevec[i].data[3] = 0; tracevec[i].data[4] = 0; tracevec[i].data[5] = 0; tracevec[i].data[6] = 0; tracevec[i].data[7] = 0; tracevec[i].valid = true; if (!callback_installed) { cyg_assert_install_failure_callback("Trace", &trace_callback); callback_installed = true; }}extern "C" voidcyg_tracemsg2(cyg_uint32 what, char *fn, char* file, cyg_uint32 line, char *msg, CYG_ADDRWORD arg0, CYG_ADDRWORD arg1){ int i = trace_index; tracevec[i].valid = false; trace_index = (trace_index + 1) % CYGNUM_INFRA_TRACE_VECTOR_SIZE; tracevec[i].what = what; tracevec[i].fn = fn; tracevec[i].file = file; tracevec[i].line = line; tracevec[i].msg = msg; tracevec[i].data[0] = arg0; tracevec[i].data[1] = arg1; tracevec[i].data[2] = 0; tracevec[i].data[3] = 0; tracevec[i].data[4] = 0; tracevec[i].data[5] = 0; tracevec[i].data[6] = 0; tracevec[i].data[7] = 0; tracevec[i].valid = true; if (!callback_installed) { cyg_assert_install_failure_callback("Trace", &trace_callback); callback_installed = true; }}extern "C" voidcyg_tracemsg4(cyg_uint32 what, char *fn, char* file, cyg_uint32 line, char *msg, CYG_ADDRWORD arg0, CYG_ADDRWORD arg1, CYG_ADDRWORD arg2, CYG_ADDRWORD arg3){ int i = trace_index; tracevec[i].valid = false; trace_index = (trace_index + 1) % CYGNUM_INFRA_TRACE_VECTOR_SIZE; tracevec[i].what = what; tracevec[i].fn = fn; tracevec[i].file = file; tracevec[i].line = line; tracevec[i].msg = msg; tracevec[i].data[0] = arg0; tracevec[i].data[1] = arg1; tracevec[i].data[2] = arg2; tracevec[i].data[3] = arg3; tracevec[i].data[4] = 0; tracevec[i].data[5] = 0; tracevec[i].data[6] = 0; tracevec[i].data[7] = 0; tracevec[i].valid = true; if (!callback_installed) { cyg_assert_install_failure_callback("Trace", &trace_callback); callback_installed = true; }}extern "C" voidcyg_tracemsg6(cyg_uint32 what, char *fn, char* file, cyg_uint32 line, char *msg, CYG_ADDRWORD arg0, CYG_ADDRWORD arg1, CYG_ADDRWORD arg2, CYG_ADDRWORD arg3, CYG_ADDRWORD arg4, CYG_ADDRWORD arg5){ int i = trace_index; tracevec[i].valid = false; trace_index = (trace_index + 1) % CYGNUM_INFRA_TRACE_VECTOR_SIZE; tracevec[i].what = what; tracevec[i].fn = fn; tracevec[i].file = file; tracevec[i].line = line; tracevec[i].msg = msg; tracevec[i].data[0] = arg0; tracevec[i].data[1] = arg1; tracevec[i].data[2] = arg2; tracevec[i].data[3] = arg3; tracevec[i].data[4] = arg4; tracevec[i].data[5] = arg5; tracevec[i].data[6] = 0; tracevec[i].data[7] = 0; tracevec[i].valid = true; if (!callback_installed) { cyg_assert_install_failure_callback("Trace", &trace_callback); callback_installed = true; }}extern "C" voidcyg_tracemsg8(cyg_uint32 what, char *fn, char* file, cyg_uint32 line, char *msg, CYG_ADDRWORD arg0, CYG_ADDRWORD arg1, CYG_ADDRWORD arg2, CYG_ADDRWORD arg3, CYG_ADDRWORD arg4, CYG_ADDRWORD arg5, CYG_ADDRWORD arg6, CYG_ADDRWORD arg7){ int i = trace_index; tracevec[i].valid = false; trace_index = (trace_index + 1) % CYGNUM_INFRA_TRACE_VECTOR_SIZE; tracevec[i].what = what; tracevec[i].fn = fn; tracevec[i].file = file; tracevec[i].line = line; tracevec[i].msg = msg; tracevec[i].data[0] = arg0; tracevec[i].data[1] = arg1; tracevec[i].data[2] = arg2; tracevec[i].data[3] = arg3; tracevec[i].data[4] = arg4; tracevec[i].data[5] = arg5; tracevec[i].data[6] = arg6; tracevec[i].data[7] = arg7;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -