How to get the CPU type on Mac?
For those (like me) missing /proc/cpuinfo badly:
slimac:~ czajnik$ sysctl -n machdep.cpu.brand_string Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
Sure, it only gives a CPU model, but well... It's still better than System Information level of details
More detailed info can be obtained by printing all sysctl variables with names starting with machdep.cpu. Not as human readable as /proc/cpuinfo, but still very useful:
slimac:~ czajnik$ sysctl -a | grep '^machdep\.cpu' machdep.cpu.max_basic: 13 machdep.cpu.max_ext: 2147483656 machdep.cpu.vendor: GenuineIntel machdep.cpu.brand_string: Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz machdep.cpu.family: 6 machdep.cpu.model: 58 machdep.cpu.extmodel: 3 machdep.cpu.extfamily: 0 machdep.cpu.stepping: 9 machdep.cpu.feature_bits: 3219913727 2142954431 machdep.cpu.leaf7_feature_bits: 641 machdep.cpu.extfeature_bits: 672139520 1 machdep.cpu.signature: 198313 machdep.cpu.brand: 0 machdep.cpu.features: FPU VME DE PSE TSC MSR PAE MCE CX8 APIC SEP MTRR PGE MCA CMOV PAT PSE36 CLFSH DS ACPI MMX FXSR SSE SSE2 SS HTT TM PBE SSE3 PCLMULQDQ DTES64 MON DSCPL VMX EST TM2 SSSE3 CX16 TPR PDCM SSE4.1 SSE4.2 xAPIC POPCNT AES PCID XSAVE OSXSAVE TSCTMR AVX1.0 RDRAND F16C machdep.cpu.leaf7_features: RDWRFSGS SMEP ENFSTRG machdep.cpu.extfeatures: SYSCALL XD EM64T LAHF RDTSCP TSCI machdep.cpu.logical_per_package: 16 machdep.cpu.cores_per_package: 8 machdep.cpu.microcode_version: 21 machdep.cpu.processor_flag: 0 machdep.cpu.mwait.linesize_min: 64 machdep.cpu.mwait.linesize_max: 64 machdep.cpu.mwait.extensions: 3 machdep.cpu.mwait.sub_Cstates: 135456 machdep.cpu.thermal.sensor: 1 machdep.cpu.thermal.dynamic_acceleration: 1 machdep.cpu.thermal.invariant_APIC_timer: 1 machdep.cpu.thermal.thresholds: 2 machdep.cpu.thermal.ACNT_MCNT: 1 machdep.cpu.thermal.core_power_limits: 0 machdep.cpu.thermal.fine_grain_clock_mod: 1 machdep.cpu.thermal.package_thermal_intr: 1 machdep.cpu.thermal.hardware_feedback: 0 machdep.cpu.thermal.energy_policy: 0 machdep.cpu.xsave.extended_state: 7 832 832 0 machdep.cpu.arch_perf.version: 3 machdep.cpu.arch_perf.number: 4 machdep.cpu.arch_perf.width: 48 machdep.cpu.arch_perf.events_number: 7 machdep.cpu.arch_perf.events: 0 machdep.cpu.arch_perf.fixed_number: 3 machdep.cpu.arch_perf.fixed_width: 48 machdep.cpu.cache.linesize: 64 machdep.cpu.cache.L2_associativity: 8 machdep.cpu.cache.size: 256 machdep.cpu.tlb.inst.small: 64 machdep.cpu.tlb.data.small: 64 machdep.cpu.tlb.data.large: 32 machdep.cpu.tlb.shared: 512 machdep.cpu.address_bits.physical: 36 machdep.cpu.address_bits.virtual: 48 machdep.cpu.core_count: 2 machdep.cpu.thread_count: 4
Gevent monkey patching versus sniffer & nose
Unless you already know, gevent is a great library built on top of greenlet module and libevent event loop, that allows for easy coroutine-based cooperative multitasking in networked applications. By the way, you know the C10K paper, don't you?
One of gevent's important features is monkey patching - ability to patch some standard Python modules to make them cooperative. There's no magic here, thanks to Python's dynamic nature gevent simply replaces the standard APIs with its own cooperative equivalents. Existing blocking code can then be reused without any modifications. Cool, isn't it? Most notably, gevent patches socket (replacing blocking I/O with libevent-based asynchronous one), thread and threading modules (replacing threads with greenlets). Continue reading…
Python care and feeding, the Dropbox way
I've just revealed (by pure accident, actually), that Dropbox client binary (i.e. Dropbox.exe file) is in fact a zip file with compiled Python files inside (.pyc files, that is). Interesting, huh? A closer look at the executable file (as well as googling for some strings found in the binary) points to the tool used to pack the application into a single executable file - it's py2exe!
Needless to say, it's tempting to look closer at the .pyc files, or even try to decompile them. Here comes the surprise - the files seem encrypted. Typically, .pyc contains a lot of human-readable strings (at least the file name and variable/function names), but it's not the case with files from unzipped Dropbox.exe:
czajnik@czajnik:~/work/dropbox/exe$ strings distutils/__init__.pyc
Oc {
z4E7ls
]yD~
:z<n
Also, every .pyc file starts with a 4-byte magic number - in case of extracted .pyc files, the magic number equals 0xb7f20d0a - no public Python release ever used this value.
It seems that Dropbox team decided to patch the Python interpreter with some decryption routines, in order to protect the application from reverse engineering. Note, that the Python interpreter (Python25.dll) itself is embedded inside Dropbox.exe as a resource, it can be easily extracted with any resource editor. I guess it's time to start IDA Pro and look deeper
Edit: For the curious - I've spent some time digging deeper. It turned out there are 2 protection levels - one is a decryption routine plugged into code demarshalling part of static PyObject *r_object(RFILE *p) function (see marshall.c). It's fairly easy to work it around, even without fully disassembling it - nothing stops one from building a small .exe which calls original code in the DLL to decrypt the file. However, there is another protection - the Python virtual machine opcodes are mixed. This required a bit of manual reverse engineering of PyObject *PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) (see ceval.c), but also turned out to be fairly easy. Now I'm able to uncompyle nearly all the files.
WSGI deployment under a subpath using uWSGI and Nginx
It's relatively obvious how to deploy a WSGI application using Nginx, and there are many tutorials out there dealing with this very task. It took me quite a few minutes, however, to figure out how to deploy the application under non-root URL, e.g. http://some.site.com/admin/.
This is typically dealt with by configuring the SCRIPT_NAME CGI parameter, and letting this name be removed from the beginning of the PATH_INFO parameter by the WSGI environment, before the path is passed down to the application. This way the WSGI application routing remains the same, no matter where in the URL tree it is deployed. The application needs to be aware of SCRIPT_NAME parameter only to generate proper URLs to self. Continue reading…
The weirdest programming language feature ever
I have to admit I had a long break from web applications development, and the topic changed a lot over the last few years. As I'm developing a web app now, I decided to improve my JavaScript knowledge, just to learn about an exceptionally awkward language feature. Continue reading…
Why RS232 uses negative voltage when idle?
Have you ever asked yourself this question? I've found it answered in April issue (261) of Circuit Cellar, in Test Your EQ section. The answer is quite intriguing.
First of all, DTL and TTL logic families were the most popular when RS232 was developed. In both DTL and TTL input current is significantly lower in the high state (a TTL input is equivalent to NPN transistor's emitter), so it makes perfect sense to use high state when idle to minimize the power consumption in the logic part.
The second part of the story is more funny. Why is high state represented by negative voltage on the line? This is because copper wires exposed to moisture are less likely to corrode if the voltage is negative. Indeed, it's the anode (positive electrode in electrolytic cell) where the oxidation happens. Beautiful explanation, isn't it?