Why are global variables suddenly available for Greasemonkey and Tampermonkey scripts? - greasemonkey

Recently while writing a userscript and I found out that variables in the page context are available.
console.log(window) did not result in an error in neither Tampermonkey nor Greasemonkey.
I am confused. Shouldn't global variables only be accessible through unsafeWindow?

Global variables are only available that way in #grant none mode. As of Greasemonkey 2.0 (June 17, 2014), #grant none mode became the default. Tampermonkey quickly followed suit, to maintain compatibility.
If you never had the habit of using #grant, this will seem like a recent (unexpected) change.
You should now always use the #grant directive so that you are conscious of what mode the script is operating in.
I also recommend using #grant GM_addStyle, at a minimum, except in those rather rare cases when #grant none is appropriate. This avoids a unexpected conflicts and side effects, and is closest to both how scripts used to work and to how many script engines still operate. (That is, such scripts are more reliable and more cross-platform compatible.)
The way Greasemonkey handles #grant is now a leading cause of many, many problems.

Related

Why cannot I use xterm to see log infos from modules directly but through log files?

I have been reading linux kernel dev by Love (3 edit). I assume, it is quit well known book for kernel development. I have although encounter, I am not able to use code, because I do not know how to compiled in kernel space (e.g. cannot use <asm/thread_info.h>). So i have decided to read guide to compile and use kernel modules first (I have also disable secure BIOS in order to load my own modules), here How Do Modules Get Into Kernel. I suppose, once I would learn, how to compile kernel space, then would be able to use kernel libraries, thus examples of the book.
Then, from exactly that link (guide), there is mentioned:
It is highly recommended that you type in, compile and load all the examples this guide discusses. It's also highly recommended you do this from a console.
You should not be working on this stuff in X.
Modules can't print to the screen like printf() can, but they can log information and warnings, which ends up being printed on your screen, but only on a console.
If you insmod a module from an xterm, the information and warnings will be logged, but only to your log files.
You won't see it unless you look through your log files. To have immediate access to this information, do all your work from console.
But how can I use console? If i do echo $TERM, : xterm-256color. So i do have xterm, but I should not have.
Conclusion: There are 2 questions.
Should I learn the guide of kernel modules first, in order to use Love's examples?
If so, How do I use console instead of xterm then?

More Resource Intensive: Tampermonkey script (for video control) running on ALL domains—or just 1K domains each with its own #include entry?

