This is the official AtomicDEX mobile beta program channel -
Android: https://play.google.com/store/apps/details?id=com.komodoplatform.atomicdex - iOS: https://testflight.apple.com/join/c2mOLEoC - Please use https://github.com/KomodoPlatform/atomicdex/issues for bug reports and feature requests. For critical security bug reports please do send us your encrypted (https://pgp.mit.edu/pks/lookup?op=get&search=0x379287998EE6CF47) report to<EMAIL_ADDRESS>and allow up to 24h for reply. For atomicDEX API (mm2) related issue reports or feature requests please do use https://github.com/KomodoPlatform/atomicDEX-API/issues
Between 08-Jan-20 12:00 AM and 09-Jan-20 12:00 AM
Vanncoins08-Jan-20 02:34 AM
Haven’t been able to match a single swap since updating atomicDEX today
Vanncoins08-Jan-20 03:52 AM
Latest update didn’t seem to fix it
Bastol08-Jan-20 04:04 AM
Since update i can't see estimated usd values anymore.
Aaand it just came back on its own for some reason
CiPhEr08-Jan-20 04:26 AM
strange thing i'm noticing with the android app is that I'll place a bunch of orders in the morning on my phone, phone runs all day with screen on at work so it can properly host orders with internet (mostly) always connected to it and now at night the orders are still on my phone, yet 90% of them are not showing up on the oracle orderbook. This is not with the latest app, but I installed about a week ago.(edited)
do orders sometimes disappear if connectivity fails for a while?
CiPhEr08-Jan-20 05:02 AM
so with new version of app I was FINALLY able to get rid of the change sounds. For anyone else wanting to do the same just:
download audacity, create a new (empty) project and then go to Generate > Silence... default length of 30s is fine. Then go to File > Export audio, and choose MP3. Put this file on your phone and link every sound to it and voila sound free experience.
MorganJekyll08-Jan-20 06:37 AM
When will CHIPS and ARRR be added to the DEX?
And once ARRR is added is it still technically a “jumbler” for other blockchains via atomic swap? Basically use it as a cloak bridge between blockchains, is this the idea?
figgy13208-Jan-20 06:43 AM
New version crashing when running in the background (android)
CiPhEr08-Jan-20 07:08 AM
@MorganJekyll i doubt arrr will be added since it is private transactions only. I believe visibility of transactions is necessary for atomicdex to work with the coin, but i'm not positive(edited)
CiPhEr08-Jan-20 07:34 AM
any suggestions on how to get orderbook queries looking better? I am using jq but at any of these brackets [ ] it makes it a line by itself so one order book entry takes up my whole vertical screen practically
TonyL08-Jan-20 07:36 AM
For human readable format it more practical to use or make GUI
CiPhEr08-Jan-20 07:39 AM
true. yeah i built an excel sheet that queries market data and compares it to the csv oracle download but i'm finding out that oracle orderbook page only has some of the markets, finally found that out after just now compiling and using mm2 for the first time. I was able to see my orders that my phone says exist but don't show up on the orderbook oracle.
CiPhEr08-Jan-20 07:51 AM
hmmm i wonder how difficult it would be to use the orderbook api on mm2 to build & keep up to date a database of trading pairs, just like the oracle orderbook but just for myself with the pairs I want to track.
CiPhEr08-Jan-20 08:14 AM
hi @smk762 sorry to bug you but do you have any info on documentation / recommendations for me to do the above? I believe you are the one currently maintaining the atomicdex orderbook oracle, no? I'd like to see about making one for myself that has the pairs i'd like to watch or, maybe you could check if it is functioning properly, it used to list all sorts of rel's for kmd but now only shows vrsc and axe.
Some of the other coins might be missing some rel's too like VRSC I think was showing FTC but not anymore(edited)
smk76208-Jan-20 08:21 AM
which language?
CiPhEr08-Jan-20 08:22 AM
like programming language? I'm just starting out in all this, so not a programmer but willing to learn!
Contribute to smk762/pytomicDEX development by creating an account on GitHub.
prob easiest to clone the repo, set your MM2.json creds and cron the orderbook script
I'm assuming you are on linux?
CiPhEr08-Jan-20 08:24 AM
yeah i do a lot with vm's on my machine and have gotten semi decent managing masternodes on my vps, writing firewall iptables code, etc
1
ubuntu mainly
smk76208-Jan-20 08:24 AM
sweet. havent tested the above on win.
should work, but sometimes some quirks
CiPhEr08-Jan-20 08:25 AM
cool yeah or i'll probably use linux
do you know if the current orderbook oracle is working correctly?
seems to be missing some pairs err some sides of pairs
smk76208-Jan-20 08:25 AM
should be, but only updates every 15 min or so
last update 13 min ago
CiPhEr08-Jan-20 08:26 AM
ok yeah for kmd only other side showing is axe and vrsc, used to be tons others this morning. Cant manage to find my orders i placed but can see them through mm2 orderbook querry
been checking a few hours
smk76208-Jan-20 08:26 AM
using vpn?
CiPhEr08-Jan-20 08:27 AM
actually yes would that affect it
smk76208-Jan-20 08:27 AM
yeah it can sometimes
CiPhEr08-Jan-20 08:27 AM
oh i'll try turning it off
showing 153 entries, same for you?
smk76208-Jan-20 08:29 AM
site agrees
I dont have a terminal to that server at the moment
Oszy08-Jan-20 08:29 AM
figgy132 Today at 06:43
New version crashing when running in the background (android)
For me too. After switching back to the app.(edited)
CiPhEr08-Jan-20 08:30 AM
yeah no worries, thanks for all your work on it though!
i built an excel sheet that uses the csv quite nicely
smk76208-Jan-20 08:30 AM
no worries, mm2 has motivated me to learn many new things
CiPhEr08-Jan-20 08:31 AM
couldn't figure out a way to have excel download the csv by itself to update so i download it manually
smk76208-Jan-20 08:31 AM
havent used excell for a while, and the csv is gen by js so prob no url for it.
CiPhEr08-Jan-20 08:32 AM
but having those pairs missing made me compile mm2 in my vm to query the orderbook manually to make sure my android app wasn't saying something not real with my orders not showing up anymore
which i'm glad i did, great to be getting into this stuff again
hmmm just checked again i think i was being a moron and not sorting something right in excel i see most everything, just not FTC
oh nice cool man i'll check it out thanks!
1
sick, yeah i might be able to tie excel into that json directly
DRE08-Jan-20 09:10 AM
when AtomicDex goes Officially to AppStore
gcharang08-Jan-20 09:14 AM
@DRE not anytime soon
the app and mm2 are still in beta and in development
@Oszy can you DM me the logs? anything in them give a reson for crash?
gcharang08-Jan-20 09:33 AM
@CiPhEr@MorganJekyll arrr will be added to the DEX. but no ETA right now
and yes, it can theoretically be used as a jumblr
3
1
CiPhEr08-Jan-20 09:34 AM
wow thats super awesome
hey any ideas for this- my app goes into order matching but doesn't proceed to next step, i've tried different amounts, does this mean that maker is already engaged with another taker?
gcharang08-Jan-20 09:36 AM
what is the pair?
CiPhEr08-Jan-20 09:36 AM
zec / kmd(edited)
i'm trying to be the taker with kmd
gcharang08-Jan-20 09:37 AM
is there only 1 order?
CiPhEr08-Jan-20 09:37 AM
it is the one for .018 price
max vol 9.78692999 zec
gcharang08-Jan-20 09:39 AM
if one order doesn't work for you, it is recommended to try matching another order
the non working order could have unupdated node or bad connectivity
ZEC recently had a network upgrade and if the maker didn't update, swap won't go through
CiPhEr08-Jan-20 09:39 AM
oh ok i see
so there would be no advantage to just let order matching sit and work right? if order doesn't get matched right away that is probably bad sign
gcharang08-Jan-20 09:41 AM
that's correct most times
CiPhEr08-Jan-20 09:41 AM
ok cool thanks
Oszy08-Jan-20 10:00 AM
sent
1
vogelfreund8808-Jan-20 10:20 AM
Hi, what is the ECA feature in the update?
gcharang08-Jan-20 10:24 AM
ECA is a coin
cipi08-Jan-20 12:08 PM
btw, there is maker on the network with ZEC that uses atomicDEX 0.2.7 Android (also as maker) and fails all swaps (last 2020-01-08 10:05:05 and 2020-01-08 11:52:18), simply because this version can't handle ZEC... so if ZEC-swaps are failing, try another maker
figgy13208-Jan-20 12:16 PM
@gcharang I will send a log and a screenshot of a crash report too
1
CoinKing8808-Jan-20 03:52 PM
Is there a step by step manual how to send DEX asset to ledger nano AND get them off again (i understand that getting them off is the tricky part?)
I got them mostly stored on the atomicdex wallet, don't want that for longterm HODL
gcharang08-Jan-20 04:00 PM
@CoinKing88 when you move DEX out of ledger, the privatekey of Komodo (as they are the same) will also be exposed to a computer.
If that is ok, here are the steps:
To store:
1) Just send to a KMD address from your Ledger
To move them:
1) Open this webpage in an offline computer: https://iancoleman.io/bip39/
2) Input your ledger seed words in the field "BIP39 Mnemonic"
3) Select KMD in the field named "Coin"
4) In "Derivation path", select the tab "BIP44"
5) you should see the addresses and privatekeys of your ledger addresses
6) copy the privatekey of the address with your DEX coin and use it to login to Verus Agama and you can move them
CoinKing8808-Jan-20 04:03 PM
Allright, thanks a lot! Last question: what if that website (iancoleman.io) goes offline?
Thanks, downloaded a copy of the code to be sure. Have a good night!
1
gcharang08-Jan-20 04:05 PM
anyway, it is just a convinient tool
there are multiple other ways to achieve the same thing(edited)
gcharang08-Jan-20 04:16 PM
Pinned a message.
scubapanda08-Jan-20 06:00 PM
Any plans on adding PIRATE in the near future?
Cryptoon08-Jan-20 06:21 PM
ye
s
needs some work to support z adresses trading though
no firm ETA
scubapanda08-Jan-20 06:37 PM
Yes, this has been the case all along? So no news.
Cryptoon08-Jan-20 06:40 PM
then why ask the question if there was a plan to add it :p
it's finished when it's finished, the days of adding countdown timers are over
scubapanda08-Jan-20 06:42 PM
Will it require a hard fork for Pirate?
Cryptoon08-Jan-20 06:42 PM
not sure in what repo they are doing the dev work, maybe if you look around a bit in the different githubs you might find the progress they are making
Bitfinger08-Jan-20 06:58 PM
Fyi in case anyone else is having issues installing the latest version, play store only worked for me after "uninstalling updates" in app settings. It was not possible to install anything before that. Probably an android issue, but figured I'd mention it
MrBizzy08-Jan-20 08:38 PM
hei people. is Dextop (atomicDEX-Pro) already a useable version?(edited)
ok, but i am trying to get my head around MM2. Do we have some more manuals/instructions besides what is in github?
1
Cryptoon08-Jan-20 09:04 PM
Best to ask @ca333
ca33308-Jan-20 09:15 PM
@MrBizzy - atomicDEX-PRO (codename "DEXtop") is the DEX desktop GUI - it is not fully usable yet but very soon.
https://developers.atomicdex.io has a lot of infos ref. the atomicDEX API-core/backend that all GUIs (mobile + Dextop) are based on.


