/* This file is part of the db4o object database http://www.db4o.com Copyright (C) 2004 - 2011 Versant Corporation http://www.versant.com db4o is free software; you can redistribute it and/or modify it under the terms of version 3 of the GNU General Public License as published by the Free Software Foundation. db4o 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, see http://www.gnu.org/licenses/. */ package com.db4o; import java.io.*; import com.db4o.foundation.*; import com.db4o.internal.encoding.*; import com.db4o.internal.handlers.*; import com.db4o.internal.slots.*; /** * @exclude */ public class DTrace { public static boolean enabled = false; public static boolean writeToLogFile = false; public static boolean writeToConsole = true; private static final String logFilePath = "C://"; private static String logFileName; private static final Object lock = new Object(); private static final LatinStringIO stringIO = new LatinStringIO(); public static RandomAccessFile _logFile; private static int UNUSED = -1; private static void breakPoint(){ if(enabled){ /* breakpoint here */ int xxx = 1; } } private static final void configure(){ if(enabled){ // addRange(15); // breakOnEvent(540); // // addRangeWithEnd(448, 460); // addRangeWithLength(770,53); // breakOnEvent(125); // trackEventsWithoutRange(); // turnAllOffExceptFor(new DTrace[] {WRITE_BYTES}); // turnAllOffExceptFor(new DTrace[] { // PERSISTENT_OWN_LENGTH, // }); // turnAllOffExceptFor(new DTrace[] { // GET_SLOT, // FILE_FREE, // TRANS_COMMIT, // }); // turnAllOffExceptFor(new DTrace[] {WRITE_BYTES}); // turnAllOffExceptFor(new DTrace[] {BTREE_NODE_REMOVE, BTREE_NODE_COMMIT_OR_ROLLBACK YAPMETA_SET_ID}); } } private static final void init() { if (enabled) { ADD_TO_CLASS_INDEX = new DTrace(true, true, "add to class index tree", true); BEGIN_TOP_LEVEL_CALL = new DTrace(true, true, "begin top level call", true); BIND = new DTrace(true, true, "bind", true); BLOCKING_QUEUE_STOPPED_EXCEPTION = new DTrace(true, true, "blocking queue stopped exception", true); BTREE_NODE_REMOVE = new DTrace(true, true, "btreenode remove", true); BTREE_NODE_COMMIT_OR_ROLLBACK = new DTrace(true, true, "btreenode commit or rollback", true); BTREE_PRODUCE_NODE = new DTrace(true, true, "btree produce node", true); CANDIDATE_READ = new DTrace(true, true, "candidate read", true); CLASSMETADATA_BY_ID = new DTrace(true, true, "classmetadata by id", true); CLASSMETADATA_INIT = new DTrace(true, true, "classmetadata init", true); CLIENT_MESSAGE_LOOP_EXCEPTION = new DTrace(true, true, "client message loop exception", true); CLOSE = new DTrace(true, true, "close", true); CLOSE_CALLED = new DTrace(true, true, "close called", true); COLLECT_CHILDREN = new DTrace(true, true, "collect children", true); COMMIT = new DTrace(false, false, "commit", true); CONTINUESET = new DTrace(true, true, "continueset", true); CREATE_CANDIDATE = new DTrace(true, true, "create candidate", true); DELETE = new DTrace(true, true, "delete", true); DONOTINCLUDE = new DTrace(true, true, "donotinclude", true); END_TOP_LEVEL_CALL = new DTrace(true, true, "end top level call", true); EVALUATE_SELF = new DTrace(true, true, "evaluate self", true); FATAL_EXCEPTION = new DTrace(true, true, "fatal exception", true); FREE = new DTrace(true, true, "free", true); FILE_FREE = new DTrace(true, true, "fileFree", true); FILE_READ = new DTrace(true, true, "fileRead", true); FILE_WRITE = new DTrace(true, true, "fileWrite", true); FREESPACEMANAGER_GET_SLOT = new DTrace(true, true, "FreespaceManager getSlot", true); FREESPACEMANAGER_RAM_FREE = new DTrace(true, true, "InMemoryfreespaceManager free", true); FREESPACEMANAGER_BTREE_FREE = new DTrace(true, true, "BTreeFreeSpaceManager free", true); FREE_ON_COMMIT = new DTrace(true, true, "trans freeOnCommit", true); FREE_ON_ROLLBACK = new DTrace(true, true, "trans freeOnRollback", true); FREE_POINTER_ON_ROLLBACK = new DTrace(true, true, "freePointerOnRollback", true); GET_POINTER_SLOT = new DTrace(true, true, "getPointerSlot", true); GET_SLOT = new DTrace(true, true, "getSlot", true); GET_FREESPACE_RAM = new DTrace(true, true, "getFreespaceRam", true); GET_YAPOBJECT = new DTrace(true, true, "get ObjectReference", true); ID_TREE_ADD = new DTrace(true, true, "id tree add", true); ID_TREE_REMOVE = new DTrace(true, true, "id tree remove", true); IO_COPY = new DTrace(true, true, "io copy", true); JUST_SET = new DTrace(true, true, "just set", true); NEW_INSTANCE = new DTrace(true, true, "newInstance", true); NOTIFY_SLOT_CREATED = new DTrace(true, true, "notifySlotCreated", true); NOTIFY_SLOT_UPDATED = new DTrace(true, true, "notify Slot updated", true); NOTIFY_SLOT_DELETED = new DTrace(true, true, "notifySlotDeleted", true); OBJECT_REFERENCE_CREATED = new DTrace(true, true, "new ObjectReference", true); PERSISTENT_BASE_NEW_SLOT = new DTrace(true, true, "PersistentBase new slot",true); PERSISTENT_OWN_LENGTH = new DTrace(true, true, "Persistent own length", true); PERSISTENTBASE_WRITE = new DTrace(true, true, "persistentbase write", true); PERSISTENTBASE_SET_ID = new DTrace(true, true, "persistentbase setid", true); PRODUCE_SLOT_CHANGE = new DTrace(true, true, "produce slot change", true); QUERY_PROCESS = new DTrace(true, true, "query process", true); READ_ARRAY_WRAPPER = new DTrace(true, true, "read array wrapper", true); READ_BYTES = new DTrace(true, true, "readBytes", true); READ_SLOT = new DTrace(true, true, "read slot", true); REFERENCE_REMOVED = new DTrace(true, true, "reference removed", true); REGULAR_SEEK = new DTrace(true, true, "regular seek", true); REMOVE_FROM_CLASS_INDEX = new DTrace(true, true, "trans removeFromClassIndexTree", true); REREAD_OLD_UUID = new DTrace(true, true, "reread old uuid", true); SERVER_MESSAGE_LOOP_EXCEPTION = new DTrace(true, true, "server message loop exception", true); SLOT_MAPPED = new DTrace(true, true, "slot mapped", true); SLOT_COMMITTED = new DTrace(true, true, "slot committed", true); SLOT_FREE_ON_COMMIT = new DTrace(true, true, "slot free on commit", true); SLOT_FREE_ON_ROLLBACK_ID = new DTrace(true, true, "slot free on rollback id", true); SLOT_FREE_ON_ROLLBACK_ADDRESS = new DTrace(true, true, "slot free on rollback address", true); SLOT_READ = new DTrace(true, true, "slot read", true); TRANS_COMMIT = new DTrace(true, true, "trans commit", true); TRANS_DELETE = new DTrace(true, true, "trans delete", true); TRANS_DONT_DELETE = new DTrace(true, true, "trans dontDelete", true); TRANS_FLUSH = new DTrace(true, true, "trans flush", true); WRITE_BYTES = new DTrace(true, true, "writeBytes", true); WRITE_POINTER = new DTrace(true, true, "write pointer", true); WRITE_UPDATE_ADJUST_INDEXES = new DTrace(true, true, "trans writeUpdateDeleteMembers", true); WRITE_XBYTES = new DTrace(true, true, "writeXBytes", true); configure(); } } private static void trackEventsWithoutRange() { _trackEventsWithoutRange = true; } private DTrace(boolean enabled_, boolean break_, String tag_, boolean log_){ if(enabled){ _enabled = enabled_; _break = break_; _tag = tag_; _log = log_; if(all == null){ all = new DTrace[100]; } all[current++] = this; } } private boolean _enabled; private boolean _break; private boolean _log; private String _tag; private static long[] _rangeStart; private static long [] _rangeEnd; private static int _rangeCount; public static long _eventNr; private static long[] _breakEventNrs; private static int _breakEventCount; private static boolean _breakAfterEvent; private static boolean _trackEventsWithoutRange; public static DTrace ADD_TO_CLASS_INDEX; public static DTrace BEGIN_TOP_LEVEL_CALL; public static DTrace BIND; public static DTrace BLOCKING_QUEUE_STOPPED_EXCEPTION; public static DTrace BTREE_NODE_COMMIT_OR_ROLLBACK; public static DTrace BTREE_NODE_REMOVE; public static DTrace BTREE_PRODUCE_NODE; public static DTrace CANDIDATE_READ; public static DTrace CLASSMETADATA_BY_ID; public static DTrace CLASSMETADATA_INIT; public static DTrace CLIENT_MESSAGE_LOOP_EXCEPTION; public static DTrace CLOSE; public static DTrace CLOSE_CALLED; public static DTrace COLLECT_CHILDREN; public static DTrace COMMIT; public static DTrace CONTINUESET; public static DTrace CREATE_CANDIDATE; public static DTrace DELETE; public static DTrace DONOTINCLUDE; public static DTrace END_TOP_LEVEL_CALL; public static DTrace EVALUATE_SELF; public static DTrace FATAL_EXCEPTION; public static DTrace FILE_FREE; public static DTrace FILE_READ; public static DTrace FILE_WRITE; public static DTrace FREE; public static DTrace FREESPACEMANAGER_GET_SLOT; public static DTrace FREESPACEMANAGER_RAM_FREE; public static DTrace FREESPACEMANAGER_BTREE_FREE; public static DTrace FREE_ON_COMMIT; public static DTrace FREE_ON_ROLLBACK; public static DTrace FREE_POINTER_ON_ROLLBACK; public static DTrace GET_SLOT; public static DTrace GET_POINTER_SLOT; public static DTrace GET_FREESPACE_RAM; public static DTrace GET_YAPOBJECT; public static DTrace ID_TREE_ADD; public static DTrace ID_TREE_REMOVE; public static DTrace IO_COPY; public static DTrace JUST_SET; public static DTrace NEW_INSTANCE; public static DTrace NOTIFY_SLOT_CREATED; public static DTrace NOTIFY_SLOT_UPDATED; public static DTrace NOTIFY_SLOT_DELETED; public static DTrace OBJECT_REFERENCE_CREATED; public static DTrace PERSISTENT_BASE_NEW_SLOT; public static DTrace PERSISTENT_OWN_LENGTH; public static DTrace PERSISTENTBASE_SET_ID; public static DTrace PERSISTENTBASE_WRITE; public static DTrace PRODUCE_SLOT_CHANGE; public static DTrace QUERY_PROCESS; public static DTrace READ_ARRAY_WRAPPER; public static DTrace READ_BYTES; public static DTrace READ_SLOT; public static DTrace REFERENCE_REMOVED; public static DTrace REGULAR_SEEK; public static DTrace REMOVE_FROM_CLASS_INDEX; public static DTrace REREAD_OLD_UUID; public static DTrace SERVER_MESSAGE_LOOP_EXCEPTION; public static DTrace SLOT_MAPPED; public static DTrace SLOT_COMMITTED; public static DTrace SLOT_FREE_ON_COMMIT; public static DTrace SLOT_FREE_ON_ROLLBACK_ID; public static DTrace SLOT_FREE_ON_ROLLBACK_ADDRESS; public static DTrace SLOT_READ; public static DTrace TRANS_COMMIT; public static DTrace TRANS_DONT_DELETE; public static DTrace TRANS_DELETE; public static DTrace TRANS_FLUSH; public static DTrace WRITE_BYTES; public static DTrace WRITE_POINTER; public static DTrace WRITE_XBYTES; public static DTrace WRITE_UPDATE_ADJUST_INDEXES; static{ init(); } private static DTrace[] all; private static int current; public void log(){ if(enabled){ log(UNUSED); } } public void log(String msg){ if(enabled){ log(UNUSED, msg); } } public void log(long p){ if(enabled){ logLength(p, 1); } } public void logInfo(String info){ if(enabled){ logEnd(UNUSED, UNUSED,0, info ); } } public void log(long p, String info){ if(enabled){ logEnd(UNUSED, p, 0, info); } } public void logLength(long start, long length){ if(enabled){ logLength(UNUSED, start, length); } } public void logLength(long id, long start, long length){ if(enabled){ logEnd(id, start, start + length - 1); } } public void logLength(Slot slot){ if(enabled){ logLength(UNUSED, slot); } } public void logLength(long id, Slot slot){ if(enabled){ if(slot == null){ return; } logLength(id, slot.address(), slot.length()); } } public void logEnd(long start, long end){ if(enabled){ logEnd(UNUSED, start, end); } } public void logEnd(long id, long start, long end){ if(enabled){ logEnd(id, start, end, null); } } public void logEnd(long id, long start, long end, String info){ // if(! Deploy.log){ // return; // } if(enabled){ if(! _enabled){ return; } boolean inRange = false; if(_rangeCount == 0){ inRange = true; } for (int i = 0; i < _rangeCount; i++) { // Case 0 ID in range if(id >= _rangeStart[i] && id <= _rangeEnd[i]){ inRange = true; break; } // Case 1 start in range if(start >= _rangeStart[i] && start <= _rangeEnd[i]){ inRange = true; break; } if(end != 0){ // Case 2 end in range if (end >= _rangeStart[i] && end <= _rangeEnd[i]){ inRange = true; break; } // Case 3 start before range, end after range if(start <= _rangeStart[i] && end >= _rangeEnd[i]){ inRange = true; break; } } } if(inRange || ( _trackEventsWithoutRange && (start == UNUSED) )){ if(_log){ _eventNr ++; StringBuffer sb = new StringBuffer(":"); sb.append(formatInt(_eventNr, 6)); sb.append(":"); sb.append(formatInt(id)); sb.append(":"); sb.append(formatInt(start)); sb.append(":"); if(end != 0 && start != end){ sb.append(formatInt(end)); sb.append(":"); sb.append(formatInt(end - start + 1)); }else{ sb.append(formatUnused()); sb.append(":"); sb.append(formatUnused()); } sb.append(":"); if(info != null){ sb.append(" " + info + " "); sb.append(":"); } sb.append(" "); sb.append(_tag); logToOutput(sb.toString()); } if(_break){ if(_breakEventCount > 0){ for (int i = 0; i < _breakEventCount; i++) { if(_breakEventNrs[i] == _eventNr){ breakPoint(); break; } } if(_breakAfterEvent){ for (int i = 0; i < _breakEventCount; i++) { if(_breakEventNrs[i] <= _eventNr){ breakPoint(); break; } } } }else{ breakPoint(); } } } } } private String formatUnused() { return formatInt(UNUSED); } private static void logToOutput(String msg){ if(enabled){ logToFile(msg); logToConsole(msg); } } private static void logToConsole(String msg){ if(enabled){ if(writeToConsole){ System.out.println(msg); } } } private static void logToFile(String msg){ if(enabled){ if(! writeToLogFile){ return; } synchronized(lock){ if(_logFile == null){ try { _logFile = new RandomAccessFile(logFile(), "rw"); logToFile("\r\n\r\n ********** BEGIN LOG ********** \r\n\r\n "); } catch (IOException e) { e.printStackTrace(); } } msg = DateHandlerBase.now() + "\r\n" + msg + "\r\n"; byte[] bytes = stringIO.write(msg); try { _logFile.write(bytes); } catch (IOException e) { e.printStackTrace(); } } } } private static String logFile(){ if(enabled){ if(logFileName != null){ return logFileName; } logFileName = "db4oDTrace_" + DateHandlerBase.now() + "_" + SignatureGenerator.generateSignature() + ".log"; logFileName = logFileName.replace(' ', '_'); logFileName = logFileName.replace(':', '_'); logFileName = logFileName.replace('-', '_'); return logFilePath + logFileName; } return null; } public static void addRange(long pos){ if(enabled){ addRangeWithEnd(pos, pos); } } public static void addRangeWithLength(long start, long length){ if(enabled){ addRangeWithEnd(start, start + length - 1); } } public static void addRangeWithEnd(long start, long end){ if(enabled){ if(_rangeStart == null){ _rangeStart = new long[1000]; _rangeEnd = new long[1000]; } _rangeStart[_rangeCount] = start; _rangeEnd[_rangeCount] = end; _rangeCount++; } } // private static void breakFromEvent(long eventNr){ // breakOnEvent(eventNr); // _breakAfterEvent = true; // } private static void breakOnEvent(long eventNr){ if(enabled){ if(_breakEventNrs == null){ _breakEventNrs = new long[100]; } _breakEventNrs[_breakEventCount] = eventNr; _breakEventCount ++; } } private String formatInt(long i, int len){ if(enabled){ String str = " "; if( i != UNUSED){ str += i + " "; } return str.substring(str.length() - len); } return null; } private String formatInt(long i){ if(enabled){ return formatInt(i, 10); } return null; } private static void turnAllOffExceptFor(DTrace[] these){ if(enabled){ for (int i = 0; i < all.length; i++) { if(all[i] == null){ break; } boolean turnOff = true; for (int j = 0; j < these.length; j++) { if(all[i] == these[j]){ turnOff = false; break; } } if(turnOff){ all[i]._break = false; all[i]._enabled = false; all[i]._log = false; } } } } public static void noWarnings(){ breakOnEvent(0); trackEventsWithoutRange(); } }