I need to retrieve the real architecture of a Mac regardless of if the process is running through Rosetta or not.
Right now in Node.js, process.arch returns x64 and in shell, uname -m returns x86_64.
Thanks to #Ouroborus, this note describes how to figure out if your app is translated.
If it's translated:
$ sysctl sysctl.proc_translated
sysctl.proc_translated: 1
If not:
$ sysctl sysctl.proc_translated
sysctl.proc_translated: 0
On non-ARM Macs:
$ sysctl sysctl.proc_translated
sysctl: unknown oid 'sysctl.proc_translated'
As #Elmo's answer indicates, the command line sysctl -n sysctl.proc_translated or the native equivalent sysctlbyname() call will indicate whether you are running under Rosetta.
Two other sysctl values are relevant. On M1 hardware without Rosetta, these values are returned:
hw.cputype: 16777228
hw.cpufamily: 458787763
hw.cputype is 0x0100000C (CPU_TYPE_ARM64) and hw.cpufamily is 0x1b588bb3 (CPUFAMILY_ARM_FIRESTORM_ICESTORM).
However, when executed under Rosetta, the low-level machine code which collects CPUID takes precendence and following two values are returned, both via sysctlbyname() and the command line:
hw.cputype: 7
hw.cpufamily: 1463508716
These correspond to 0x7 (CPU_TYPE_X86) and 0x573b5eec (INTEL_WESTMERE).
It appears Rosetta reports an x86-compatible Westmere chip under Rosetta, but this choice seems consistent everywhere I've seen. This "virtual architecture" may be useful information for some programs.
Another possibility presents itself in the IO Registry. While the default IOService plane collects data in real-time, the IODeviceTree plane is stored at boot, and includes these entries in the tree (command line ioreg -p IODeviceTree or ioreg -c IOPlatformDevice):
cpu0#0 <class IOPlatformDevice, id 0x10000010f, registered, matched, active, busy 0 (180 ms), retain 8>
| | | {
...
| | | "compatible" = <"apple,icestorm","ARM,v8">
(for CPUs 0-3)
and
cpu4#100 <class IOPlatformDevice, id 0x100000113, registered, matched, active, busy 0 (186 ms), retain 8>
| | | {
...
| | | "compatible" = <"apple,firestorm","ARM,v8">
(for CPUs 4-7)
This clearly indicates the ARMv8 Firestorm + Icestorm M1 chip.
The same approach should work for the M1 Pro and M1 Max.
Related
is it somehow possible, to view the final machine code (x86 instruction) that a browser generates from my Javascript? E.g.
--- Raw source ---
function add(a, b){
return a + b;
}
...
--- Code ---
source_position = 0
kind = FUNCTION
Instructions (size = 456)
0x36953100 0 8b4c2404 mov ecx,[esp+0x4]
0x36953104 4 81f991806049 cmp ecx,0x49608091 ;; object: 0x49608091 <undefined>
0x3695310a 10 750a jnz 22 (0x36953116)
0x3695310c 12 8b4e13 mov ecx,[esi+0x13]
0x3695310f 15 8b4917 mov ecx,[ecx+0x17]
0x36953112 18 894c2404 mov [esp+0x4],ecx
0x36953116 22 55 push ebp
Thanks!
Your script doesn't transform to machine code directly. JavaScript runs on virtual machine V8 (it's true for chrome and classic nodejs) and you can get VM byte code using:
node --print-bytecode script.js
Then V8 executes and optimizes the byte code and calls external C libraries and OS API (system calls) or WEB API. Final machine code may vary even with the same javascript code (for example before and after optimization).
You can also start Chrome from the command line with
--js-flags="--print-bytecode"
UPD:
As #PeterCordes noticed nodejs allow to see Turbofan generated machine code using
node --print-opt-code script.js
Chrome:
--js-flags="--print-opt-code"
Also you can use HTML visualizer like https://github.com/v8/v8/tree/master/tools/turbolizer
So I'm trying to connect to openEEG upon running the claimInterface() function I get
NetworkError: Unable to claim interface
lsusb shows this problem is likely because some MSI driver is running on the same driver
Output of lsusb -v -s4
Bus 002 Device 004: ID 1770:ff00
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x1770
idProduct 0xff00
bcdDevice 1.10
iManufacturer 1 MSI EPF USB
iProduct 1 MSI EPF USB
iSerial 1 MSI EPF USB
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 34
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 2mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.10
bCountryCode 33 US
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 57
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 10
Device Status: 0xa630
(Bus Powered)
Bus 001 Device 004: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x0403 Future Technology Devices International, Ltd
idProduct 0x6001 FT232 USB-Serial (UART) IC
bcdDevice 6.00
iManufacturer 1 FTDI
iProduct 2 FT232R USB UART
iSerial 3 A105XV9J
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 32
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 90mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 2 FT232R USB UART
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Device Status: 0x0000
(Bus Powered)
I originally tried adding 255 as the classCode on navigator.usb.requestDevice because the documentation said I can do that, but they don't have the same IDs so that was pointless. Also upon reconnecting I can only get lsusb to output of the MSI driver even though Chrome picks it up and I got an access denied error.
which is strange because I changed the udev rules and used sudo chmod -R 777 * In dev/bus/usb
I then found in folder "001" a file that I previously had to manually change the permissions of thinking it was the MSI driver but this time the original file was deleted in place of one named "007" instead of "005" (probably because I tried plugging the device in twice)
So this must be a combination of MSI security features? and OpenEEG creating a new file every time it's loaded?
The only solution I can think of is to delete a file that I don't understand and change the permissions every time it's plugged in. both of which are very prohibitive for uses especially since I want my website to work across a broad range of devices and operating systems
PS: Using Linux Mint if that's relevant and here is my code(I don't think it's the problem) that is being run with on local node.js server
document.addEventListener('DOMContentLoaded', event => {
let button = document.getElementById('connect')
button.addEventListener('click', async() => {
var device
const VENDOR_ID = 0x0403
const PRODUCT_ID = 0x6001
const CLASS_CODE = 255
device = await navigator.usb.requestDevice({
filters: [{
vendorId: VENDOR_ID,
productId: PRODUCT_ID,
classCode: CLASS_CODE
}]
})
console.log('opening..')
await device.open()
console.log('open!')
.then(() => device.selectConfiguration(1))
.then(() => device.claimInterface(0)).catch(error => { console.log(error + 'eeeeeeerrrr ' + device.configuration.interfaces[0].interfaceNumber); });
console.log(device);
await device.close().catch(error => { console.log(error + 'eeeeeeerrrr'); });
});
})
EDIT/UPDATE: lsusb returns nothing when not connected the two drivers are coming from the same input???????
When you connect your device on the USB port Linux loads its driver and claim the device for itself.
If you want to use it somewhere else just unload the driver:
$ sudo modprobe -r ftdi_sio
If you reboot your computer the driver will load again and you'll have to unload it manually. If you want to keep it unloaded you can do:
$ echo "ftdi_sio" | sudo tee -a /etc/modules
I can understand why it got you confused, considering the output of lsusb is not that clear but I think the other MSI driver is for the root USB controller on your computer. If you remove it you won't be able to see your ports or anything connected to them.
If unloading the driver does not fix your problem maybe you're not claiming the correct device. You can find out more reading the log file if you write on your navigation bar chrome://device-log/
My question is, what is the most efficient configuration for PhantomJS tests.
Currently I have 1 instance of PhantomJS running and every instance can have 2 tabs opened (dev env).
Is it better to have more instance of phantomjs or opened tabs, and if tabs, what is the upper limit of PhantomJS.
CPU:
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 58
model name : Intel(R) Core(TM) i5-3210M CPU # 2.50GHz
stepping : 9
microcode : 0x19
cpu MHz : 2494.316
cache size : 3072 KB
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx rdtscp lm constant_tsc up rep_good nopl xtopology nonstop_tsc pni pclmulqdq monitor ssse3 cx16 sse4_1 sse4_2 popcnt aes xsave avx rdrand hypervisor lahf_lm
bogomips : 4988.63
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
Memory:
total used free shared buffers cached
Mem: 2515896 1155828 1360068 0 171648 622668
More information:
I would like to handle multiple tests at once with as less memory as possible. Now I am running two pages per phantom instance, and already I am having issues with network requests. I have a timeout of 20s and if a specific network request is not finished in that time, test fails.
Test is successful if I only run one page in one PhantomJS instance, but that is not optimal, because we will be running more then 1000 tests, and I would like to arrange tests in multiple pages across multiple phantomjs instances.
Example:
10 phantomjs instances
every phantomjs instance can run 30 pages
Now why when running multiple pages in one instance, does the network request lag so much?
I try to profile my node.js script at CLI.
As written at https://code.google.com/p/v8/wiki/V8Profiler, or http://blog.arc90.com/2012/03/05/profiling-node-programs-on-mac-os-x/ a do:
$ node --prof my_script.js
All ok, I get file named v8.log with bunch of lines.
But then in inspection tools all go wrong.
$ tools/mac-tick-processor v8.log
show to me
Statistical profiling result from v8.log, (298 ticks, 237 unaccounted, 0 excluded).
and empty JavaScript section.
[JavaScript]:
ticks total nonlib name
Also I try https://github.com/bnoordhuis/node-profiler, but get some results too.
How I can work with --prof results?
$ node -v
v0.8.18
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.7.4
BuildVersion: 11E53
As suggested by #Dogbert you can use github.com/sidorares/node-tick
Feel free to create pull request if you missing any functionality. I haven't updated it for quite a while and it still seems to work
After Node 4.4.0:
node --prof-process isolate-0xnnnnnnnnnnnn-v8.log > processed.txt
From: https://nodejs.org/en/docs/guides/simple-profiling/
I would like to test how loading external javascripts affect the page when remote servers are slow to respond.
I looked for tools that can slow down connection for specific sites but I could only find tools that slow down the whole network or that don't exist for Mac (like here or here)
Are there tools like that?
Using the Detours App for Mac, you can redirect certain hosts to your own local web server. From your server, you can then fetch the resource (via curl, etc.), sleep for a certain amount of time, and then return the response.
Its not the easy way out, but you could use IPTABLES (unix ip-router) in conjunction with TC (traffic control)?
This is quite extensive if you dont know how terminal bash-scripting works but you will need a terminal 100% for a proper solution.
If this does not work for you, try a simpler method: http://lartc.org/howto/lartc.ratelimit.single.html
Store this in for instance your home folder, call it bwm.sh
#!/bin/bash
# through this interface
IF=$1
# on this HOST
HOST=$2
# get the IP from HOST
HOSTIP="`nslookup $HOST|grep Address|grep -v "#"|cut -d " " -f2`"
# with this rate
your_rate=$3
# defaults /sbin/tc
TC="`whereis tc | sed 's/[^\ ]*.\([^\ ]*\).*/\1/'`"
# defaults /sbin/iptables
IPTABLES="`whereis iptables | sed 's/[^\ ]*.\([^\ ]*\).*/\1/'`"
#some number
PRIO="123"
# you create a new rule in the mangle table
IPT="$IPTABLES -t mangle"
echo "Program locations found: iptables: $IPTABLES and tc: $TC"
echo "down-rating bandwidth\n on $HOST\n to $your_rate whilst marking packages that origins\n from $HOSTIP\n with $PRIO on interface\n named $IF"
echo -n "starting setup.."
# apply custom filter
$IPT -N myfilter
# add it to the POSTROUTING chain
$IPT -A POSTROUTING -j myfilter
# if conntrack is used - restore a mark and allow the packets, which already have been marked, through - no need to check again
$IPT -A myfilter -p tcp -j CONNMARK --restore-mark
$IPT -A myfilter -m mark --mark $PRIO -j ACCEPT
# add to it your matching rule
$IPT -A myfilter -p tcp -s $HOSTIP -j MARK --set-mark $PRIO
# conntrack it optionally, so not every packet has to be rematched
$IPT -A myfilter -j CONNMARK --save-mark
# use that mark in a tc filter rule
echo qdisc add
$TC qdisc add dev $IF root handle 1: htb default 30
echo class add
$TC class add dev $IF parent 1: classid 1:1 htb rate $your_rate # <<<<<<<< fill in rate
echo sfq add
# add an SFQ qdisc to the end - to which you then attach the actual filter
$TC qdisc add dev $IF parent 1:1 sfq perturb 10
echo filter add
$TC filter add dev $IF parent 1:1 prio 1 handle $PRIO fw flowid 1:1
echo "done"
Now open terminal window and achieve root permissions
finder > terminal > open, we will go to user home and enter super user
cd; su
enter root password
start program with Interface, Hostname, Rate parameters
sh bwm.sh IF HOST RATE