an-box
Use
.an-box
to turn divs and other block level elements into card-like containers for other content.
.an-box
will take care of line spacing, padding and margins.
However, if you need anything extra, such as a definite width, you will
need a helper class such as
.an-25p
(for example).
.an-box
with no further content but this text.
This box also has the class
.an-25p
so that it only takes up 25% of the page container's width.
.an-box
with no further content but this text.
This box also has the class
.an-45p
so that it only takes up 45% of the page container's width.
.an-box
with
.an-center
applied. With this combination, you can center
the content of your
.an-box.
You will need another helper class to center text itself. See
TODO
This will be under text formatting in
the future.
for this.
NOTICE: When using .an-label within .an-center, the contents of
.an-center
will need to be wrapped in another element, such as a span.
an-infobox
Use
.an-infobox
to as an alternative, for highlighting important details, for instance.
an-sunkenplace
A container that appears engraved into the page.
The name should ring a bell.


Logout
Hello Admin!
4
Applicants
Locators
14
Job Postings
14
Admin
14
Request
14
Shortlist
14
Skills Inventory
14
Pending Job Posts
14
List of Hired Applicants
14
Archive
14
Reports
14
Dashboard
Applicant Short List
Short List Date
ShortList Score
ShortList Status
Applicant Name
Job Title
Send


Registration Form
User name :
Password :
Sex :
Male
Female
Hobbies :
Movies
Music
Sports
Country :
Australia
China
India
USA
UK
Languages Known :
Arabic
Chinese
English
French
Hindi


We have sent an email to activate your account.
Please activate your account.
You will now be redirected to the main page.


DiveKit
public class DiveKit
DiveKit object holds values for water type and unit of measurements.
-
Initializes a
DiveKit
object using default values ofDiveKit.WaterType.saltWater
andDiveKit.MeasurementUnit.imperial
.Since
1.0Declaration
Swift
public static let `default`: DiveKit
-
The type of water to use when performing calculations.
See moreDeclaration
Swift
public enum WaterType : String, Codable
-
The unit of measurement to use when performing calculations, also which unit of measure calculations will be returned in.
See moreDeclaration
Swift
public enum MeasurementUnit : String, Codable
-
An object to hold values for constants.
See moreDeclaration
Swift
public struct Constants
-
An object to hold string representations of units for depth, weight, volume and pressure.
See moreDeclaration
Swift
public struct Units
-
Property storing the water type to be used by an instance of a DiveKit object.
Declaration
Swift
private(set) public var waterType: DiveKit.WaterType { get }
-
Property storing the unit measure to be used by an instance of a DiveKit object.
Declaration
Swift
private(set) public var measurementUnit: DiveKit.MeasurementUnit { get }
-
Property storing constant values based on
DiveKit.WaterType
andDiveKit.MeasurementUnit
Declaration
Swift
public var constants: DiveKit.Constants { get }
-
Initializes a
DiveKit
object using provided parametersSince
1.0Declaration
Swift
public convenience init(waterType: DiveKit.WaterType, measurementUnit: DiveKit.MeasurementUnit)
Parameters
waterType
measurementUnit
-
See moreDiveKit.Error
is the error type returned by DikeKit. It encompasses a few different types of errors, each with their own associated reasons.Declaration
Swift
public enum Error : LocalizedError


