📄 sde.c
字号:
/* * @(#)SDE.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. */#include <setjmp.h>#include "util.h"#include "SDE.h"/** * This SourceDebugExtension code does not * allow concurrent translation - due to caching method. * A separate thread setting the default stratum ID * is, however, fine. */#define INIT_SIZE_FILE 10#define INIT_SIZE_LINE 100#define INIT_SIZE_STRATUM 3#define BASE_STRATUM_NAME "Java"#define null NULL#define true JNI_TRUE#define false JNI_FALSE#define String char *#define private statictypedef struct { int fileId; String sourceName; String sourcePath; /* do not read - use accessor */ int isConverted;} FileTableRecord;typedef struct { int jplsStart; int jplsEnd; int jplsLineInc; int njplsStart; int njplsEnd; int fileId;} LineTableRecord;typedef struct { String id; int fileIndex; int lineIndex;} StratumTableRecord;/* back-end wide value for default stratum */private String globalDefaultStratumId = null;/* reference type default */private String defaultStratumId = null;private jclass cachedClass = NULL;private FileTableRecord* fileTable;private LineTableRecord* lineTable;private StratumTableRecord* stratumTable;private int fileTableSize;private int lineTableSize;private int stratumTableSize;private int fileIndex;private int lineIndex;private int stratumIndex = 0;private int currentFileId;private int defaultStratumIndex;private int baseStratumIndex;private char* sdePos;private char* jplsFilename = null; private char* NullString = null; /* mangled in parse, cannot be parsed. Must be kept. */private String sourceDebugExtension;private jboolean sourceMapIsValid;private jmp_buf jmp_buf_env;private int stratumTableIndex(String stratumId);private int stiLineTableIndex(int sti, int jplsLine);private int stiLineNumber(int sti, int lti, int jplsLine);private void decode(void);private void ignoreWhite(void);private jboolean isValid(void); private void loadDebugInfo(JNIEnv *env, jclass clazz) { if (!isSameObject(env, clazz, cachedClass)) { /* Not the same - swap out the info */ /* Delete existing info */ if ( cachedClass != null ) { tossGlobalRef(env, &cachedClass); cachedClass = null; } if ( sourceDebugExtension!=null ) { jvmtiDeallocate(sourceDebugExtension); } sourceDebugExtension = null; /* Init info */ lineTable = null; fileTable = null; stratumTable = null; lineTableSize = 0; fileTableSize = 0; stratumTableSize = 0; fileIndex = 0; lineIndex = 0; stratumIndex = 0; currentFileId = 0; defaultStratumId = null; defaultStratumIndex = -1; baseStratumIndex = -2; /* so as not to match -1 above */ sourceMapIsValid = false; if (getSourceDebugExtension(clazz, &sourceDebugExtension) == JVMTI_ERROR_NONE) { sdePos = sourceDebugExtension; if (setjmp(jmp_buf_env) == 0) { /* this is the initial (non-error) case, do parse */ decode(); } } cachedClass = null; saveGlobalRef(env, clazz, &cachedClass); } } /* Return 1 if match, 0 if no match */ private int patternMatch(char *classname, const char *pattern) { int pattLen; int compLen; char *start; int offset; if (pattern == NULL || classname == NULL) { return 0; } pattLen = (int)strlen(pattern); if ((pattern[0] != '*') && (pattern[pattLen-1] != '*')) { return strcmp(pattern, classname) == 0; } compLen = pattLen - 1; offset = (int)strlen(classname) - compLen; if (offset < 0) { return 0; } if (pattern[0] == '*') { pattern++; start = classname + offset; } else { start = classname; } return strncmp(pattern, start, compLen) == 0; } /** * Return 1 if p1 is a SourceName for stratum sti, * else, return 0. */ private int searchOneSourceName(int sti, char *p1) { int fileIndexStart = stratumTable[sti].fileIndex; /* one past end */ int fileIndexEnd = stratumTable[sti+1].fileIndex; int ii; for (ii = fileIndexStart; ii < fileIndexEnd; ++ii) { if (patternMatch(fileTable[ii].sourceName, p1)) { return 1; } } return 0; } /** * Return 1 if p1 is a SourceName for any stratum * else, return 0. */ int searchAllSourceNames(JNIEnv *env, jclass clazz, char *p1) { int ii; loadDebugInfo(env, clazz); if (!isValid()) { return 0; /* no SDE or not SourceMap */ } for (ii = 0; ii < stratumIndex - 1; ++ii) { if (searchOneSourceName(ii, p1) == 1) { return 1; } } return 0; } /** * Convert a line number table, as returned by the JVMTI * function GetLineNumberTable, to one for another stratum. * Conversion is by overwrite. * Actual line numbers are not returned - just a unique * number (file ID in top 16 bits, line number in * bottom 16 bits) - this is all stepping needs. */ void convertLineNumberTable(JNIEnv *env, jclass clazz, jint *entryCountPtr, jvmtiLineNumberEntry **tablePtr) { jvmtiLineNumberEntry *fromEntry = *tablePtr; jvmtiLineNumberEntry *toEntry = *tablePtr; int cnt = *entryCountPtr; int lastLn = 0; int sti; loadDebugInfo(env, clazz); if (!isValid()) { return; /* no SDE or not SourceMap - return unchanged */ } sti = stratumTableIndex(globalDefaultStratumId); if (sti == baseStratumIndex) { return; /* Java stratum - return unchanged */ } LOG_MISC(("SDE is re-ordering the line table")); for (; cnt-->0; ++fromEntry) { int jplsLine = fromEntry->line_number; int lti = stiLineTableIndex(sti, jplsLine); if (lti >= 0) { int fileId = lineTable[lti].fileId; int ln = stiLineNumber(sti, lti, jplsLine); ln += (fileId << 16); /* create line hash */ if (ln != lastLn) { lastLn = ln; toEntry->start_location = fromEntry->start_location; toEntry->line_number = ln; ++toEntry; } } } /*LINTED*/ *entryCountPtr = (int)(toEntry - *tablePtr); } /** * Set back-end wide default stratum ID . */ void setGlobalStratumId(char *id) { globalDefaultStratumId = id; } private void syntax(String msg) { char buf[200]; (void)snprintf(buf, sizeof(buf), "bad SourceDebugExtension syntax - position %d - %s\n", /*LINTED*/ (int)(sdePos-sourceDebugExtension), msg); JDI_ASSERT_FAILED(buf); longjmp(jmp_buf_env, 1); /* abort parse */ } private char sdePeek(void) { if (*sdePos == 0) { syntax("unexpected EOF"); } return *sdePos; } private char sdeRead(void) { if (*sdePos == 0) { syntax("unexpected EOF"); } return *sdePos++; } private void sdeAdvance(void) { sdePos++; } private void assureLineTableSize(void) { if (lineIndex >= lineTableSize) { size_t allocSize; LineTableRecord* new_lineTable; int new_lineTableSize; new_lineTableSize = lineTableSize == 0? INIT_SIZE_LINE : lineTableSize * 2; allocSize = new_lineTableSize * (int)sizeof(LineTableRecord); new_lineTable = jvmtiAllocate((jint)allocSize); if ( new_lineTable == NULL ) { EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY, "SDE line table"); } if ( lineTable!=NULL ) { (void)memcpy(new_lineTable, lineTable, lineTableSize * (int)sizeof(LineTableRecord)); jvmtiDeallocate(lineTable); } lineTable = new_lineTable; lineTableSize = new_lineTableSize; } } private void assureFileTableSize(void) { if (fileIndex >= fileTableSize) { size_t allocSize; FileTableRecord* new_fileTable; int new_fileTableSize; new_fileTableSize = fileTableSize == 0? INIT_SIZE_FILE : fileTableSize * 2; allocSize = new_fileTableSize * (int)sizeof(FileTableRecord); new_fileTable = jvmtiAllocate((jint)allocSize); if ( new_fileTable == NULL ) { EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY, "SDE file table"); } if ( fileTable!=NULL ) { (void)memcpy(new_fileTable, fileTable, fileTableSize * (int)sizeof(FileTableRecord)); jvmtiDeallocate(fileTable); } fileTable = new_fileTable; fileTableSize = new_fileTableSize; } } private void assureStratumTableSize(void) { if (stratumIndex >= stratumTableSize) { size_t allocSize; StratumTableRecord* new_stratumTable; int new_stratumTableSize;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -