DTrace 0.1 Release
Purpose
This is the 0.1 Release for this project, developed by Hellwolf36 (Chris Cameirao)
The purpose of 0.1 is to show that I am aware of how a D-Trace probe works, by using a D script to pick up on function call counts (for now) and see what it can gather. This functionality can only be tested on Mac OS X 10.5 Leopard or Open Solaris.
Being able to write a D-Trace script helps when I start writing probes for 0.2.
Step 1: Build Pre-requisites
The user is responsible for making sure that thier Mac or Solaris machine has met the requirements for building Mozilla. These instructions (Mac or OpenSolaris) must be met. It is recommended that you have at least built Mozilla at least once and are able to run it.
You must build v3.0.1 or higher of Mozilla Firefox in order to have D-Trace functionality. I used 3.0.3. Retrieve this version here
Step 2: Change your $PATH global
There is one specific header file that client.mk or configure will check for. It is called sys/sdt.h. If your current PATH cannot link to it, then not only will D-Trace not work, but Mozilla will not compile. In Mac and Solaris, this problem should be resolved by using this as your $PATH:
export PATH=/usr/include/sys:/usr/include:/opt/local/bin:/opt/local/sbin:$PATH
/usr/include/(sys) contains the sys/sdt.h header you need. The other 2 help resolve a possible issue when compiling on Mac (Your compiler may say libIDL and GLib cannot be found - even after installing it, this should resolve it).
Step 3: .Mozconfig file
Once you have extracted all the contents of the tar file (from Step 1), you should have a mozilla directory.
//Assuming you placed it within your home directory<br> $cd ~/mozilla $vi .mozconfig ac_add_options --enable-dtrace ac_add_options --disable-tests ac_add_options --disable-debug ac_add_options --enable-optimize ac_add_options --enable-application=browser
The first option is the one we need. This tells the build to check for D-Trace dependancies and build the necessary probes on runtime. The rest are to ensure your build goes as fast as possible, and the application in the end will consume less memory. :wq out of the file and compile Mozilla using:
//Mac make -f client.mk build //OpenSolaris gmake -f client.mk build
Some people often omit the dtrace line from .mozconfig and run this command instead:
$ configure --enable-dtrace $ make or gmake
This works the same way. But I have seen most OpenSolaris people do this when it comes to installing patches to improve the D-Trace functionality.
Step 4: Check for current probes
It is wise that you have 2 Terminals running at this point. 1 will allow you to keep firefox running, the other will allow you to do dtrace grunt work.
In order to pick up any current probes, you must run the firefox-bin while you do these commands. Re-direct yourself to the Mozilla application you will use.
//OpenSolaris $ cd dist/bin //Mac<br> $ cd dist/Minefield.app/Contents/MacOS //Run the executable specified with (you may run it in Background if you wish) $ ./firefox-bin -profilemanager [$]
Upon running, it is wise to create yourself a seperate profile than the one you are using for Firefox. This helps if you have 2 different versions of it running at once.
To get a list of any javascript based probes that are currently running, we will use the dtrace command. For Mac users, you need superuser permissions via sudo to make this command run.
[sudo] dtrace -n 'javascript*' -l
This command will output all currently running scripts matching this naming convention. It will only display probes that are currently running, so firefox must be running in order for this command to output. The output should look something like this (Provider ID may be different):
ID PROVIDER MODULE FUNCTION NAME 20925 javascript333 libmozjs.dylib js_Interpret function-args 20926 javascript333 libmozjs.dylib jsdtrace_function_args function-args 20927 javascript333 libmozjs.dylib js_Interpret function-entry 20928 javascript333 libmozjs.dylib jsdtrace_function_entry function-entry 20929 javascript333 libmozjs.dylib js_Interpret function-info 20930 javascript333 libmozjs.dylib jsdtrace_function_info function-info 20931 javascript333 libmozjs.dylib js_Interpret function-return 20932 javascript333 libmozjs.dylib jsdtrace_function_return function-return 20933 javascript333 libmozjs.dylib js_Interpret function-rval 20934 javascript333 libmozjs.dylib jsdtrace_function_rval function-rval
javascript333 is the unique provider for the probes. 333 is required in case you have 2 programs running that use D-Tracing (replacing the * with the number helps limit your script). libmozjs.dylib is the Mozilla module that has the definition of these probes. Each probe has 5 categories split into 2 functions - the function itself and the interpreter.
A list of all the probe definitions can be found at this blog written by John Rice.
Step 5 - Compiling a D-Trace Script
It is wise to have 2 terminals running. One for Minefield, the other for these commands:
I have written 2 DTrace scripts. The first one captures and outputs any calls found on the function-entry probe (basically the event fired when a function was entered or processed), along with how many times. The second one outputs the I/O buffer sizes your processes use.
D-Trace scripts are .d files that allow the user to interact with the existing probes and do innovative things. If a programmer tends to add new probes to the Mozilla code base, they can use a script to pick up on it to make sure it was implemented and interacted properly.
With your terminal that isn't handling Mozilla Minefield, go to your mozilla home directory, create a file called js_callcount.d and paste this code into it.
#pragma D option quiet dtrace:::BEGIN { printf("Tracing... Hit Ctrl-C to end.\n"); } javascript*:::function-entry { @funcs[basename(copyinstr(arg0)), copyinstr(arg2)] = count(); } dtrace:::END { printf(" %-32s %-36s %8s\n", "FILE", "FUNC", "CALLS"); printa(" %-32s %-36s %@8d\n", @funcs); }
Quiet will tell the system to post less garbage to the screen with an exception for the print functions. The BEGIN component runs the functions upon running of the script.
The middle will pick up 2 arguments: The filename and function name. And @funcs is the array that will store these in an array-like setup. Each time a duplicate is found, the count on it is increased. END basically loops through the array and displays all the functions picked up and outputs them in chart format when Ctrl+C (kills program) is pressed.
To compile this script, make sure Minefield is running, then use this command on the non-Minefield terminal.
[sudo] dtrace -s js_callcount.d
Do not hit Ctrl+C until you have done some action(s). Such as going to Google.ca, hitting the back button, or whatever modifies the window. Ctrl+C when you are finished. You will get a display of what functions were called and how many times from each file it picked up.
My Test Case - Above code on a website redirection
Test Case:
- Ran Minefield on first terminal. Created a profile called DTrace and used it
- Ran my D-Script on my second terminal.
- On Minefield - typed http://www.wikipedia.org/wiki/Santino_Marella and hit Enter.
- Clicked on the first instance of RAW (should be in basic description field on top of wiki).
- Ctrl+C'd out of my D-Script on second terminal.
- Closed Minefield and Ctrl+C'd out of my first terminal.
My results were:
//DTrace::BEGIN Tracing... Hit Ctrl-C to end. //Started picking up on my Minefield interactions //DTrace::END FILE FUNC CALLS Santino_Marella writeln 2 WWE_Raw writeln 2 autocomplete.xml QueryInterface 2 autocomplete.xml attachController 2 autocomplete.xml getBoundingClientRect 2 autocomplete.xml getComplexValue 2 autocomplete.xml getIntPref 2 autocomplete.xml handleEnter 2 autocomplete.xml setConsumeRollupEvent 2 autocomplete.xml stopSearch 2 browser.js BrowserLoadURL 2 browser.js FillInHTMLTooltip 2 browser.js addToUrlbarHistory 2 browser.js canonizeUrl 2 browser.js contentAreaClick 2 browser.js getEngineByAlias 2 browser.js getPreventDefault 2 browser.js getShortcutOrURI 2 browser.js handleURLBarCommand 2 browser.js loadURI 2 browser.js removeEventListener 2 browser.js search 2 browser.xml loadURI 2 browser.xml loadURIWithFlags 2 index.php?title=-&action=raw&gen=js&useskin=monobook collapseTable 2 nsSessionStore.js ConvertFromUnicode 2 nsSessionStore.js Finish 2 nsSessionStore.js call 2 nsSessionStore.js filter 2 nsSessionStore.js finish 2 nsSessionStore.js getAttribute 2 nsSessionStore.js getElementById 2 nsSessionStore.js getEnumerator 2 nsSessionStore.js getMostRecentWindow 2 nsSessionStore.js pow 2 nsSessionStore.js sss_collectWindowData 2 nsSessionStore.js sss_forEachBrowserWindow 2 nsSessionStore.js sss_getCurrentState 2 nsSessionStore.js sss_getMostRecentBrowserWindow 2 nsSessionStore.js sss_saveState 2 nsSessionStore.js sss_saveWindowHistory 2 nsSessionStore.js sss_updateCookieHosts 2 nsSessionStore.js sss_updateCookies 2 nsSessionStore.js sss_updateTextAndScrollData 2 nsSessionStore.js sss_updateWindowFeatures 2 nsSessionStore.js sss_writeFile 2 nsSessionStore.js toSource 2 nsSessionStore.js write 2 tabbox.xml getAttribute 2 tabbox.xml getElementsByTagNameNS 2 tabbox.xml item 2 tabbrowser.xml loadURIWithFlags 2 textbox.xml setAttribute 2 textbox.xml setSelectionRange 2 urlbarBindings.xml getIntPref 2 urlbarBindings.xml getService 2 utilityOverlay.js XPCNativeWrapper function wrapper 2 utilityOverlay.js focusElement 2 utilityOverlay.js getService 2 utils.js PU_createFixedURI 2 utils.js PU_getURLAndPostDataForKeyword 2 utils.js PU_markPageAsTyped 2 utils.js QueryInterface 2 utils.js createFixupURI 2 utils.js getURIForKeyword 2 utils.js markPageAsTyped 2 wikibits.js?179 ts_makeSortable 2 autocomplete.xml closePopup 4 autocomplete.xml detachController 4 autocomplete.xml initSearchNames 4 browser.js FullZoom__applyPrefToSetting 4 browser.js FullZoom_onLocationChange 4 browser.js PSB_updateState 4 browser.js URLBarSetURI 4 browser.js UpdateBackForwardCommands 4 browser.js addEventListener 4 browser.js charsetLoadListener 4 browser.js checkForDirectoryListing 4 browser.js checkLoadURIWithPrincipal 4 browser.js createExposableURI 4 browser.js decodeURI 4 browser.js getAttribute 4 browser.js getBoolPref 4 browser.js getEngineByName 4 browser.js getPref 4 browser.js losslessDecodeURI 4 browser.js newURI 4 browser.js shouldLoad 4 browser.xml attachFormFill 4 browser.xml getTabBrowser 4 browser.xml setDocShell 4 browser.xul hasAttribute 4 button.xml getAttribute 4 button.xml removeAttribute 4 button.xml setAttribute 4 findbar.xml getAnonymousElementByAttribute 4 findbar.xml getElement 4 general.xml getAttribute 4 general.xml removeAttribute 4 index.php?title=-&action=raw&gen=js&useskin=monobook LinkFA 4 index.php?title=-&action=raw&gen=js&useskin=monobook createCollapseButtons 4 index.php?title=-&action=raw&gen=js&useskin=monobook createNavigationBarToggleButton 4 index.php?title=-&action=raw&gen=js&useskin=monobook sysopFunctions 4 index.php?title=-&action=raw&gen=js&useskin=monobook uploadwizard_newusers 4 javascript&smaxage=21600&maxage=86400 getElementsByTagName 4 javascript&smaxage=21600&maxage=86400 indexOf 4 mwsuggest.js?179 os_initHandlers 4 mwsuggest.js?179 setAttribute 4 notification.xml getElementsByTagName 4 notification.xml removeTransientNotifications 4 nsContentPrefService.js ContentPrefService__selectPref 4 nsContentPrefService.js group 4 nsContentPrefService.js reset 4 nsContentPrefService.js step 4 nsLoginManager.js XPCNativeWrapper function wrapper 4 nsLoginManager.js countLogins 4 nsLoginManager.js newURI 4 nsLoginManager.js toString 4 nsSessionStore.js annotateCrashReport 4 nsSessionStore.js getEntryAtIndex 4 nsSessionStore.js getScrollPosition 4 nsSessionStore.js max 4 nsSessionStore.js sss_collectTabData 4 nsSessionStore.js sss_saveStateDelayed 4 nsSessionStore.js sss_serializeHistoryEntry 4 nsSessionStore.js sss_updateCrashReportURL 4 nsSessionStore.js sss_updateTextAndScrollDataForFrame 4 nsSessionStore.js sss_updateTextAndScrollDataForTab 4 popup.xml openPopup 4 reporterOverlay.js getElementById 4 reporterOverlay.js setAttribute 4 storage-Legacy.js <null> 4 tabbrowser.xml QueryInterface 4 tabbrowser.xml getAnonymousElementByAttribute 4 tabbrowser.xml getNotificationBox 4 tabbrowser.xml getService 4 tabbrowser.xml indexOf 4 tabbrowser.xml isFailedFavicon 4 tabbrowser.xml isFailedIcon 4 tabbrowser.xml newURI 4 tabbrowser.xml schemeIs 4 tabbrowser.xml setAndLoadFaviconForPage 4 tabbrowser.xml setTabTitle 4 tabbrowser.xml setTabTitleLoading 4 tabbrowser.xml shouldLoadFavIcon 4 tabbrowser.xml updateTitlebar 4 textbox.xml _updateVisibleText 4 textbox.xml removeAttribute 4 utils.js PU_getMostRecentBookmarkForURI 4 utils.js PU_getMostRecentFolderForFeedURI 4 utils.js getBookmarkIdsForURI 4 utils.js getItemAnnotation 4 utils.js getItemsWithAnnotation 4 viewZoomOverlay.js getBoolPref 4 wikibits.js?179 addCheckboxClickHandlers 4 wikibits.js?179 akeytt 4 wikibits.js?179 getElementsByClassName 4 wikibits.js?179 importScriptURI 4 wikibits.js?179 match 4 wikibits.js?179 runOnloadHook 4 wikibits.js?179 setupCheckboxShiftClick 4 wikibits.js?179 showTocToggle 4 wikibits.js?179 sortables_init 4 autocomplete.xml createEvent 6 autocomplete.xml dispatchEvent 6 autocomplete.xml initEvent 6 browser.js SetPageProxyState 6 nsSessionStore.js init 6 nsSessionStore.js now 6 nsSessionStore.js sss_checkPrivacyLevel 6 urlbarBindings.xml _hideURLTooltip 6 browser.js hasAttribute 8 browser.js isSuccessCode 8 browser.js mimeTypeIsTextBased 8 browser.js notifyObservers 8 contentAreaUtils.js checkLoadURIStrWithPrincipal 8 contentAreaUtils.js getService 8 contentAreaUtils.js urlSecurityCheck 8 controller.js getControllerForCommand 8 controller.js goUpdatePlacesCommands 8 index.php?title=-&action=raw&gen=js&useskin=monobook floor 8 index.php?title=-&action=raw&gen=js&useskin=monobook insertBefore 8 nsSessionStore.js createInstance 8 nsSessionStore.js newURI 8 nsSessionStore.js schemeIs 8 nsSessionStore.js sss_getURIFromString 8 nsSessionStore.js sss_onTabLoad 8 nsSessionStore.js substr 8 nsSessionStore.js test 8 tabbrowser.xml getBoolPref 8 tabbrowser.xml setIcon 8 text.xml setAttribute 8 textbox.xml _clearEmptyText 8 wikibits.js?179 addEventListener 8 wikibits.js?179 hookEvent 8 browser.js PageProxyClearIcon 10 nsSessionStore.js forEach 10 nsSessionStore.js getIntPref 10 nsSessionStore.js sss_getWindowDimension 10 progressmeter.xml createEvent 10 progressmeter.xml dispatchEvent 10 progressmeter.xml initEvent 10 progressmeter.xml setAttribute 10 utilityOverlay.js isValidFeed 10 utilityOverlay.js replace 10 utilityOverlay.js toLowerCase 10 browser.js PageProxySetIcon 12 browser.js QueryInterface 12 browser.js indexOf 12 browser.js push 12 editMenuOverlay.js goUpdateGlobalEditMenuItems 12 index.php?title=-&action=raw&gen=js&useskin=monobook createElement 12 index.php?title=-&action=raw&gen=js&useskin=monobook createTextNode 12 index.php?title=-&action=raw&gen=js&useskin=monobook random 12 index.php?title=-&action=raw&gen=js&useskin=monobook setAttribute 12 javascript&smaxage=21600&maxage=86400 getElementById 12 nsSessionStore.js QueryInterface 12 progressmeter.xml getAttribute 12 progressmeter.xml round 12 tabbrowser.xml getBrowserAtIndex 12 tabbrowser.xml getBrowserForDocument 12 wikibits.js?179 createElement 12 wikibits.js?179 getElementById 12 nsSearchService.js epsGetAttr 14 nsSearchService.js step 14 nsSearchService.js toLowerCase 14 nsSessionStore.js getNext 14 nsSessionStore.js indexOf 14 nsSessionStore.js push 14 index.php?title=-&action=raw&gen=js&useskin=monobook appendChild 16 nsSearchService.js equals 16 tabbrowser.xml getBrowserIndexForDocument 16 tabbrowser.xml hasAttribute 16 tabbrowser.xml setAttribute 16 tabbrowser.xml updateIcon 16 textbox.xml hasAttribute 16 urlbarBindings.xml <null> 16 wikibits.js?179 createTextNode 16 wikibits.js?179 toLowerCase 16 wikibits.js?179 updateTooltipAccessKeys 16 autocomplete.xml getAnonymousElementByAttribute 18 browser.xul getElementById 18 nsSessionStore.js getService 18 nsSessionStore.js hasMoreElements 18 index.php?title=-&action=raw&gen=js&useskin=monobook getElementsByTagName 20 tabbrowser.xml removeAttribute 20 XPCOMUtils.jsm equals 22 browser.xml getInterface 24 mwsuggest.js?179 addEventListener 24 mwsuggest.js?179 getElementById 24 mwsuggest.js?179 os_hookEvent 24 nsLoginManager.js <null> 24 tabbrowser.xml getAttribute 24 wikibits.js?179 getElementsByTagName 24 browser.js getService 26 browser.js split 26 browser.js test 26 nsSearchService.js exists 28 nsSearchService.js reset 28 tabbrowser.xml getBrowserForTab 28 wikibits.js?179 appendChild 28 wikibits.js?179 indexOf 28 browser.js getBrowser 30 browser.js toLowerCase 30 nsMicrosummaryService.js MSS__getBookmarks 32 nsMicrosummaryService.js MSS__updateMicrosummaries 32 nsMicrosummaryService.js getItemsWithAnnotation 32 nsMicrosummaryService.js getPref 32 nsMicrosummaryService.js getPrefType 32 nsMicrosummaryService.js getService 32 nsMicrosummaryService.js max 32 nsMicrosummaryService.js now 32 XStringBundle GetStringFromName 36 XStringBundle getString 36 urlbarBindings.xml clearTimeout 38 urlbarBindings.xml setTimeout 38 wikibits.js?179 addOnloadHook 40 globalOverlay.js removeAttribute 42 nsSearchService.js ENSURE_WARN 42 nsSearchService.js NS_ASSERT 42 wikibits.js?179 test 50 browser.js replace 54 browser.js XPCNativeWrapper function wrapper 58 general.xml setAttribute 58 browser.js browser_onSecChange 64 wikibits.js?179 replace 64 autocomplete.xml _adjustAcItem 68 autocomplete.xml getCommentAt 68 autocomplete.xml getImageAt 68 autocomplete.xml getStyleAt 68 autocomplete.xml handleText 68 autocomplete.xml max 68 browser.js LocBar_searchBegin 68 browser.js LocBar_searchComplete 68 browser.js URLBarOnInput 68 browser.js clearTimeout 68 autocomplete.xml createElementNS 70 autocomplete.xml getPreventDefault 70 autocomplete.xml onKeyPress 70 autocomplete.xml removeAttribute 70 wikibits.js?179 setAttribute 70 browser.js getIdentityHandler 72 listbox.xml clearSelection 72 listbox.xml splice 72 richlistbox.xml _fireOnSelect 72 richlistbox.xml createEvent 72 richlistbox.xml dispatchEvent 72 richlistbox.xml initEvent 72 richlistbox.xml removeAttribute 72 richlistbox.xml updateCommands 72 autocomplete.xml _appendCurrentResult 74 autocomplete.xml _invalidate 74 autocomplete.xml getValueAt 74 autocomplete.xml unEscapeURIForUI 74 browser.js setAttribute 74 autocomplete.xml getService 78 browser.js setTimeout 80 globalOverlay.js isCommandEnabled 80 urlbarBindings.xml _initURLTooltip 88 index.php?title=-&action=raw&gen=js&useskin=monobook getElementById 90 browser.xml QueryInterface 94 controller.js updatePlacesCommand 96 globalOverlay.js getControllerForCommand 96 globalOverlay.js goUpdateCommand 96 wikibits.js?179 exec 96 reporterOverlay.js <null> 104 browser.js getElementById 116 javascript&smaxage=21600&maxage=86400 decodeURI 118 javascript&smaxage=21600&maxage=86400 <null> 122 autocomplete.xml createTextNode 134 autocomplete.xml _getBoundaryIndices 136 autocomplete.xml _getSearchTokens 136 autocomplete.xml _needsAlternateEmphasis 136 autocomplete.xml _setUpDescription 136 autocomplete.xml slice 136 autocomplete.xml sort 136 autocomplete.xml split 136 autocomplete.xml apply 138 autocomplete.xml fireEvent 138 autocomplete.xml _openAutocompletePopup 142 autocomplete.xml openPopup 142 urlbarBindings.xml openAutocompletePopup 142 browser.js removeAttribute 144 listbox.xml getAttribute 144 richlistbox.xml ensureElementIsVisible 144 autocomplete.xml adjustHeight 148 autocomplete.xml replace 148 globalOverlay.js setAttribute 150 popup.xml hidePopup 156 popup.xml QueryInterface 164 wikibits.js?179 getAttribute 170 globalOverlay.js getElementById 192 globalOverlay.js goSetCommandEnabled 192 autocomplete.xml hasAttribute 198 autocomplete.xml removeChild 198 autocomplete.xml appendChild 204 autocomplete.xml indexOf 204 browser.js <null> 206 autocomplete.xml setTimeout 210 autocomplete.xml toLowerCase 272 index.php?title=-&action=raw&gen=js&useskin=monobook test 308 index.php?title=-&action=raw&gen=js&useskin=monobook <null> 324 autocomplete.xml hasChildNodes 334 autocomplete.xml substr 338 autocomplete.xml setAttribute 344 autocomplete.xml parseInt 508 autocomplete.xml min 592 autocomplete.xml push 610 javascript&smaxage=21600&maxage=86400 substr 712 autocomplete.xml getAttribute 1506 autocomplete.xml charCodeAt 3876
The probe mainly picked up on Javascript and XML calls. But this is pretty staggering considering my test case was pretty basic, especially the number of times the XML commands were called (most likely utility functions for the Javascript). Feel free to try out your own test cases, but involving more complex things.
Why did I go wrestling themed? Well, I watch WWE Raw/Smackdown quite often, and Santino Marella is a RAW Wrestler. He is a villian using an Italian Stereotype gimmick. I find him quite entertaining to watch because of his microphone skills. Plus, I compiled this script on Thursday (where his WWE.com show - Santino's Casa is uploaded every Thursday) and finished watching it before I compiled this script.