Copyright Bruce Wilcox<EMAIL_ADDRESS>brilligunderstanding.com
Revision 7/18/2021 cs11.5
While the system defaults to running as a stand-alone chatbot under Windows, when run under LINUX it defaults to being a server.
Nominally (meaning depending on hardware and what your bot does) ChatScript can process a volley on a single core in 10 milliseconds on a slow machine, thus handling 100 volleys every second from different users using one core. A human-human volley is often around 15 seconds, so handling 1000 simultaneous users with a single core slow server is not unreasonable.
The fastest server OS for ChatScript is Linux. The Mac tends to misfire in the OS itself with heavy client loads. Windows is a much slower server in general. And Linux version of CS has support for forking chatscript (no such support under Windows), so you can run a fork of the engine on every core, saturating cpu processing to the max while still serving a single port. Speedup is nearly linear per core added.
When you run the Mac/LINUX program, it defaults to server mode, port
1024
. To run the server under Windows you must give it a
command line parameter specifying a port. There are various command line
parameters to affect behavior, described at the end.
ChatScript maintains an independent history with each user-bot combination in a single file in the USER’s directory. It is nominally up to you to define some unique name for each user. There is no login validation service provided by ChatScript; that is your responsibility. Some simple things which ChatScript supports directly are:
If the login name is “.” , the system will assign a user name of the IP address it receives. This doesn’t work from localhost nor will it work if you have a server of your own relaying between the client and the ChatScript server (since the IP address will always be of your relay server).
If the login name is guest, the system will assign a user name of guest concatenated with the IP address. You could also use the user’s email address as a login id. ChatScript will automatically convert periods and @ in a user’s name to _ , so a login like<EMAIL_ADDRESS>will become gowilcox_gmail_com. Likewise logging in as guest will result in something like guest_123_124_155_12. Of course, if the user eventually comes back some other day on a different IP address, they lose their history. Can’t be helped. And you end up with dead files.
The client webpage/program connects on a socket to the IP and port of the server. If you are coming from a webpage, the webpage must establish the socket. The system does not use HTTP. HTTP is an agreement on what port to use (a standard http port) and what message protocols look like to the HTTP server. Similarly ChatScript uses an agreement on what port to use (but you get to specify the port) and what the message protocols look like.
And, each communication is a one-shot deal. The socket is made, the client sends a message to the server, the server sends data back, AND CLOSES THE CONNECTION. Given that potentially thousands of users may be using the server at the same time, it is undesirable for it to try to maintain that many open sockets. If for some reason you need to maintain a permanent connection to a client, you can write an intermediary server program that has a permanent socket to the client, and relays messages back and forth between the client and the ChatScript server.
This is also what you would do if you wanted ChatScript to “push” unsolicited messages to the client. Your intermediary server can use timeouts to decide to send a specific message to the ChatScript server, and then relay the result back to the client as an unsolicited output. Similarly, your intermediate server might receive various asynchronous events and signals, and can pass requests to ChatScript at that time and pass the result back to a permanently connected client.
Each chat volley (incoming and outgoing message) is an entirely different connection. This means the Chatbot server is not devoting resources waiting for a user to reply and doesn’t care how long it takes the user to come back again.
The message a client sends is a concatenation of three null-terminated text strings. Or in place of the first two null-termination markers, you may use Ascii 1 (since JavaScript doesn’t play well with trying to join null-terminated strings) so that you send a single null-terminated string with ascii 1 as separators between components. The first component is the user login name. The second component is the name of the chatbot to talk to. If this is a null string (or just Ascii 1), the system will connect to the default bot.
The third component is the message. If the message is null, this is a start of new conversation. This MUST be the first thing you do with a new user. Ideally you do it whenever a new conversation is starting with that user which is how the system knows the old conversation ended. Usually script will detect that this is the start of a new conversation and say something like hello or welcome back to indicate the two parties are starting up a new conversation, though through the history file the system may have a lot of information about what has gone on in prior conversations. As long as the user is connected to the webpage, for example, you wouldn’t send a startup message again.
Due to the requirement of a unique user name, you NORMALLY require the user to enter a login name once on the client, after which you pass that on each transmission to the server. You can bypass asking for a user name if you always just use the “guest” or “.” user names.
The message sent to the server during a conversation should never be null (since that looks like a conversation start). Either always prepend a blank on every line from the user, or add a blank if the user presses ENTER without anything else or pass along the newline/cr character.
The chatbot can wait forever for each input (the connection is terminated for each volley) and the only way to know that the human “left” is when the human “comes back” with a start of a new conversation.
You can test everything on your own machine in Windows using batch files in SERVER BATCH FILES. Launch the server by double clicking on server.bat and then launch the client by double clicking on localclient.bat. Since this is on your own machine, firewall opening a port is unnecessary. Remember that to be a remote server you need to make your port available for inbound TCP if you have a firewall - if you don’t have a firewall you must be insane).
If you run the Windows ChatScript engine with client=ip:port as an
argument, it will act as a client to talk to and test a remote server.
The ip address must be numeric and the :port
is
optional.
The client will start a new conversation and then loop with you
conversing to it (assuming your server is running). If you issue a
:restart command to the server, the client will prompt you for a new
login. If you prefix your login name with *
, then you get
to speak first to the chatbot continuing any prior conversation
(normally the chatbot speaks first starting a new conversation).
For LINUX, just perform the equivalent commands of the batch files (except that since you can’t readily run multiple apps, you’ll have to background the server presumably by doing a nohup command on it.
When you want to change the contents of the server, obviously you could just stop and start it again. Of course that blocks people from using it in the interim and you might even cut off a user from getting his response. You don’t have to do that.
You can restart a live server without interferring with people. In actuality, the server starts up by loading all of its data into memory (except for specific users). So the dictionary, topic data, livedata, etc are all memory resident. This means you can, while the server is running, revise those files on disk. You can, for example run a stand-alone copy and rebuilt topics from raw data. Or you can edit livedata files or dictionary files. None of this impacts a running server.
Then, as an authorized user, you can issue a :restart command. Because the chatbot server handles one user one volley at a time, when you are talking to the server no one else is (briefly). So you can tell the server to reload all of its data and that will complete your turn and it will then merrily handle the next user with the new data.
Each user’s record tracks where they have been in a topic. If you have changed that topic, the record becomes invalid and any memory it has of where they have been in that topic, or if they are sitting at a rejoinder there waiting for the next user input, will be forgotten. It’s now a fresh topic. All other unchanged topics will not affect the user in any way.
The user’s topic data does not have the actual rules of the topic (it is not a copy of the topic) because that would make the files huge. Instead, the checksum of the topic is stored with the user’s topic data in USERS when they start using up rules from a topic. And each top level rule is identified by a corresponding bit in the user’s topic data, which can be compressed if a block of rules is all used or all unused. So effectively we turn on a bit whenever a rule is used up.
When you bring a new topic into the system, it has a different checksum. Therefore the system detects that the user’s file does not match the new topic data and should be considered invalid. IF the checksum of the new topic is 0 (a special value which you can request with the flag “safe” on the topic) then the system considered the topic automatically compatible. So if you just change spelllings or add rules at end or add rejoinders (which are not top level), such a topic can continue to be safely used with a user’s saved data.
In reality, the only change where you have to worry about compatibility is altering gambits, since you can always safely add responders at the end or rejoinders anywhere. And you can even add gambits using a trick. You could insert a block of n gambits to replace an existing gambit via making the block be a new topic and replacing the existing gambit with a call to that new topic. This is a “safe change” in that someone who has not reached that gambit will get the new experience. Of course some one who has already been to that gambit will not see the revision, but can continue on the rest of the topic as it used to be.
And technically I speak a mistruth in saying that you can just dump
responders at the end. IF you use a segemented responder to access the
topic ^respond(~yourtopic.secondhalf)
then you would be
impacting that. You can get around that by instead replacing a responder
with u: () ^respond(~auxresponses)
.
I develop the source on a Windows machine and transfer it to a LINUX box. To insure the source does not have carriage returns, I use :clean to read and write all src directory files without carriage returns.
To truly know if the server is alive, you actually need to send it a
message that it responds to. This means implementing
something
in your bot that reacts rapidly to your message.
The fastest messages are OOB ones, because they do not parse. So early
in your control script you can do something like:
u: ( \[ ping \]) Pong.
and use that to prove the server is fully functional.
If the server crashes, it may automatically recover, generating the message
Sorry. I forgot what I was thinking about.
If your bot personality assigns a message to the user variable $crashmsg, it will use that instead. One cannot guarantee the server doesn’t go down completely, and I recommend it be on a cron job trying to start it maybe every minute or every 5. The system will detect if its port is already busy and not start a new copy if the old one is still running.
Be advised that ChatScript assumes the current directory is the one the executable is in and accesses its data relative to that. For cron this means you want an entry like:
0,5,10,15,20,25,30,35,40,45,50,55 * * * * cd /home/bruce/ChatScript;
./ChatScript/LinuxChatscript32 2>/home/bruce/cronserver.log
CS user or server logs are never written to anything other than local filesystem. A server log could in theory be written remote to a database since it is done as a single log line, but user logs can involve tracing, which must go to local fileserver since the log is written incrementally within a line and there would be inordinate network traffic.
Still, for server logs it is a constantly increasing record count and performance would suffer significantly so logs go to the local filesystem and you have to get logs from the local machine(s). This is what they do at Amazon and they have tools to yank logs from all deployed servers.
The ChatScript server consists of a main thread to handle computing a response, a thread to accept incoming connections, and threads for each connection spawned. The connection threads handle reading the message from the user, getting the attention of the main thread to get a response, and then passing that response back to the user. Any logging is normally done from the connection threads, so the main server is free to spend all its effort handling volleys.
Under a full load of users, the main thread will nominally be always busy and the system CPU bound as a consequence. However, the main thread must also read and write user data for each volley. That may slow things down and make the system IO bound if there are lots and lots of user files around and the system is using cloud-based files instead of local ones. This will lower thruput significantly. It can be compensated for by locally caching active user data. There is a parameter to tell the server to track some number of users in memory. It will write out those memory copies periodically, but obviously if the server crashes, some users may be 50 volleys out of date.
If you run multiple servers on a machine, you may find one of them fails to start because it runs out of memory. ChatScript allocates all the memory it thinks it needs at startup, so if it succeeds, it won’t fail at runtime on a memory request but will run forever. But if multiple servers allocate too much memory at startup, then a new server trying to startup may fail. You need to configure the memory used on the command line. Go look at the advanced doc on command line parameters (non-server).
Various :xxxx
commands primarily control/affect the
server.
:show
serverlogToggles whether the server is logging data into the server logfile.
:show
echoserverIf server logging is enabled, this will print the entries sent to the log on the print console as well.
:quit
This stops a running server, causing the program to exit. It will first flush any cached user files.
:restart
This will force the system to reload all its data files from disk (dictionary, topic data, live data) and then ask for your login. It’s like starting the system from scratch, but it never stops execution. Good for revising a live server.
:crash
Force a crash to test system behavior during a crash.
:flush
If the server is caching user topic data in memory, this flushes all the cache items to disk.
ChatScript has various :xxxx commands that can be given instead of
normal chat input. These remain valid in server mode, and are a security
liability if you have potentially hostile users. Therefore all
:xxxx
commands require authorization (even in stand-alone
mode). This is the file authorizedIP.txt
existing in the
top level directory. It will be read to validate any :xxx
command. If the file is absent AND no authorize=
command
line parameter was given, authorization is granted.
The authorization file ships with a default all
, WHICH
IS DANGEROUS TO A SERVER. Normally the file will exist but have its
content erased. That will lock out commands.
 Then you can log in to the ChatScript server and issue a
:xxxx
command.
The file can have any number of lines of IP addresses to be
considered legal. You can also enter L_login
lines, which
will match a login name against the user’s login. If that matches, that
is also authorization. This works best when user names are assigned by a
member authorization system, but it good enough in short durations if
you use a weird enough login, e.g., L_b1r8u2c9e0
(bruce
interspersed with digits). Example file:
<IP_ADDRESS>
<IP_ADDRESS>
L_master
(a user named master case insensitive)
An authorization of all
allows everyone. See also
authorize=
command line parameter and nodebug
parameter.
Building a web-based interface to ChatScript is different from building an app involving ChatScript. In the web-based version, the ChatScript engine will always be a server on a reasonably powerful machine and have available the full resources of the web. In building an app-based NLP application with ChatScript, there are two general architectures, embeed-based and server-based. Embedded based is described in the External communcations manual.
The other app configuration always requires an internet connection and communicates with a ChatScript server over it. w addition, this means it can easily to voice-to-text over it and text-to-voice back. All log files are already on the server so complete access to all conversations is conveniently available and all ChatScript data files are also easy to update as desired.
Of course the requirement of having an internet connection available is a severe one on the client and may also mean his app is generating data charges he may not like.
You still have a client app which sends and receives the communications (voices and/or texts) and must still decode return text from ChatScript to retrieve app commands for avatar behavior and other functions.
If you are using voice-to-text on the server, then you would create a
server app that receives inputs from the client, communicates with the
voice-to-text server, then hands appropriate text over to the ChatScript
server.
The server app, on receiving the ChatScript output, may need to send it
over to a text-to-voice conversion, and then ship all results back to
the client. If you are not using voice in any capacity, the client app
could communicate directly with the ChatScript server.
ChatScript normally is not RESTful. It saves user state between volleys. But if you are scaling using multiple CS servers, you either need to arrange for routing specific users to specific CS servers where their files are, or have a central fileserver or database where user files are kept. And for proper full-scale service, you need a database that has multiple copies of data (like DynamoDB) that does not depend on a single machine. Or, your use of CS must be RESTful, meaning no user state is actually kept on the server side. This is partly possible. The data kept in the user topic file is:
You can direct CS not to save ANY user data by turning on user caching, but setting the cache count to 0. Now you have a system that is RESTful, but can’t keep any state. You can, however, send out state via out-of-band messages and read back in state the same way.
Currently there is a limit of 20k for an output message and user topic files vary in size including up to 40K (and you can allow them to be bigger via command line option). So it is not really practical to transmit all user state back and forth as oob data. Here is what is reasonable to accomplish:
Dont save most recent messages. You cannot detect the user repeating themselves automatically, though if you wrote out the most recent message you could manually check for immediate repeat.
Maybe write out user facts, depending on how many.
Don’t change topic flags on the fly (so don’t write them out). Don’t write out the state of all rules (so you can’t detect repeat or used up responders) but do write out the deepest gambit of a topic used. From that on start of a volley you can manually turn off all preceeding gambits.
Write out the current topic (for sure) and the interesting topic stack if you care.
Write out the rejoinder tag
Write out any user variables you care about. You may not care about the random seed or turn number, or you can write them out as well.
Currently there is no interface to context data so you can’t write that out. Generally all this will be written out by a post-process phase.
ChatScript normally reads and writes everything in plain text. If you need greater security then you need to do several things.
turn off server logs and user logs
Use encrypt= and decrypt= command line parameters.
Use default system or roll your own encryption in privatecode.
Encryption applies to user topic files and long term memory files
(^export and ^import). The built-in encryption method calls an external
api server using json to perform encryption and decryption, passing the
server urls provided by encrypt=
and decrypt=
and ltmencrypt
and userencrypt
command line
parameters. The routines will add in the user’s login id if you use %s
in the command line parameters. Eg.,
encrypt=http://someapi/someotherdata/%s decrypt=http://someapi/%s/something
Where %s goes depends on the api you call.
To roll your own, you have to define routines in private code that encrypt and decrypt (see examples in os.cpp) and on private initialization override the default variables controlling userFileSystem.encrypt and userFileSystem.decrypt.
When running a CS client talking to a cs server, there are some
debugging commands that can prove useful. It is similar to local mode in
that you have to log in with some arbitrary name. By default the bot
goes first in the conversation, but if you want the human to go first,
just put an * in front of your user name. If you want to name the bot
you want to talk to (in multibot servers), put a :botname after your
login, e.g. bruce:bot1
.
This is the same :source command that you can use on a standalone server, sending the lines of the the file from client to server.
This loads the dll compile of CS and executes the commands of the file given, to test the dll.
Tell server to restart (reload) itself.
A conversation is a series of tab-delimited lines, where the first column is user name, the second is botname, and the third is user message. When user name changes, you have a new conversation.
These commands read lines from a file (the first argument). If given, the second argument says how many lines to read before quitting. And the third argument, if given, tells how many lines to skip before really starting. The file is presumed to be at the top level of the ChatScript directory (if you dont give full path).
Typical data (except for :jmeter and :jaraw files) consists of tab or comma separated columns. First column is the user id. Second column is the category of the conversation. Third column is the specialty involved. Fourth column is the location, or some data to be passed back out unchanged. Sometimes this is converted status, or human labeled response or whatever. Fourth column is user input. Fifth column, if given, is the output expected from the bot, which is just echoed out.
45543099 Computer Email usa Welcome! What's wrong with your email?
45543099 Computer Email usa Could only receive
45543099 Computer Email usa Are emails stuck in your outbox?
45543099 Computer Email usa I have lost everything
45543100 Consumer_Electronics TV usa Welcome! What's wrong with your TV?
45543100 Consumer_Electronics TV usa White fuzzy
45543100 Consumer_Electronics TV usa What's the brand and model number of your TV? How old is it?
45543100 Consumer_Electronics TV usa 2 years old
A full conversation starts with the bot remarks and alternates bot lines with user lines. Bot lines are there for completeness and are not passed to the server.
Each line is an independent conversation of 1 line done by user. E.g.,
45543099 Computer Email usa Could only receive
45543100 Consumer_Electronics TV usa White fuzzy
Each conversation is started by sending a conversation initiation message of
[category: xxx specialty: yyy location: zzz id: iii expect: "..." ]
where the location and expect fields only exists if the corresponding column was nonblank. Thereafter the lines sent to the server are just the user inputs.
A conversation is a series of lines until a new user or category is detected. It starts with the opening message from the bot, and the lines alternate what the bot says (which are ignored and not passed to the server) and what the user says. E.g.,
A conversation is a series of lines until a new user or category is detected. It consists ONLY of what the user says.
In addition to file, if your file ends with /, that means use that as a directory and do all files within it (recursive).
A line is an entire conversation (a la JMETER std format), with what is expected from the bot and what the user says in return. An output file of TMP/jmeter.txt is generated which labels inputs with they passed (the output from bot matched expectation) or FAILED (and what oob data was shipped is shown along with what was expected and what was received).
Currently this only works for TCP, not api or integration which have different formats.
Send the message under a [category: legal] header and the file only consists of input lines from user with no other data.


Magic Squares
Games
Put the numbers in order so that they read 1-8.
The 0 is the 'empty' place. Click on any number
next to 0 and they will switch places.
# of moves:


Hi, I'm Philip, a Tyrannosaurus Rex. My friends call me P-Rex. Let's play tag, you're it, try to catch me!


{% include common.html %}
Did you know that it took months of hard work and two full weeks of vacation time to bring this awesome plugin to you completly free? Did you also know that I love coffee and beer and it makes me feel that my hard work is really appreciated when you buy me one or say thanks?
Please take a second to show your appreciation and donate to keep development going! Click the button thingy below, it won't bite!
{% include donate.html %}


February 9, 2019
This event is part of a large network of similar events that will happen around the world (in Bangalore, Los Angeles, Mexico, São Paulo, Stockholm, Tokyo, etc.), brought together by the
- 20h ~ 22h TOPO, Laboratory for Digital Writings.
EV Building address: 1515 Saint-Catherine St W, Montreal, QC H3G 2W1 // 6.720 is located just in front of the elevator in the 6th floor, some posters will be guiding your way!
TOPO address: 5445, avenue de Gaspé, local 608, H2T 3B2.
The day at Concordia University will feature various presentations by artists, researchers, designers, and teachers. And during the evening, starting at 8PM, we will have a night of performances at Agence TOPO, in the Mile End. Suggested donations (PWYC - $10) for the artists.
 Over the last 5 years the project grew into a reliable and feature-full piece of software. But it also disproportionately outgrew the concept of a Processing sketch, which lead to starting the project over with the Rust programing language.


Slices of
╱╲
╱
╲
╲
╱
╲╱
Units
Units
(
las unidades
) are the smallest elements of language.
1.0
Phonemes and graphemes
1.1
Letters
1.2
Numbers
1.3
Punctuation
1.4
Other symbols
1.5
Vowels
1.6
Consonants
1.7
Pronunciation
1.8
Orthography


/*
Copyright (c) 2014, Intel Corporation
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
"use strict";
module.exports = function(config) {
var common = require('../../lib/common');
var api = require('./api');
var ConnectionOptions = require('./iot.connection.def')(config);
var module = {};
function SendActuationCommandOption(data) {
this.pathname = common.buildPath(api.control.SEND_ACTUATION_COMMAND, data.accountId);
this.token = data.userToken;
ConnectionOptions.call(this);
this.method = 'POST';
this.body = JSON.stringify(data.body);
}
SendActuationCommandOption.prototype = new ConnectionOptions();
SendActuationCommandOption.prototype.constructor = SendActuationCommandOption;
module.SendActuationCommandOption = SendActuationCommandOption;
function SaveComplexCommandOption(data) {
this.pathname = common.buildPath(api.control.SAVE_COMMAND, [data.accountId, data.commandName]);
this.token = data.userToken;
ConnectionOptions.call(this);
this.method = 'POST';
this.body = JSON.stringify(data.body);
}
SaveComplexCommandOption.prototype = new ConnectionOptions();
SaveComplexCommandOption.prototype.constructor = SaveComplexCommandOption;
module.SaveComplexCommandOption = SaveComplexCommandOption;
function GetComplexCommandsOption(data) {
this.pathname = common.buildPath(api.control.GET_COMMANDS, data.accountId);
this.token = data.userToken;
ConnectionOptions.call(this);
this.method = 'GET';
}
GetComplexCommandsOption.prototype = new ConnectionOptions();
GetComplexCommandsOption.prototype.constructor = GetComplexCommandsOption;
module.GetComplexCommandsOption = GetComplexCommandsOption;
function DeleteComplexCommandOption(data) {
this.pathname = common.buildPath(api.control.DELETE_COMMAND, [data.accountId, data.commandName]);
this.token = data.userToken;
ConnectionOptions.call(this);
this.method = 'DELETE';
}
DeleteComplexCommandOption.prototype = new ConnectionOptions();
DeleteComplexCommandOption.prototype.constructor = DeleteComplexCommandOption;
module.DeleteComplexCommandOption = DeleteComplexCommandOption;
function UpdateComplexCommandOption(data) {
this.pathname = common.buildPath(api.control.UPDATE_COMMAND, [data.accountId, data.commandName]);
this.token = data.userToken;
ConnectionOptions.call(this);
this.method = 'PUT';
this.body = JSON.stringify(data.body);
}
UpdateComplexCommandOption.prototype = new ConnectionOptions();
UpdateComplexCommandOption.prototype.constructor = UpdateComplexCommandOption;
module.UpdateComplexCommandOption = UpdateComplexCommandOption;
function ActuationsOption(data) {
this.pathname = common.buildPath(api.control.ACTUATIONS, [data.accountId, data.deviceId]);
Iif(data.from) {
this.query = { from: data.from };
}
this.token = data.deviceToken;
ConnectionOptions.call(this);
this.method = 'GET';
}
ActuationsOption.prototype = new ConnectionOptions();
ActuationsOption.prototype.constructor = ActuationsOption;
module.ActuationsOption = ActuationsOption;
return module;
}
|


This is a getting started guide for Fedora. It is a manual configuration so you understand all the underlying packages / services / ports, etc…
This guide will only get ONE node (previously minion) working. Multiple nodes require a functional networking configuration done outside of Kubernetes. Although the additional Kubernetes configuration requirements should be obvious.
The Kubernetes package provides a few services: kube-apiserver, kube-scheduler, kube-controller-manager, kubelet, kube-proxy. These services are managed by systemd and the configuration resides in a central location: /etc/kubernetes. We will break the services up between the hosts. The first host, fed-master, will be the Kubernetes master. This host will run the kube-apiserver, kube-controller-manager, and kube-scheduler. In addition, the master will also run etcd (not needed if etcd runs on a different host but this guide assumes that etcd and Kubernetes master run on the same host). The remaining host, fed-node will be the node and run kubelet, proxy and docker.
System Information:
Hosts:
fed-master = <IP_ADDRESS>
fed-node = <IP_ADDRESS>
Prepare the hosts:
yum -y install --enablerepo=updates-testing kubernetes
yum -y install etcd iptables
echo "<IP_ADDRESS> fed-master
<IP_ADDRESS> fed-node" >> /etc/hosts
# Comma separated list of nodes in the etcd cluster
KUBE_MASTER="--master=http://fed-master:8080"
# logging to stderr means we get it in the systemd journal
KUBE_LOGTOSTDERR="--logtostderr=true"
# journal message level, 0 is debug
KUBE_LOG_LEVEL="--v=0"
# Should this cluster be allowed to run privileged docker containers
KUBE_ALLOW_PRIV="--allow-privileged=false"
systemctl disable iptables-services firewalld
systemctl stop iptables-services firewalld
Configure the Kubernetes services on the master.
# The address on the local server to listen to.
KUBE_API_ADDRESS="--address=<IP_ADDRESS>"
# Comma separated list of nodes in the etcd cluster
KUBE_ETCD_SERVERS="--etcd-servers=http://<IP_ADDRESS>:4001"
# Address range to use for services
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=<IP_ADDRESS>/16"
# Add your own!
KUBE_API_ARGS=""
ETCD_LISTEN_CLIENT_URLS="http://<IP_ADDRESS>:4001"
mkdir /var/run/kubernetes
chown kube:kube /var/run/kubernetes
chmod 750 /var/run/kubernetes
for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler; do
systemctl restart $SERVICES
systemctl enable $SERVICES
systemctl status $SERVICES
done
Addition of nodes:
Create following node.json file on Kubernetes master node:
{
"apiVersion": "v1",
"kind": "Node",
"metadata": {
"name": "fed-node",
"labels":{ "name": "fed-node-label"}
},
"spec": {
"externalID": "fed-node"
}
}
Now create a node object internally in your Kubernetes cluster by running:
$ kubectl create -f ./node.json
$ kubectl get nodes
NAME LABELS STATUS
fed-node name=fed-node-label Unknown
Please note that in the above, it only creates a representation for the node
fed-node internally. It does not provision the actual fed-node. Also, it
is assumed that fed-node (as specified in name
) can be resolved and is
reachable from Kubernetes master node. This guide will discuss how to provision
a Kubernetes node (fed-node) below.
Configure the Kubernetes services on the node.
We need to configure the kubelet on the node.
###
# Kubernetes kubelet (node) config
# The address for the info server to serve on (set to <IP_ADDRESS> or "" for all interfaces)
KUBELET_ADDRESS="--address=<IP_ADDRESS>"
# You may leave this blank to use the actual hostname
KUBELET_HOSTNAME="--hostname-override=fed-node"
# location of the api-server
KUBELET_API_SERVER="--api-servers=http://fed-master:8080"
# Add your own!
#KUBELET_ARGS=""
for SERVICES in kube-proxy kubelet docker; do
systemctl restart $SERVICES
systemctl enable $SERVICES
systemctl status $SERVICES
done
kubectl get nodes
NAME LABELS STATUS
fed-node name=fed-node-label Ready
To delete fed-node from your Kubernetes cluster, one should run the following on fed-master (Please do not do it, it is just for information):
kubectl delete -f ./node.json
You should be finished!
The cluster should be running! Launch a test pod.
You should have a functional cluster, check out 101!


.NET Rocks Interview: .NET Success Stories
Here. "This is the first of a series of shows we are going to do this year highlighting .NET Success Stories; companies that have implemented .NET applications successfully as either pilot projects or production projects. In this show we hear from two different companies."
It's stories like this that are going to finally turn the masses away from the unmanaged world to the managed world. And they'll never, ever want to go back...


Intuitive Controls
Foot-pressable buttons as well as
improved error recovery, feedforward and
feedback through context-specific light sequences.
Problem Space:
It feels like I’m babysitting a drunk toddler.
Cultural Probe Participant, Mother of Two
Ultimately, robotic vacuums need to gain trust through three guiding principles:
Keep the user in the loop by allowing them a certain degree of control
Communicate to the user what the robot vacuum is doing and why
Remind the user that the robot is here to care for them, not the other way around
Powerbut Lumos is made up of four major components, each playing its part in building trust
Bla bla
Bla bla
Bla bla
Bla bla
The 2-in-1 handle brings back control to the user.
Foot-pressable buttons as well as
improved error recovery, feedforward and
feedback through context-specific light sequences.
A charging dock that tells you if it's time to clean your house
Bla bla
Providing the user with metrics that determine the health of their home.
Simplifying and giving heirarchy to the different modes of controls.
Communicating learning.


menu
Work Experience
Education
Research
Teaching
Contact
Home
Work Experience
Education
Research
Teaching
Contact
Home
Want to get in touch?
Send me an email at: audrey[dot]bascoul[at]berkeley.edu


Rose-Hulman's eSports Club is dedicated to bringing fans of competitive gaming together to enjoy the community and all the excitement that competitions can bring.
The Rose-Hulman eSports Club has announced our next League of Legends Tournament to be on March 14-15, 2015. We have been endorsed by Riot so there will be many RP prizes as well as a triumphant ryze skin for the winning team. The second day of the event will be for the two final teams to play a best of three. Go to our events page to find out more!
Posted on: 12/3/14
The Rose-Hulman eSports Club got approved for its second year budget. The budget is much larger than the first which means we can make events that bring in more participants as well as create a better expereince at the events we host. We are planning to have a club meeting at the beginning of the academic year to figure out when these events should occur.
Posted on: 7/20/14
The Rose-Hulman eSports Club will be hosting its first club mixer on May 3rd, 2014! This event will have brackets for multiple games as well as giveaways and free pizza. There will also be an ASUS representative present to demo some great stuff! Go to our events page to find out more!
Posted on: 4/21/14
Team Sad Boys was able to win this years League of Legends tournament! Click Here to see the full bracket and here to watch some of the games that were streamed.
Posted on: 2/23/14
The Rose-Hulman eSports Club will be hosting its first event on February 22nd, 2014! This event will be a League of Legends tournament consisting of a 5v5 bracket as well as a 1v1 bracket. Go to our events page to find out more!
Posted on: 1/21/14
After some hard work from our members the Rose-Hulman eSports website is up and running! This will be the place that the club will post its events and provide detail about what our club does. Be on the watch for our first event shortly!
Posted on: 1/16/14


strtod
, strtof
, strtold
, strtod_l
, strtof_l
, strtold_l
—string to double or floatSynopsis
#include <stdlib.h> double strtod(const char *restrict str, char **restrict tail); float strtof(const char *restrict str, char **restrict tail); long double strtold(const char *restrict str, char **restrict tail); #include <stdlib.h> double strtod_l(const char *restrict str, char **restrict tail, locale_t locale); float strtof_l(const char *restrict str, char **restrict tail, locale_t locale); long double strtold_l(const char *restrict str, char **restrict tail, locale_t locale); double _strtod_r(void *reent, const char *restrict str, char **restrict tail);
Description
strtod
, strtof
, strtold
parse the character string
str, producing a substring which can be converted to a double,
float, or long double value, respectively. The substring converted
is the longest initial subsequence of str, beginning with the
first non-whitespace character, that has one of these formats:
[+|-]digits[.[digits]][(e|E)[+|-]digits] [+|-].digits[(e|E)[+|-]digits] [+|-](i|I)(n|N)(f|F)[(i|I)(n|N)(i|I)(t|T)(y|Y)] [+|-](n|N)(a|A)(n|N)[<(>[hexdigits]<)>] [+|-]0(x|X)hexdigits[.[hexdigits]][(p|P)[+|-]digits] [+|-]0(x|X).hexdigits[(p|P)[+|-]digits]
The substring contains no characters if str is empty, consists
entirely of whitespace, or if the first non-whitespace
character is something other than +
, -
, .
, or a
digit, and cannot be parsed as infinity or NaN. If the platform
does not support NaN, then NaN is treated as an empty substring.
If the substring is empty, no conversion is done, and
the value of str is stored in *tail
. Otherwise,
the substring is converted, and a pointer to the final string
(which will contain at least the terminating null character of
str) is stored in *tail
. If you want no
assignment to *tail
, pass a null pointer as tail.
This implementation returns the nearest machine number to the
input decimal string. Ties are broken by using the IEEE
round-even rule. However, strtof
is currently subject to
double rounding errors.
strtod_l
, strtof_l
, strtold_l
are like strtod
,
strtof
, strtold
but perform the conversion based on the
locale specified by the locale object locale. If locale is
LC_GLOBAL_LOCALE or not a valid locale object, the behaviour is
undefined.
The alternate function _strtod_r
is a reentrant version.
The extra argument reent is a pointer to a reentrancy structure.
Returns
These functions return the converted substring value, if any. If
no conversion could be performed, 0 is returned. If the correct
value is out of the range of representable values, plus or minus
HUGE_VAL
(HUGE_VALF
, HUGE_VALL
) is returned, and
ERANGE
is stored in errno. If the correct value would cause
underflow, 0 is returned and ERANGE
is stored in errno.
Portability
strtod
is ANSI.
strtof
, strtold
are C99.
strtod_l
, strtof_l
, strtold_l
are GNU extensions.
Supporting OS subroutines required: close
, fstat
, isatty
,
lseek
, read
, sbrk
, write
.


PerfMonitor is a tool for quickly and easily collecting ETW performance data and generating useful reports. It is based on the Event Tracing for Windows (ETW) feature of the operating system which can collect information machine wide a a variety of useful events (see advanced data collection on what data is alread built into the OS and CLR). It is the powerful technology the the windows performance group uses almost exclusively to track and understand the performance of windows, and the basis for their XPerf tool. The data collected by PerfMonitor is the same data that XPerf uses, so PerfMonitor can be used to simplify data collection and simple reporting and XPerf can be used for more advanced analysis on the same data. PerfMonitor also has the ability to decode symbolic information associated with .NET Runtime code, making PerfMonitor more valuable for .NET investigations. The source code for PerfMonitor as well as the TraceEvent data parsing library on which is based are availalble at bcl.codeplex.com, so user-defined data analysis is also relatively easy.
See also FAQ, TroubleShooting, ETW Background, Understanding the Analysis Report.
PerfMonitor was designed to be easy to deploy and use. To deploy PerfMonitor simply copy the PerfMonitor.exe to the computer you wish to use it on. No additional files or installation step is needed. You can get the latest copy of PerfMonitor.exe from the PerfMonitor download page. Simply click in the PerfMonitor.bin.zip file to download it, click through the dialog boxes, and then copy the exe to your hard drive. You are then ready to go!
Open an Administrator command window (Start->All Programs ->Accessories -> Command Prompt -> Right Click -> Run as Administrator), change your directory to where you placed the perfMonitor.exe and then type the command
This command tells perfMonitor to
You can then browse the resulting report.
The
source code for CpuTest is useful when analyzing this
data. See
Understanding the Analysis Report
for more on the report.
The 'runAnalyze' command used in the quick start was designed to make doing a common set of operations easy. However it is just one possible 'path' from data collection to analysis. PerfMonitor allows these steps to be done individually, which allows for more advanced scenarios. The first step in most profiling scenario is simply to turn on and off data collection. These are what the 'start' and 'stop' operations doo
The start command turns on (machine wide) logging, and the stop command turns logging off. Only one session can be on simultaneously. If you try to start a session when one is already started, it closes the existing session and opens an new one. The effect of turning on a session is immediate and take effect on live processes as well as new processes that are created. A filename can be specifed (suggested extention is .ETL), but it will default to 'perfMonitorOutput.etl if not provided. ETW allows a huge array of events to be turned on, which can be a daunting task, so perfMonitor simplifies this by choosing a good set of default events, that are useful in a broad variety of performance invesigations but are not too expensive to collect. This includes OS kernel operations associated with processes, threads, DLLs, page faults, diskIO, and CPU sampling as well as CLR events associted with Garbage Collections, the CLR Thread pool, lock contention, exceptions, and compilation of managed code to native code. While PerfMonitor chooses a good set of default events to collect, though various options it gives you full control over what events are collected see Advanced Data Collection for more.
Once logging has been started, it will continue until it is explicitly stopped. Thus scripts that uses 'start' should be very robust to error handling to insure that the 'stop' command is exectuted under all cases (inlcuding a user hitting Ctrl-C). For this reason you should try to use the 'run' or 'collect' commands instead of 'start' and 'stop' whenever possible.
Due to a limitation in ETW implementation, kernel event can not be collected into the same ETL file as all other events. PerfMonitor works around this by making two separate files (eg *.etl and *.kernel.etl). Thus typically perfMonitor generates two files. Whenver PerfMonitor is manipuating and ETL file called X.etl, looks fvor any 'shadow' file like X.*.etl and combines the files into one when doing its processing . Thus in many scenarios you can ignore the fact that PerfMonitor generates mulitple files. You can also merge these files into a single file (see perfMonitor merge command below).
The combination of starting ETW logging, running a command, and then stopping, is so common the 'run' command was created to do precisely this. Thus the command
Is equivalent to
Note that data collection is still machine wide, so you will get information about the entire machine at the time that Foo.exe was also running. One important value to the 'run' command is that it tries pretty hard to insure tha the 'stop' command is issued under any error condition or if the user interrupts the command (Ctrl-C).
When you wish to profile a process which is already running or can't be started 'by hand', you can't use the 'run' command. While you could use the 'start' and 'stop', we wish to discource that (too easy to leave ETW on), Instead there is a 'collect' command which turns on logging, and waits for the user to type a 'S' to stop collection. Thus
Will start logging and wait for the user to type 'S' and the enter key. You can abort the collection with Ctrl-C.
When data is collected with 'collect' (or when perfMonitor 'stop' is used), by default PerfMonitor does a 'ClrRundown'. A 'ClrRundown' makes a request to every process running the .NET Runtime to dump symbolic information so that stack traces involving managed code can be decoded. This is only needed if the process of interested is managed AND it has not exited. This is why it is not necessary to do a rundown when you use the 'run' command (since the process already did a rundown when it died).
Rundown does take time and file space, so if you know that the process of interest is either not a .NET program or will have died before collection has ended you can specify the /noRundown flag to 'collect' to avoid this overhead.
As already mentioned, due to limitations in ETW, data from PerfMonitor typically consists of two files: an .ETL file and a .Kernel.ETL file. In addition, these files do not contain all the information necessary to decode the events on another machine (information missing are the EXACT version of exectuable files, as well as the mappings of hard drives to drive letters). Thus the raw information is not well suited to being transered to another maching for analysis. The perfmonitor 'merge' command is designed to fix this. By typing By typing
PerfMonitor will combine filename.ETL (defaults to perfmonitor.etl) and fileName.kernel.ETL into just fileName.ETL (deleting the originals if successful) Moreover it will include all information needed to decode the ETL file on another machine. Thus after merging the single file can now be transfered to another machine for off-line analysis. It also works equally well on the machine where the data was collected (it just takes an extra step to create).
The ETL files created by PerfMonitor are identical to files that would be created by the windows XPerf tool. Thus a useful scenario is to use PerfMonitor to collect information on a remote machine (because it is one EXE that is easy to deploy anywhere), and then use XPerf to analyze the resulting data on another machine.
Typically ETW will generate 2-4 Meg of data for every second of collection (although this can vary widely depending on the events being logged, and what applications are doing during the log). It is also true that log files larger than 500 Meg or so are quite unwieldly. Thus it is best if data is collected for less than 100 seconds. This can be a problem if you are trying to understand a performance problem that is intermittant. This is where the /Circular:sizeMB option is useful. By specifying /Circular:100 it caps the file size at 100 meg (probably enough for 25-50 seconds of trace), so logging can be left on indefinately. When the problem occurs, as long as you can stop the logging within about 25 seconds, you should have data on the performance anomoly.
Once you have ETL files created by PerfMonitor, you can run a variety of analyses on them by using the 'analyze' command
Will perform a set of useful performance evaluations on the data in filename.ETL (defauts to perfMonitor.etl) for the process designated by nameOrPID. NameOrPID is either the process name (defined to be the name of the EXE without path or extension), or the (decimal) process ID. The 'analyze' will work if you don't specify a process to focus on, but typically is not what you want. You can discover what processes were started in a given ETL file by doing
Which gives a list of process that started while data was being collected. This can then be used to determine the correct /process: qualifer to use.
As a convenience, the command the command
Will perform the run command (start data collection, run the command, stop), and then do an 'analyze' command, using the process name from the command as the focus process. This was the command used in the QuickStart, and is quite common. bsp;
The report that is generated by the 'analyze' command is meant to be self-explainitory, however a certain amount of performance background is valuable in interpreting the data. This is what is presented here. This section assumes some familiarity with ETW, Please see ETW Background if you are new to ETW.
The main report has three sections
See also Understanding CPU Performance Data, Understanding GC Performance Data, Understanding Just In Time Compiler Data, FAQ, TroubleShooting, ETW Background, Home.
The data shown by default in the PerfMonitor stack viewer are stack traces taken every millisecond on each processor on the system. Every millisecond, on every CPU whatever process is running on that CPU is stopped and the operating system 'walks the stack' associated with the running code collecting the return address of every method on the stack. Stackwalking may not be perfect. It is possible that the OS can't find the next frame (leading to broken stacks stacks) or that an optimizing compiler has removed a method call (see missing frames), which can make analysis more difficult. However for the most part the scheme works well, and has low overhead (typically less than 5% slowdown), so monitoring can be done on 'production' systems.
Because the samples are taken every millisecond per processor, each sample represents 1 millisecond of CPU time. However exactly where the sample is taken is effectively 'random', and so it is really 'unfair' to 'charge' the full millisecond to the routine that happened to be running at the time the sample was taken. While this is true, it is also true that as more samples are taken this 'unfairness' decreases as the square root of the number of samples. If a method has just 1 or 2 samples is could be just random chance that it happened in that particular method, but methods with 10 samples are likely to have truly used between 7 and 13 samples (30% error). Routines with 100 samples are likely to be within 90 and 110 (10% error). For 'typical' analysis this means you want at least 1000 and preferablly more like 5000 samples (there is diminishing routines after 10K). By collecting a few thousand samples you insure that even moderatly 'warm' methods will have at least 10 samples, and 'hot' methods will have at least 100s, which keep the error acceptably small. Because PerfMonitor does not allow you to vary the sampling frequency, this means that you need to run the scenario for at least several seconds (for CPU bound tasks), and 10-20 seconds for less CPU bound activities.
Even with 1000s of samples, there is still 'noise' that is typically at least 3%. This error gets larger as the methods being investigated have fewer samples. This makes it problematic to use sample based profiling to compare two traces to track down small regressions (say 3%). Noise is likely to be at least as large as the 'signal' (diff) you are trying to track down. Increasing the number of samples will help, however you should always keep in mind the sampling error when comparing small differences between two traces.
Before doing a detailed CPU analysis, it is important to insure that optimizing CPU will have an effect. If your program is Disk or Network bound, then optimizing CPU will have little effect. This is why the top level 'rollups' of CPU consumption are an important to look at first. If the total CPU samples add up to 400 msec, than that is an upper bound on what CPU optimization can have. You should spend your time only of costs that are large enough to justify optimization.
Because a stack trace is collected for each sample, every node has both an exclusive metric (the number of samples that were collected in that particular method) and an inclusive metric (the number of samples that collected in that method or any method that that method called). Exclusive times are useful in the bottom up view to quickly determine the 'hot' methods that are the most important to optimize. Inclusive times are useful in the top-down and caller-calle views to understand how time is spent in methods that are not in the bottom-up view.
All programs call into operating system functions to do 'primitive' operations (e.g. read from a file, update the screen ...). However these functions are typically have a large number of private internal methods to implement the functionality. This detail is typically not useful to an application developer trying to optimize HIS code, and only serves to make the report hard to read. PerfMonitor avoids this problem by grouping all functions that are part of the operating system. A method is defined to be part of the operating system if it is implemented in a DLL that is under the c:\windows directory. Once a call is made into an OS function, any further calls are grouped into the existing frame until a method outside the OS is called. This feature can be turned off with the /noOSGrouping qualifer if desired.
This grouping greatly simplifies the CPU reports PerfMonitor generates. It does however mean that the meaning of 'Exclusive' time for OS functions is different from user functions. For OS functions, exclusive time means the sample might have been in the function itself but it might also mean that it occurs in any OS function that function called.
By default PerfMonitor collects all the information needed to map the information collected at runtime (return addresses) into names of methods. However unmanaged code relies on information stored in program database file (PDBs) to provide this mapping. By default PerfMonitor does not try to map return addresses of unmanaged code to symbolic names. Typically PerfMonitor can determine the module of the return address, but needs the PDB to resolve the function name, resulting in a name like module!?. If even the module cannot be determined the address is displayed as ?!?)
PerfMonitor can be made to look up return addresses in unmanaged code using the /SymbolsForDlls:dllList, where dllList is a comma separated list of DLL names (without path or extension). For this to work the _NT_SYMBOL_PATH variable must be set so that the necessary PDB files can be found. See Symbol Resolution for complete details. You may also use the /NoOSGrouping qualifier if you are interested in the detailed stacks associated with DLLs under c:\windows.
Performance investigations can either be 'top-down' (starting with the Main program and how the time spent there is divided into methods it calls), or 'bottom-up' (starting with methods at 'leaf' methods where samples were actually taken, and look for methods that used a lot of time). Both techniques are useful, however 'bottom-up' is usually a better way to start because methods at the bottom tend to be simpler and thus easier to understand and have intuition about how much CPU they should be using. Top-down analysis will tell you how the 'large' components of your program use CPU. This can be useful to find large structural problems (a phase of your program is taking much longer than expected).
By default PerfMonitor causes the Runtime to log an event at the begining and end of each .NET Garbage Collection as well as every time 100K of objects are allocated. As with all events the precise time is logged, so the amount of time spent in the GC can be known. Most applications spend less than 10% of the total CPU time in the GC itself. If your appliation is over this %, it usually means that your allocation pattern is such that you are causing many expensive Gen 2 GCs to occur.
If the GC heap is a large percentage of the total memory used then GC heap optimization using a profile like ClrProfiler. See Memory Usage Auditing For .NET Applications for more on memory optimization. .
During SOME GCs the application itself has to be suspended so the GC can update object references. Thus the application will pause when a GC happens. If these pause times are larger than 100ms or so, it can impact the user experience. The GC statistics will track the maximum and average pause time to allow you to confirm that this bad GC behavior is not happening.
PerfMonitior tracks detailed information of what methods were Just In Time compiled. This data is mostly useful for optimizing startup (because that is when most methods get JIT compiled). If large numbers of methods are being compiled it can noticably affect startup time. This report tells you exactly how much time is being spent (in fact exactly which methods and exactly when they were compiled). If JIT time is high, the NGen Tool can be used to precompile the code, and thus eliminate most of this overhead at startup.
Event Tracing for Windows (ETW) is a general purpose, efficient, scalable event logging service built into the windows operating system. Effectively all Windows components as well as user defined componts can define logging 'Providers' that can be turned on and off selectively at any time to provide interesting information about what that component is doing. Each event is automatically tagged with the provider it came from and the exact (too 100ns) time it happened, what process and thread generated it, as well as event specific information. Events can also be optionally tagged with the exact stack trace. Much of the power of ETW comes from the fact that the operating system provider come built in with a variety of useful events including process and thread creation, 1 msec CPU sampling (with stack trace), context switches, disk I/O (including file name), DLL loading, virutal memory allocation, and network I/O. On top of these other windows components such as the .NET Runtime add their own providers that add component-specific information such as garbage collection events and Just in Time compilation (see advanced data collection for more). The result is very detailed view of the system as a whole, which is sufficient to diagnose most performance issues.
The data collection is machine wide (you automatically get events from every process in the system), which, among other things, means that data collection logistics are simpler (you don't need to know which process is important). The overhead associated with collection varies depending on the kind of events logged and what the appliation does. The default events turned on by PerfMonitor will slow the application down by less than 10% (more typically less than 5%). In addition, the Windows development group uses ETW logging extensively, so these logging paths are well tested (you are not running in a unusual mode). These characteristics make it reasonable to leave event collection on 'in production' to 'catch' unusal performance events. The '/Circular' option is particularly valuable
The size of the data files again depend on the events that were turned on and what the applications is doing. For the default events perfMonitor will typically generate between 2 and 4Meg of log per second. Thus data collection times less than 100 seconds are reasonable. If your scenario is larger then that, you should consider using a circular buffer to limit the amount of data collected.
PerfMonitor data collection is based on Event Tracing for Windows (ETW). This is a general facility for logging information in a low overhead way. It is useful extensively throughout the Windows OS and in particular is used by both the Windows OS Kernel and the .NET CLR Runtime. By default PerfMonitor picks a default set of these events that have high value for the kinds of analysis PerfMonitor can visualize. Howevever PerfMonitor can also be used as simply a data-collector, at which point it can be useful to turn on other events. This is what the /KerneEvents: /ClrEvents: and /Provider: qualifiers do
All ETW events log the following information
By far, the ETW events built into the Windows Kernel are the most fundamental and useful. Almost any data collection will want to turn at least some of these on. See Kernel ETW Event for more information on particular events. Here we will only provide an overview. It is useful to break kernel events into three groups:
The default group is the group that PerfMonitor turns on by default. The most verbose of these events is the 'Profile' event that is trigger a stack trace every millisecond for each CPU on the machine (so you know what youre CPU is doing). Thus on a 4 processor machine you will get 4000 samples (with stack traces) every second of trace time. This can add up. Assume you will get at least 1 Meg of file size per second of trace. If you need to run very long traces (100s of seconds), you should strongly consider using the circular buffer mode to keep the logs under control.
The following Kernel events are not on by default because they can be relatively verbose or are for more specialized performance investigations.
The finalThe final set of kernel events are typically useful for people writing device drivers or trying to understand why hardware or low level OS software is misbehaving
In addition to the kernel events, if you are running .NET Runtime code you are likely to want to also have the CLR ETW events truned on. PerfMonitor turns a number of these on by default. See CLR ETW Events for more information on these events.
The Kernel and CLR ETW events are by far the most important because the data they collect applies to most programs. This is why PerfMonitor turns these providers on by default, and has special qualifers (/kernelEvents and /CLREvents) to make speicify specific events easy. However sometime it is useful to also have events that tell you 'higher level' information. There are litterally hundreds of ETW providers built into Windows already, and it is also possible for you to instrument your own code with ETW event. PerfMonitor can control these other provider too. This is what the /providers: qualifer is for.
To turn a ETW provider on, you need three pieces of information
The /providers qualifer is a comma separated list of these specifications where each component above is separted by a ':' For example the silverlight provider happens to be assigned the GUID AA087E0E-0B35-4e28-8F3A-440C3F51EEF1. Thus the specification
Starts data collection with all the normal CLR and Kernel providers but also turns on the silverlight provider passing it the bitset 0xFFFFFFF and a verbose level (5). This is relatively advanced scenario as you need to know what each bit in the bitset means, and how to decode the events once they are collected.
You can find the list of providers available in the system by issuing the following 'logman' windows command
However this list is very large and overwelming. It is typically more intersting to find out the set of providers that are available for your particular application. You can do this with the command
Where PID_OF_PROCESS is the process id for your applciation. This restricts the providers to just those that are currently active for that process. This is a far smaller list, and much more likely to be relevant to you. Once you have an interesting provider you can learmn about what keywords and levels it has by issueing
This will give details on what keywords and levels can be given. You now hav the GUID, Keyword, and level information that you can then pass to the /providers: qualifer of PerfMonitor.
In version 4.5 of the .NET Runtime, the System.Diagnostics.Tracing.EventSource class was added to the runtime that makes it very easy to create your own ETW provider and generate your own events. PerfMonitor has support for during these providers on and off very easily. The first piece of this support is the ability to discover what EventSources a given application (or DLL). For example
Will list all eventSources in 'MyApp.exe' (or any DLL that is statically reachable from Mypp.exe') and list them. For example the output might be
Event sources in eventProvider.exe. EventSource Name EventSource Guid ------------------------------------------------------------------------- MinimalEventSource : 7370a335-9b9a-5ba0-63c2-8ce045c35503 MyCompany-MyApp : 74cf8ddb-febf-5c1c-67c4-c721006bace0 AnotherEventSource : a217696f-5896-584d-31d5-8c90e8d3483e
The /dumpManifests qualifer can be used to specify a directory to dump all the eventSource manifests found. For example
Will dump three .manifest.xml files into '.' (the current directory), one for each of the event sources. This gives detailed information about the keywords available in the eventSource as well as all the events and their payload schmeas.
Once you have determined which EventSource you are interested in, perfMonitor supports the syntax @filename#EventSourceName to specify eventSources in the /provider: qualifer. For example you can turn on the 'MinimalEventSource' by specifying
Which runs 'MyApp.exe' with the MinimalEventSource turned on. If you don't specify the # syntax, PerfMonitor assumes you want all EventsSources turned on. Thus
Turns on all three EvenSources in MyApp.exe. and runs the application and . When using the 'run' command, you can event exclude the Filename (it is assumed to be the exe that is run). Thus
Is equivalent to the previous example. The command above will turn on the Kernel and CLR events asl well as the EventSources. You would need to specify the /clrEvents:None and /kernelEvents:Process,Image qualifiers to suppress all but the least verbose events. This is common enough that PerfMonitor has a special command called 'monitorRun' that does just this. Thus
Is really shorthand for
Once you have created the ETL file, you can print out the formatted text from EventSources using the printSources command
Will pretty print the events in the PerfMonitorOutput.etl file to standard output. Use the /outputFile=FILE qualifer to send the output elsewhere. Monitoring and then printing the EventSources output as text is common enough that there is a shortcut 'monitorPrint' command
Will monitor the app (turn on all its eventSources), and then print the resulting output. If XML output is desired instead you can use the 'monitorDump' shortcut.
Finally perfMonitor also supports realtime 'listening' to event sources. For example
Will listen to all the eventSources in 'MyApp' and print them out in 'real time'. Control - C ends the session.
At collection time, when a CPU sample or a stack trace is taken, it is represented by an address in memory. This memory address needs to be converted to symbolic form to be useful for analysis. This happens in two steps.
If the first step fails (uncommon), then the address is given the symbolic name ?!? (unknown module and method). However if the second step fails (more common) then you can at least know the module and the address is given the symbolic name module!?.
Code that does not belong to any DLL must have been dynamically generated. If this code was generated by the .NET Runtime by compiling a .NET Method, it should have been decoded by PerfMonitor. Howvever if you specified the /NoRundown or the log file is otherwise incomplete, it is possible that the information necessary to decode the address has been lost. More commonly, however there are a number of 'anonymous' helper methods that are generated by the runtime, and since these have no name, there is not much to do except leave them as ?!?. These helper typically are uninteresting (they don't have much exclusive time), and can ignored during analysis. They typically happen at the boundary of managed and unmanaged code.
Code that was not generated at runtime is always part of the body of a DLL, and thus the DLL name can always be determined. Precompiled managed code lives in (NGEN) images which have in .ni in their name and the information should be in the ETL file PerfMonitor collected. If you see things unknown function names in modules that have .ni in them it implies that something went wrong with CLR rundown (see ?!? methods). For unmanaged code (that do not have .ni) the addresses need to be looked up in the symbolic information associated with that DLL. This symbolic information is stored in program database files (PDBs), and can be fairly expensive (10s of seconds or more), to resolve a large trace. Because of this PerfMonitor by default only fully decodes 'High Value' DLLs including
This is a good set of defaults for most managed code development. However if your performance problem deals with unmanagd code., You will want other DLLs decoded. Currently the only way to do this is by specifying the /SymbolsForDlls:dll1,dll2 ... when the data is analyzed. Where the dlls do NOT have their file name extension or path. (TODO: Improve the experence). The first time you use the /SymbolsForDlls qualifier you will also want to use /PrimeSymbols as explained below.
When a trace is opened for analysis, it does the symbolic lookup for unmanaged dlls. Click the 'log' button in the lower right corner to see detailed diagnostic information about symbol loockup. An important part of this lookup is finding he program database (PDB) files. Like most diagnostic tools, PerfMonitor uses the _NT_SYMBOL_PATH environment variable for a semi-colon separated list of places to look for PDB files. If you have unmanged executables that you built, this environment variable should include paths to the PDBs that your compiler generated.
The _NT_SYMBOL_PATH variable can have a special syntax of SRV*cacheDir*symbolServer, where cacheDir is a directory on the local machine, and symbolsServer is a network or web path. This directs PerfMonitor to look up the PDB on the remote symbol server and copy the PDB to cacheDir, and then decode the symbols. If the PDB is archived in a symbol server, looking up the PDB is now easy (you point at a symbol server) but it can also be VERY slow (10s of seconds or more because of network latancies). The most important use of symbol servers is to get the PDBs for the Windows operating system DLLs.
Because symbol servers can be so slow and often you don't need the extra symbol information anyway (e.g if you are doing a pure managed investigation), by default PerfMonitor does NOT look up symbols on NON-LOCAL locations (it will look in al machine-local locations, including symbol server cache locations). However this does NOT work well the FIRST time. The FIRST time you must use the /PrimeSymbols option when launching PerfMonitor (TODO improve experience). This will tell PerfMonitor to take the time to look up the PDBs on symbol servers (and prime the local symbol server cache). After doing this once, you should not have to do it again (until OS dlls get updated).
By far, the most common unmanaged DLLs of interest are the DLLs that Microsoft ships as part of the operating system. Thus if you don't specify a _NT_SYMBOL_PATH PerfMonitor uses the following 'standard' one
This says is to look up PDB at the stanard microsoft PDB server http://msdl.microsoft.com/download/symbols and cache them locally in %TEMP%\symbols. Thus by default you can always find the PDBs for stanard Microsoft DLLs.
Thus typically all you need to get good symbols is
Run PerfMonitor /PrimeSymbols once when doing your first analysis. By default this will fetch the important OS and CLR dlls from the default Microsoft symbol server.
Afterward just run PerfMonitor normally. You will get the cached symbols and it will be (reasonably) fast (Because it finds them locally on your computer)
If you are investigating performance problems of unmanaged DLLs of EXEs that did not come from Microsoft (e.g you built them yourself), you have to set the _NT_SYMBOL_PATH to include the location of these PDBs before launching PerfMonitor.
Here are some tips for troubleshooting comon issues.
Because of the expense of looking up symbols for unmanaged DLL, PerfMonitor requires a small amount of work by the user to decode them. First PerfMonitor by default only decodes a handful of important operating system dlls by default. You must use the /SymbolsForDlls:dll1,dll2 to specify more. Second, even for these important DLLs PerfMonitor NEVER tries to find symbols except on the local machine unless the /PrimeSymbols options is given. Thus this option must be given the FIRST time you use PerfMonitor and wish to have symbols. Finally if the DLL is not shipped from Microsoft, symbol search path is almost certain NOT to work, you need to tell PerfMonitor where to find symbols by specifying the _NT_SYMBOL_PATH variable.
Thus if this is the first time you have used PerfMonitor and the symbols are important to your analysis, and the DLL were created by microsoft, then you can
If that does not work, look carefully at the *.convertlog.txt that is generated and read see Symbol Resolution for more complete information.
When a sample is taken, the ETW system attempts to take a stack trace. For a variety of reasons it is possible that this will fail before a complete stack is taken. PerfMonitor uses the heuristic that all stacks should end in a frame in a particular OS DLL (ntdll) which is responsible for creating threads. If a stack does not end there, PerfMonitor assumes that it is broken, and injects a pseduo-node called 'BROKEN' between the thread and the part of the stack that was fetched (at the very least it will have the address of where the sample was taken). Thus BROKEN stacks should always be direct children of some frame representing a OS thread.
When the number of BROKEN stacks are small (say < 3% of total samples), they can simply be ignored. This is the common case. However the more broken stacks there are, the less useful a 'top-down' analysis (using the CallTree View) is because effectively some non-trivial fraction of the samples are not being placed in their proper place, giving you skewed results near the top of the stack. A 'bottom-up' analysis (where you look first as where methods where samples occured) is not affected by broken stacks (however as that analysis moves 'up the stack', it can be affected)
Broken stacks occur for the following reasons
If you are profing a 64 bit process there is pretty good chance that you are being affected by scenario (2) above. There are three work-arounds to broken stacks in that instance
C:\Windows\Microsoft.NET\Framework\v2.0.50727\NGen install YourApp.exe.
You will have to repreat this every time your application is recompiled.Missing stack frames are different than a broken stack because it is frames in the 'middle' of the stack that are missing. Typically only one or maybe two methods are missing. There are three basic reasons for missing stacks.
While missing frames can be confusing and thus slow down analysis, they rarely truely block it. Missing frames are the price paid for profiling unmodified code in a very low overhead way.
PerfMonitor emits a ? for any program address that it can not resolve to a symbolic name. See troubleshooting Symbols and Symbol Resolution for more.
If the stack trace that is taken at data sample time does not terminate in OS DLL that starts threads, the stack is considered broken. See Broken Stacks for more.
The algorithm used to crawl the stack is not perfect. In some cases there is not sufficient information on the stack to quickly find the caller. Also compilers perform inlining, tailcall and other optionations that literally remove the frame completely at runtime. The good news is that while sometimes confusing, it is usually pretty easy to fill in the gaps. See Missing Frames for more.
/// This class is simply a example of a CPU bound computation. It does it recurisively to /// make the example more interesting. The main entry point is the RecSpin routine. class Spinner { public static int aStatic = 0; // Spin for 'timeSec' seconds. We do only 1 second in this // method, doing the rest in the helper. public static void RecSpin(int timeSec) { if (timeSec <= 0) return; --timeSec; SpinForASecond(); RecSpinHelper(timeSec); } // RecSpinHelper is a clone of RecSpin. It is repeated // to simulate mutual recursion (more interesting example) static void RecSpinHelper(int timeSec) { if (timeSec <= 0) return; --timeSec; SpinForASecond(); RecSpin(timeSec); } // SpingForASecond repeatedly calls DateTime.Now until for // 1 second. It also does some work of its own in this // methods so we get some exclusive time to look at. static void SpinForASecond() { DateTime start = DateTime.Now; for (; ; ) { if ((DateTime.Now - start).TotalSeconds > 1) break; // Do some work in this routine as well. for (int i = 0; i < 10; i++) aStatic += i; } } }


What Fresh Hell is This! An application that helps you keep track of your hellish experiences. Here you can record every hellish experience you have had. The application will show you your most recent misfortunes as well as keep some simple stats about how often you have these experiences.
This cartharsis brought to you by @net_zer0


Download
Card
Notifications
Profile
Clients
Search
Add new customer
CLIENT ID
CLOSING AGENT
COMPANY
ORDER
INVOICE PAID


You must request access to this administrative site by email.
<EMAIL_ADDRESS>Authentication is a one time process, after which your IDIR will be enabled for future logins.
You have been logged out.


Downs' Incoming Brazilian - Which Foreigner Will Be Offloaded?
by Soccer LadumaWith Sundowns’ Brazilian defender, Ricardo Nascimento on the comeback trail after groin surgery and possibly set for involvement in the second half of the season, Pitso Mosimane will have a big decision to make on which of his foreign players to cut loose.
As Nascimento steps up his rehabilitation after injury, the coach will need to offload one of his five currently registered foreigners in Mauricio Affonso, Gaston Sirino, Jose Ali Meza, Bangaly Soumahoro and Emiliano Tade.
As reported in Issue 1147, Tade is facing a fight to save his Sundowns career having struggled to maintain his early impact at the club and not having featured at all this season after a knee injury.
Below are the five foreigners under threat and the case for and against Sundowns offloading them to make space for Nascimento.
Gaston Sirino:
The Uruguayan has had a superb start to this season with nine goals and three assists in his 15 appearances so far. Sundowns failed to win either of their last two matches with Sirino missing due to a quad injury. He is a key player for the side and would not be offloaded unless a lengthy ban came his way having recently been charged by the PSL Disciplinary Committee for an ‘assault’ on SuperSport United’s Clayton Daniels and Dean Furman.
Mauricio Affonso:
After the 0-0 draw against Baroka, Mosimane told SuperSport TV that Affonso is now one of the side’s most important players. Having scored with his first three shots across their three different competitions, he looks to have a crucial role to play. The coach stated that he was brought in for his height in the CAF Champions League and is unlikely to consider letting him go.
Jose Ali Meza:
Having scored just two goals last season – both against weaker opponents in the CAF Champions League preliminary rounds – he looked set to depart on loan to Maritzburg United in the last transfer window. Since then, he has come back into favour and has started six of the last eight matches. He scored against AmaZulu and assisted against Black Leopards, but has been taken off early in recent games. He still needs to prove himself in a Sundowns shirt.
Bangaly Soumahoro:
With just 17 minutes played last season and only one outing this campaign so far, it does not seem like Sundowns would miss him much, and Nascimento plays in the same central defensive position. The strong form of Mosa Lebusa and Motjeka Madisha this season could also convince Mosimane to potentially let the Ivorian depart.
Emiliano Tade:
The arrival of Affonso and the return to favour of Meza has pushed Tade down the pecking order. Keletso Makgalwa is also back from loan and now fit again after an ankle injury, whilst Tokelo Rantie and Phakamani Mahlambi are also forward options who need game-time. The Argentine scored on his Sundowns debut and had excellent stats for AmaZulu, but the options mean that Tade could be considered surplus to requirements.
Who should Sundowns keep or offload to make space for Nascimento? Let us know by commenting below!
Earn Airtime & Data With Soccer Laduma’s Social Media App - Download Now


Home
|
Join Us
|
Directions
freeCodeCamp
Bridgend
How to find us
We meet at two locations join the facebook group to find out which we are at this week
The White Horse, Coychurch
Starbucks, Waterton


Because methodm1 is a static
method that is called from
within the same class – in which its declared, it can be called without
needing to instantiate an object to do so.
Therefore, after the call to m1, and the subsequent throw clause
at line 3, the RuntimeException (thrown at line 3) is caught at line 8, and
the code flow enters the next try block (at line 9) – where another
throw clause occurs.
The catch block for the Exception thats thrown at line 10,
contains code logic that both prints a String value, and throws another
RuntimeException (at line 13). Since RuntimeException is not
required to be caught after its thrown, the execution of the program code is not
interrupted as a result of the thrown
RuntimeException. Instead, the code flow simply transitions to the next line of program code.
Note: Although the the execution of the program code is not interrupted as a result of the thrown
RuntimeException, when the program completes its execution, the program results
indicate that a (un-caught) RuntimeException did in fact occur, when
the program was run.
The finally block that immediately follows the thrown
RuntimeException
(at line 13) also contains code logic that prints a String value – and is subsequently followed by
another finally block, that prints a String value as well.