eventfilter.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 1,327 行 · 第 1/3 页
C
1,327 行
/* * @(#)eventFilter.c 1.9 06/10/25 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * 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 version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. *//* * eventFilter * * This module handles event filteration and the enabling/disabling * of the corresponding events. Used for filters on JDI EventRequests * and also internal requests. Our data is in a private hidden section * of the HandlerNode's data. See comment for enclosing * module eventHandler. */#include "util.h"#include "eventFilter.h"#include "eventFilterRestricted.h"#include "eventHandlerRestricted.h"#include "stepControl.h"#include "threadControl.h"#include "SDE.h"typedef struct ClassFilter { jclass clazz;} ClassFilter;typedef struct LocationFilter { jclass clazz; jmethodID method; jlocation location;} LocationFilter;typedef struct ThreadFilter { jthread thread;} ThreadFilter;typedef struct CountFilter { jint count;} CountFilter;typedef struct ConditionalFilter { jint exprID;} ConditionalFilter;typedef struct FieldFilter { jclass clazz; jfieldID field;} FieldFilter;typedef struct ExceptionFilter { jclass exception; jboolean caught; jboolean uncaught;} ExceptionFilter;typedef struct InstanceFilter { jobject instance;} InstanceFilter;typedef struct StepFilter { jint size; jint depth; jthread thread;} StepFilter;typedef struct MatchFilter { char *classPattern;} MatchFilter;typedef struct SourceNameFilter { char *sourceNamePattern;} SourceNameFilter;typedef struct Filter_ { jbyte modifier; union { struct ClassFilter ClassOnly; struct LocationFilter LocationOnly; struct ThreadFilter ThreadOnly; struct CountFilter Count; struct ConditionalFilter Conditional; struct FieldFilter FieldOnly; struct ExceptionFilter ExceptionOnly; struct InstanceFilter InstanceOnly; struct StepFilter Step; struct MatchFilter ClassMatch; struct MatchFilter ClassExclude; struct SourceNameFilter SourceNameOnly; } u;} Filter;/* The filters array is allocated to the specified filterCount. * Theoretically, some compiler could do range checking on this * array - so, we define it to have a ludicrously large size so * that this range checking won't get upset. * * The actual allocated number of bytes is computed using the * offset of "filters" and so is not effected by this number. */#define MAX_FILTERS 10000typedef struct EventFilters_ { jint filterCount; Filter filters[MAX_FILTERS];} EventFilters;typedef struct EventFilterPrivate_HandlerNode_ { EventHandlerRestricted_HandlerNode not_for_us; EventFilters ef;} EventFilterPrivate_HandlerNode;/** * The following macros extract filter info (EventFilters) from private * data at the end of a HandlerNode */#define EVENT_FILTERS(node) (&(((EventFilterPrivate_HandlerNode*)(void*)node)->ef))#define FILTER_COUNT(node) (EVENT_FILTERS(node)->filterCount)#define FILTERS_ARRAY(node) (EVENT_FILTERS(node)->filters)#define FILTER(node,index) ((FILTERS_ARRAY(node))[index])#define NODE_EI(node) (node->ei)/***** filter set-up / destruction *****//** * Allocate a HandlerNode. * We do it because eventHandler doesn't know how big to make it. */HandlerNode *eventFilterRestricted_alloc(jint filterCount){ /*LINTED*/ size_t size = offsetof(EventFilterPrivate_HandlerNode, ef) + offsetof(EventFilters, filters) + (filterCount * (int)sizeof(Filter)); HandlerNode *node = jvmtiAllocate((jint)size); if (node != NULL) { int i; Filter *filter; (void)memset(node, 0, size); FILTER_COUNT(node) = filterCount; /* Initialize all modifiers */ for (i = 0, filter = FILTERS_ARRAY(node); i < filterCount; i++, filter++) { filter->modifier = JDWP_REQUEST_NONE; } } return node;}/** * Free up global refs held by the filter. * free things up at the JNI level if needed. */static jvmtiErrorclearFilters(HandlerNode *node){ JNIEnv *env = getEnv(); jint i; jvmtiError error = JVMTI_ERROR_NONE; Filter *filter = FILTERS_ARRAY(node); for (i = 0; i < FILTER_COUNT(node); ++i, ++filter) { switch (filter->modifier) { case JDWP_REQUEST_MODIFIER(ThreadOnly): if ( filter->u.ThreadOnly.thread != NULL ) { tossGlobalRef(env, &(filter->u.ThreadOnly.thread)); } break; case JDWP_REQUEST_MODIFIER(LocationOnly): tossGlobalRef(env, &(filter->u.LocationOnly.clazz)); break; case JDWP_REQUEST_MODIFIER(FieldOnly): tossGlobalRef(env, &(filter->u.FieldOnly.clazz)); break; case JDWP_REQUEST_MODIFIER(ExceptionOnly): if ( filter->u.ExceptionOnly.exception != NULL ) { tossGlobalRef(env, &(filter->u.ExceptionOnly.exception)); } break; case JDWP_REQUEST_MODIFIER(InstanceOnly): if ( filter->u.InstanceOnly.instance != NULL ) { tossGlobalRef(env, &(filter->u.InstanceOnly.instance)); } break; case JDWP_REQUEST_MODIFIER(ClassOnly): tossGlobalRef(env, &(filter->u.ClassOnly.clazz)); break; case JDWP_REQUEST_MODIFIER(ClassMatch): jvmtiDeallocate(filter->u.ClassMatch.classPattern); break; case JDWP_REQUEST_MODIFIER(ClassExclude): jvmtiDeallocate(filter->u.ClassExclude.classPattern); break; case JDWP_REQUEST_MODIFIER(Step): { jthread thread = filter->u.Step.thread; error = stepControl_endStep(thread); if (error == JVMTI_ERROR_NONE) { tossGlobalRef(env, &(filter->u.Step.thread)); } break; } } } if (error == JVMTI_ERROR_NONE) { FILTER_COUNT(node) = 0; /* blast so we don't clear again */ } return error;}/***** filtering *****//* * Match a string against a wildcard * string pattern. */static jboolean patternStringMatch(char *classname, const char *pattern){ int pattLen; int compLen; char *start; int offset; if ( pattern==NULL || classname==NULL ) { return JNI_FALSE; } pattLen = (int)strlen(pattern); if ((pattern[0] != '*') && (pattern[pattLen-1] != '*')) { /* An exact match is required when there is no *: bug 4331522 */ return strcmp(pattern, classname) == 0; } else { compLen = pattLen - 1; offset = (int)strlen(classname) - compLen; if (offset < 0) { return JNI_FALSE; } else { if (pattern[0] == '*') { pattern++; start = classname + offset; } else { start = classname; } return strncmp(pattern, start, compLen) == 0; } }}/* Return the object instance in which the event occurred *//* Return NULL if static or if an error occurs */static jobjecteventInstance(EventInfo *evinfo){ jobject object = NULL; jthread thread ; jmethodID method ; jint modifiers = 0; jvmtiError error; switch (evinfo->ei) { case EI_SINGLE_STEP: case EI_BREAKPOINT: case EI_FRAME_POP: case EI_METHOD_ENTRY: case EI_METHOD_EXIT: case EI_EXCEPTION: case EI_EXCEPTION_CATCH: case EI_MONITOR_CONTENDED_ENTER: case EI_MONITOR_CONTENDED_ENTERED: case EI_MONITOR_WAIT: case EI_MONITOR_WAITED: thread = evinfo->thread; method = evinfo->method; break; case EI_FIELD_ACCESS: case EI_FIELD_MODIFICATION: object = evinfo->object; return object; default: return object; /* NULL */ } error = methodModifiers(method, &modifiers); /* fail if error or static (0x8) */ if (error == JVMTI_ERROR_NONE && thread!=NULL && (modifiers & 0x8) == 0) { FrameNumber fnum = 0; /* get slot zero object "this" */ error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalObject) (gdata->jvmti, thread, fnum, 0, &object); if (error != JVMTI_ERROR_NONE) object = NULL; } return object;}/* * Determine if this event is interesting to this handler. * Do so by checking each of the handler's filters. * Return false if any of the filters fail, * true if the handler wants this event. * Anyone modifying this function should check * eventFilterRestricted_passesUnloadFilter and * eventFilter_predictFiltering as well. * * If shouldDelete is returned true, a count filter has expired * and the corresponding node should be deleted. */jboolean eventFilterRestricted_passesFilter(JNIEnv *env, char *classname, EventInfo *evinfo, HandlerNode *node, jboolean *shouldDelete){ jthread thread; jclass clazz; jmethodID method; Filter *filter = FILTERS_ARRAY(node); int i; *shouldDelete = JNI_FALSE; thread = evinfo->thread; clazz = evinfo->clazz; method = evinfo->method; /* * Suppress most events if they happen in debug threads */ if ((evinfo->ei != EI_CLASS_PREPARE) && (evinfo->ei != EI_GC_FINISH) && (evinfo->ei != EI_CLASS_LOAD) && threadControl_isDebugThread(thread)) { return JNI_FALSE; } for (i = 0; i < FILTER_COUNT(node); ++i, ++filter) { switch (filter->modifier) { case JDWP_REQUEST_MODIFIER(ThreadOnly): if (!isSameObject(env, thread, filter->u.ThreadOnly.thread)) { return JNI_FALSE; } break; case JDWP_REQUEST_MODIFIER(ClassOnly): /* Class filters catch events in the specified * class and any subclass/subinterface. */ if (!JNI_FUNC_PTR(env,IsAssignableFrom)(env, clazz, filter->u.ClassOnly.clazz)) { return JNI_FALSE; } break; /* This is kinda cheating assumming the event * fields will be in the same locations, but it is * true now. */ case JDWP_REQUEST_MODIFIER(LocationOnly): if (evinfo->method != filter->u.LocationOnly.method || evinfo->location != filter->u.LocationOnly.location || !isSameObject(env, clazz, filter->u.LocationOnly.clazz)) { return JNI_FALSE; } break; case JDWP_REQUEST_MODIFIER(FieldOnly): /* Field watchpoints can be triggered from the * declared class or any subclass/subinterface. */ if ((evinfo->u.field_access.field != filter->u.FieldOnly.field) || !isSameObject(env, evinfo->u.field_access.field_clazz, filter->u.FieldOnly.clazz)) { return JNI_FALSE; } break; case JDWP_REQUEST_MODIFIER(ExceptionOnly): /* do we want caught/uncaught exceptions */ if (!((evinfo->u.exception.catch_clazz == NULL)? filter->u.ExceptionOnly.uncaught : filter->u.ExceptionOnly.caught)) { return JNI_FALSE; } /* do we care about exception class */ if (filter->u.ExceptionOnly.exception != NULL) { jclass exception = evinfo->object; /* do we want this exception class */ if (!JNI_FUNC_PTR(env,IsInstanceOf)(env, exception, filter->u.ExceptionOnly.exception)) { return JNI_FALSE; } } break; case JDWP_REQUEST_MODIFIER(InstanceOnly): { jobject eventInst = eventInstance(evinfo); jobject filterInst = filter->u.InstanceOnly.instance; /* if no error and doesn't match, don't pass * filter */ if (eventInst != NULL && !isSameObject(env, eventInst, filterInst)) { return JNI_FALSE; } break; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?