I've got a quick question--and I apologize in advance if the answer is (or should be) obvious… the question might betray my very basic [i.e., basically non-existent] fluency in code.
But I wrote a .js userscript in Tampermonkey to allow me to have more precise control over video playback in Safari. I've had it set to run on all domains:
// #include http://*
// #include https://*
And while that's certainly worked for me thus far, I'm aware that the script runs needlessly on the 80% of my Internet-ing I do that doesn't involve any interaction with video elements… So I went through and compiled an exhaustive list of ~1,000 specific domains where it makes sense to have the script running, e.g.,:
// #include *://*.facebook.com/*
// #include *://*.vimeo.com/*
// #include *://*.youtube.com/*
But after actually entering in 1,000 lines of this into my [formerly quite petite!] userscript, it dawned one me that--as far as I know--I could actually be greatly increasing the amount of system resources it takes to run this script by forcing it to now run through a long list of domains to see if it matches… and that perhaps simply having it run by default could be less resource-intensive?
Ha, at the same time, I can also imagine how running it everywhere = obviously more of a waste of resources… But since I've no idea how I'd even go about testing this (and I certainly don't have a solid enough grasp of the underlying theory here) --> I thought I'd leave it up to the experts, and reach out to you here for advice!
Thank you for your help!! :-)
Partial answer because it's too big for a comment and because I don't have the inclination to setup and run some new experiments right now. (If someone posts an answer with updated, verifiable numbers, it gets my upvote.)
Here's a rough sketch of what happens when you have Tampermonkey, Violentmonkey, etc. and installed userscripts:
Every page you visit is checked against the #include, #match, and #exclude directives of every active userscript. The smarter engines would check #exclude first and stop if a match is found.
Some engines are better about this checking than others and, ideally, the site match information would be kept in memory for maximum speed.
Every <frame> or iframe on all the pages you visit are checked against the #include, #match, and #exclude directives of every active userscript, unless that script has #noframes set.
If a script matches a page (or frame), then Tampermonkey (etc), must:
(A) Fetch the script code, and any data -- often from disk (slow).
(B) Then create some level of sandbox -- depending on the engine, the browser, and the #grant mode.
(C) Inject the script into the aforementioned sandbox -- almost always wrapped by an anonymous function -- and run it.
Then, the userscript will use resources, depending on its code.
In general:
#match performs better (last checked years ago) than #include. If you are going to use 1000 lines, use #match over include.
Use #noframes unless you have a reason not to.
Steps 1 and 2 ideally can be done all from memory (need to see what the various engines currently do), and a lot of #includes can be processed in the same time it takes to inject one userscript. (Anybody want to try to collect some numbers?)
If a userscript or its data (#require files, #resource files, GM_setValue data) need to be fetched from disk, then that's comparatively a huge time lag. (But still faster than fetching stuff from the internet.)
Finally, the time effort and possible stress of having to maintain a large list of sites, editing the userscript file each time, has to be compared to how invasive your script is.
If it was me, and the script only delayed pages by less than about 300 milliseconds, I'd just hold my nose and use:
// #match *://*/*
// #noframes
However, if the script is more invasive, slower, or more resource intensive, you can use a hybrid approach...
Keep the list of sites to fully run on in GM_setValue data and/or a #resourced file.
That way you could edit the list on the fly using, for example, menu commands; or via the Tampermonkey script-data editor; or even via buttons that you create for that purpose. All of that is beyond the scope of this question, however.

Why are some Bash commands both built-in and external?

Some commands are internal built-in Bash commands while others are external (other programs). I see why certain commands need to be built-in. Some of the reasons are:
If a command needs to change the internal state of the shell process.
If a command performs a very basic operation in the shell.
If a command is called often and needs to be made fast. An external command is executed by loading an external program and hence is slower.
But why are some commands both built-in and external, for example echo and test? I understand echo is used a lot and thus is built-in (Reason 3). But then why also have it as an external command and have a binary for it in /bin/echo? The built-in version of echo will always take precedence over the external version and thus, the external version is hardly ever used. So, why then have an external version of it at all?
It's exactly your point 3. When a command does very little (echo is a good example), spawning a new process dominates the run time behavior. With growing disks and bandwidth and code bases you always reach a spot when you have so much data and so many files (our code base at work has 100k files!!) that one less spawn per file makes a difference of minutes.
That's also why the typical built-in is a drop-in replacement which takes (perhaps a superset of) the same arguments as the binary.
You also ask why the old binary is still retained even though Bash has it as a built-in — the answer is that a lot of programs rely on the existence of that /bin/echo. It's actually standardized.
Bash is only one of many user interfaces and offline command interpreters. They all have different sets of built-ins. Some shells are purposefully small and rely a lot on what you could call "legacy" binaries. One example is ash and its successor, Dash. Dash is now the default /bin/sh in Ubuntu and Debian due to its speed, and is popular for embedded systems due to its small size. (But even Dash has builtins for echo, test and dozens of other commands, and provides a command history for interactive use.)

Compare-And-Swap not working on many Cores

When I discovered the "CAS" instruction, I remember that I well understood that it could work for threads running on one single CPU but I was surprised that it could for many CPUs
Yesterday, I had my first opportunity to test it on one of my developments. I implemented it and it really worked fine; all my unit-tests was green. Perfect.
But today, I ran my unit-tests on another machine and they are now failing. Less perfect
The main difference on the two machines is that the first one (the one on which the unit-tests are green) is a quit old laptop, with only one core! The second one is more recent i7, and more powerfull...
Now, on my i7, if I force my unit-tests to run on one single core, they become successful. I do this by running
taskset -c <cpu-id> my-unit-test
Legitimately, my original question comes back: is CAS working on many cores? OK, according to what I read, I would be surprised if it didn't...
So what? I hope it comes from a bug in my code. To give you more information, I have a class with a critical section. I added an attribute
bool m_isBeingModified;
It is initialized to false. Moreover, at the beginning of my critical section, I run the function
inline void waitForClassBeingModified()
{
while (!__sync_bool_compare_and_swap(&m_isBeingModified, false, true))
{} /// I concider that I can to such a loop as my critical section is very light/short
}
Finally, at the end of my critical section, I reset my boolean variable
m_isBeingModified = false;
I tried to set my attribute as volatile but it did not change anything: my unit-tests are still failing
Last information:
gcc --version
gcc (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Thank you for your help
Also use __sync_bool_compare_and_swap to unset the variable instead of just m_isBeingModified = false;. Also, don't implement your own mutex...
Both the compiler and the CPU can reorder code in unintended ways. The __sync primitives are marked in such a way to prevent this reordering from happining. Thus, with m_isBeingModified = false; it could very well the case that the compiler would first set the variable to false and only then generate the code for whatever you intended to be inside of the critical region.
Thanks to Uli's precious help, I think that I have now all the elements to answer to my question.
First of all, I may not be clear until there but the function I want to protect against concurrent access is very light. It takes around 80 cpu cycles to complete (TSC). That's why I prefer to implement my own 'light' concurrent mutex based one CAS than using pthread_mutex.
I found this interesting page that explains how to 'temporarily' disable the code-reordering thanks to the following instruction:
__asm__ __volatile__("":::"memory");
Using it, I really boost my concurrency-protection and, of course all my tests are still successful.
To get a summary, the following list reports the impact on performance of different solutions I tried:
Original code (without protection): around 80 TSC
Double CAS (set & unset variable): around 105 TSC
Mutexes based solution: around 120 TSC
Single CAS + disable reordering: around 85 TSC

Basic Install Cygwin Windows 10 - IO Error opening <file>

I am using Windows 10.
I downloaded setup-x86_64.exe from https://cygwin.com/install.html and am selecting the defaults (Install from Internet/Direct Connection/default locations).
I have tried several mirrors including cygwin.mirror.constant.com
I am accepting all the default packages plus some basic developer stuff (gdb, make) and check "Select required packages (RECOMMENDED)".
I get quite a way through the Cygwin Setup and then get the first of many pop-up messages "IO Error Opening file....._autorebase/binutils/cygwin/grep/mintty etc. Do you want to skip this package?"
If I skip the packages, I get a non-working Cygwin install (it can't find mintty). If I don't skip the packages, it hangs when the Cygwin installer hangs when it gets to the first of the problem packages.
Thanks in advance about what part of the setup process I am missing.
A bit late, but anyway: I have stumbled across the same problems yesterday when I tried to install Cygwin on Windows 10 the first time.
I have followed all advice given at various sites (including this one): Disabled antivirus software, followed the Cygwin FAQ, and so on, but to no avail.
Then I studied the setup log and found a line which told something about an address mismatch (sorry that I don't have the exact wording - I surely won't repeat the experiment ...). That lead me to the idea that it might something have to do with ASLR (a technique for hardening the system against malware).
The next step was to turn off ASLR via the UI of Windows Defender. After I had done that, I could install Cygwin without any problems. I have not yet tested if I actually could use Cygwin when I turn on ASLR again; I don't feel very comfortable when having turned it off completely.
The alternative would be to turn off ASLR per executable. This is also possible in Windows Defender's UI. But it could mean adding dozens of exceptions, depending on how many Cygwin packages you have installed.
The technical reason for the problem is how POSIX's fork() works. Basically, it clones the parent process's image, using the same offset addresses. But when ASLR is active, those offsets will change when cloning the process, which will make fork() fail. Since fork() is extensively used by Cygwin, it can't operate as intended when ASLR is active.

Resources