I saw this question being asked on here years ago with few but interesting answers. I'd imagine that a lot of you still have some pretty interesting stories to tell about some crafty workarounds.
I've done it a few times but my favorite hack for Windows is to use a bootdisk to swap the accessibility app with command prompt so you can wipe the local admin password.
So I once made a script with python and selenium to make fake petitions to bring back Wendy's spicy chicken nuggets. It stopped around 9,000 when the script crashed after awhile... I think they did bring it back though so I feel like I was responsible.
I've worked on a single-machine computer vision system which used RabbitMQ to send messages around, including JPEG frames which were rather heavy, in contrast to other messages.
After we hit a certain number of frames/second, RabbitMQ became a bottleneck. My solution was to write the JPEG frame in the shared memory, then pass around shared memory ID, offset and frame length, instead of the whole frame. Only services that actually needed the frame would read it, others would just pass around a small JSON object. After that was implemented, the bottleneck disappeared.
I don't know if this qualifies as a "hack", but it certainly felt that way in the moment.
What's really awesome about this is I think you independently discovered a huge trick in performance optimization. "Zero copy" solutions for eliminating the overhead of moving frames around are very popular - if you look up that term you'll see it pop up everywhere. Companies/teams of engineers spend months coming up with this solution and its a reliable way to reduce overhead of moving data around. It works across all layers and in fact entire hardware architectures are designed to allow for this kind of stuff. Kudos :)
Most USB cameras send JPEG frames because USB 2.0 isn't nearly enough to support raw frames: 60 frames/second * 1920*1080 pixels/frame * 4 bytes/pixel = ~475MiB/s, while maximum USB 2.0 bandwidth is ~60MiB/s. You also don't want to store raw frames on the cloud storage, your bill would skyrocket. Those are some of the reasons for using JPEG.
If you're using dockerized services (which are a must for NVidia-based CV, since their CV libraries are a dependency hell), you must use some kind of networking solution to communicate. RabbitMQ might be considered overkill, but it does the job and is robust.
It's not nice to talk that way about others' work, especially when your comment insults, but doesn't provide any insight whatsoever.
Yea you're right of course, I was being glib. Glad it worked out in the end for you. For the record I don't think RabbitMQ was overkill, I think it's just way too much overhead to work for something like sending frames of video (which I think is the moral of your story). Anyway I'm guessing this was for a school project and you won't have to live with it so it's moot.
It was actually a production system we built on my first job. It wasn't just sending frames from A to B, it did have a few moving parts. It eventually got stable and stopped changing, so in a way, I don't have to live with it. But it's up and running and does its job.
> If you're using dockerized services (which are a must for NVidia-based CV, since their CV libraries are a dependency hell), you must use some kind of networking solution to communicate.
Eithen the two processes can share memory, in which case they don't need to communicate via network, much less RabbitMQ, or they can't, in which case the hack wouldn't have worked at all.
I suppose what I meant to say is you need to communicate between processes somehow. Shared memory is fast, but it's hard to communicate with it exclusively - message-based protocols are better suited for that, and most of them are implemented over TCP.
A lot of standard protocols can run over a unix domain socket, if you're not at the level of implementing a shared memory communication protocol but want to cut some overhead for more or less free.
I worked for a healthcare startup that interfaced with a lot of large insurance companies. They had no API access for their patient information and would just give us credentials to ancient web portals instead.
I wrote my own browser automation scripts to create our own internal patient API. Ended up reducing claim billing errors by a ton and resulted in 6 figures a month in additional revenue.
What impact did the 6 figures in additional revenue bring to you personally vs. the owners of your startup? How were you acknowledged or compensated for this feat?
Honestly I was a brand new hire and it was my first real engineering job so I gained nothing from it. At the time I had no idea how to advocate for myself or my accomplishments. Big lesson learned.
I hexedited an old Devart DLL that refused to pick up our valid license with the Mono License Compiler to just... not check for a license. I had to find the exact right byte pattern manually then flip the flip 2 of them to a brfalse.0
This is so completely random, and not really code related, but it was huge at the time (circa 1990). I was compiling large bibliographies of research documents for NSF that eventually had to be read into Word Perfect 5.1 for DOS for printing. We had written a very complex system of WP macros to search for tags that we programmatically put in the file, but they took forever to run and would often crash. My colleague and I found that we could only use search/replace to send begin/end pairs of tags for any formatting code (e.g. bold, italics). However, if we replaced the closing tags first, then the opening one, WP would notice that there were pairs of empty tags and get rid of the extra closing tag so that the underlying text would be formatted properly.
We were doing this everyday, so it cut the processing time from many hours to seconds. We swore each other to secrecy about this development and marched off to Dunkin’ Donuts with our giant ice coffee belt-loop holsters to celebrate.
Rewriting a C++ matrix library to change its API back in 1996/1997, for a 100x speedup.
It was a nice library... It had things like a = b + c; ... but back then, C++ really didn't have tools to support that syntax with great performance. Especially mixed with a bad allocator, that prevented multi-threaded allocation.
I'd have to think more about "proudest" but here is a recent one:
Reshaped RAID by
* LVM moving entire storage off to external iscsi SAN
* wiping the controller config and recreating it from scratch in desired layout
* migrating it back from SAN
(before the whiners, it had backups and it was a node in cluster so even if it died no availability loss).
Similar weird admin trick was
* removing all of the nonessential LVs in LVM
* creating a big fat file in /dev/shm (essentially ramdisk)
* migrating storage to that file
* shredding content of hard drives
* voila, shredding drives of system without restarting and with still having ability to clean shutdown it.
My favorite hacks mostly came from when I worked in a robotics+computer vision research lab, ~13 years ago.
If you've never worked with stereo vision systems, they have multiple cameras as input. The algorithms need to know the exact position of each camera. These calibrations are extremely sensitive - if the camera moves even a teensy bit, the algorithms start to fail because the image features aren't where they expect. Anytime we had a bad calibration, we needed to rerun calibration. This was a process where we waved a checkerboard in front of the cameras at tons of different angles, and software would process all the images and deduce the pose of each camera. It typically took at least an hour, and sometimes it'd fail and you'd need to redo it. Typically we'd need to recalibrate systems every few weeks, no matter how hard we tried to make the whole rig rigid.
Anyways, one day I accidentally drove the robot's sensor head into a table right before a demo with the people funding the project. The program started spitting out "BAD CALIBRATION" warnings. This would basically mean we'd need to cancel or postpone the demo to recalibrate, which would look really bad since they traveled all the way to our office only to be told "never mind!"
As a last-ditch effort. I grabbed the cameras and started wiggling them back and forth, and managed to force them into an orientation where the calibration worked. The demo went off perfectly. I later told the researchers about it and they hated it. "You should just always do calibration," etc.
My favorite hack that I've seen someone else do was at Google, where some specific project had a weird test that checked some ratio like "lines of tests to lines of code." Someone checked in a test with the comment "If you're not cheating you're not trying", and it just had the same assertion over and over for hundreds of lines to satisfy the metric. I never looked into why the person couldn't just disable the test, but I like the simplicity of the solution.
But that is a calibration. In fact it's exactly how you'd do an automatic calibration of a system like this: mount cameras on robotic arms or some other multi-axis system, then move them around with a feedback loop until cameras produce the wanted image.
basically, redesign the arguments for a function such that I can call it again at a given spot with one parameter changed and, to a first order approximation, it acts as if the function is resumable.
I've used this trick in a few places now, just recently in idiomorph to allow head elements to load before the rest of the content is morphed:
2 daily scheduled 20 minute naps (8AM, 3PM) with noise cancelling headphones and a face mask neutralizes the side effects of sleep fragmentation with a new child.
Not that hacky or mind-boggling, but does involve a hex editor and lots of money...
I added support for the '\ ' PostScript escaped space sequence to a custom, high-performance PDF parser.
A former employer used this to derive key figures from financial statements. Any change to the parser had to be Pareto-optimal: so if you modified the parser, it should not fail to parse any key figure that was previously possible to parse. Adding this improved reading word-wrapped text in hundreds of cases and key figures in dozens; I recall that my bosses thought it must be a mistake, and that I had to convince them by finding the right section in some Adobe PDF spec.
I wasn't an expert at the PDF format. But stumbling on a number split in two by apparently nothing, and digging up a 0x5C 0x20 '\ ' with a hex editor, I seemed to recall that PDF was built on top of PostScript, and that TeX / LaTeX syntax was somehow related to PostScript. So it struck me that what was a literal backslash in the PDF must just be an escape sequence.
Oh, your comment reminded me of one of my proudest moments as a high school student!
Norton Utilities was a must for any MS-DOS user, and so, poor students pirated it when they could. The problem was once installed, it asked for a password, and subsequent runs would demand it. My friend got ahold of a diskette with a complete but password-locked copy, and while he knew the password, he found it annoying and wanted to bypass it.
By trial and error, we found a location where the binary stored the password, but it was encrypted. Studying the "encryption", it turned out it was an XOR of the password padded with spaces until I think 20 characters, so you could change that location to XORed spaces to enter the password with a single Enter, or change it to zeros so it behaved like a new install.
I don't know what my friend did with his copy, I just remember the high of beating the copy protection of the legendary Peter Norton.
In my master's thesis, I was generating component graphs from source code.
One issue I had was the generated graphs were suuuuper ugly due to the connections between components overlapping in a non-optimal way. Turns out, untangling graphs is a NP-HARD problem. I got around it by using a spring-repulsion simulation, where connections between components pulled them together but components repelled other components when they got close. It wasn't a perfect solution, but it got me 90% of the way!
It's such a powerful technique and it's so simple to implement! I used the same technique for putting a bunch of icons on a map and making sure they were as close as possible to their target position without overlapping.
I often create screen recordings for my classes, but it's very boring and time consuming. I'm a perfectionist, and if I mistype a command I prefer to re-record everything. Moreover, every time one of the tools used in the videos gets a significant update, I feel compelled to redo the video.
I have started using xdotool [1] to create bash scripts that send mouse clicks and keystrokes to apps. Interleaving calls to xdotool with the "sleep" command [2] produce a convincing effect. If I need to redo a video to fix typos or after a program update, I just fix the bash script and restart the recording.
Alas, the only thing that is missing in my videos is the sound of keyboard clicks… But nothing is perfect!
We used something similar in 2008 at CeBIT (which was the biggest IT trade show in Germany at the time). A publishing house for IT magazines set up a side area for minibooths and gave them out to a dozen open-source projects. I was there with a bunch others to represent KDE. We only had a few posters and stickers, nothing fancy, so we had to make our booth flashy somehow. My friend quickly hacked together something with a similar input simulation tool that opened applications from the start menu, flipped through directories in Dolphin, and such, and set it up to run in a loop. It sure did help us catch people's attention.
If adding mouse/keyboard sounds the main challenge is the variability in sounds, for instance how hard keys are pressed. Also, repetetive sounds, or sounds that are mis-timed to the corresponding action, are worse than no sound at all.
> I have started using xdotool [1] to create bash scripts that send mouse clicks and keystrokes to apps. Interleaving calls to xdotool with the "sleep" command [2] produce a convincing effect.
Debugging mysterious recurring hangs in a storage appliance. The nodes were connected via Infiniband, so there were two parts to the hack. The first was to write a program which would find all of the kernel memory areas and register them with the Infiniband controller. The second was to slurp up all of the memory on a hung node via Infiniband from one of its peers, and convert that into dump format so we could use gdb on it. After collecting a couple of dozen such dumps and poring over them for a couple of days, I was finally able to debug one of our most intractable problems.
That led to a second, though lesser, hack. The problem turned out to be code that was allocating way too much memory. (Userland programmers working in the kernel, ugh.) This would sometimes cause the stack pointer for one task to jump all the way over its task structure into the stack of the previous task, which would make that stack very confusing. That's why it took two days to figure out, even with dumps in hand. (Also, putting the stack right next to the task structure was a stupid decision on Linux's part.) To find the dozens of places where this was happening, I wrote a tool to disassemble all of our kernel code and look for the part of the function prolog that allocated stack space, thus creating a list of those that were allocating too much. Then I spent a week fixing them.
It was a grueling process, under lots of pressure at a struggling startup, but ultimately the result was very rewarding.
About 15 years ago I was trying to debug a pesky timing issue and couldn't reproduce it.
I wrote a script to capture and replay network traces from Wireshark (then called Ethereal) that included keeping the timings intact. Caught the bug reliably every time.
Was reminded the other day about the time I arrived early at the night shift to learn a particular manual "scheduling" technique (how to match single size and double size packages to hundreds of deliverables, and I think there was some options too).
I saw the excel file, asked for 5 minutes, came back after 15 and had solved the problem to such a degree that it went from wasting two hours for two teamleaders on every night we did this job to being almost trivial for one to do in 5 minutes.
And the solution was trivial. Like really trivial. But no one had thought of it before : )
Second best probably when I saved a messed up server in US (an person on site hadn't noticed the . in rm -rf ./bin and had proceeded to use sudo without thinking, as every Linux user does when they go through that dangerous phase).
I realized I still had one ssh connection to the server, realized either scp or rsync or something was in sbin (or somewhere else) and we could use it to copy the necessary binaries to get it back on track.
This easily saved us a 3 days (RHEL with Oracle 11g something easily took days to get right and it also was a massive pain to do).
First, you might have overestimated the complexity of it. I tried to describe it as uncomplicated as possible without giving up the exact details of what it was, but I admit I might have failed at it. It was utterly trivial.
Basically we produced single packs and two-packs of a product and customers would order 1-n of them, sometimes with customizations.
The trivial but immensely tedious job was to make production and packing lists that took this into account.
I.e. with these orders:
Customer 1: 5 packs
Customer 2: 3 packs
That would end up like
Customer 1: 2x2-packs + 1 single pack
Customer 2: 1x2pack + 1 single pack modification x
Total:
5 2-packs
+ 1 single pack
+ 1 single pack modification x
Of course a real production run would have hundreds of these.
What I did once I got hold of the list was just to integer division (or what it is called) by 2 on each row to get the number of double packs in one column, something like (original number - 2x doublePacks) to get a 1 or 0 for single pack and then make a sum at the bottom for all columns.
I might have made som checksums too.
As for modifications I cannot remember anymore, I might have added some color or something, but once the immensely tedious first part was done it wasn't much of a problem IIRC.
Thanks! I may be fine tuning the installation process on newer Ubuntu/Debian if I have time over the holidays.
(the code is stable, that's why there are no new features, although I do plan to move up from Python 3.5 to whatever is the least common denominator across distros to clean up a few things)
Worked for a web hosting company. Created a regional routing and fail over mechanism that leveraged the CDN's own cache to store routing information so sites could be dynamical and individually re-routed by the CDN.
Very carefully scheduling NMI and IRQ updates to achieve a virtual sound channel on an old NES, resulting in a sawtooth bassline with volume control. This steals about 13% of the CPU time. The biggest hack in the arrangement is the scheduling of OAM DMA to sneakily just barely fit between timed audio updates, since it pauses the CPU and would otherwise cause an audible glitch. Among other things, if NMI notices that it interrupted IRQ, it apologizes profusely and exits immediately, which is a rather unusual workaround on 6502 systems.
I've open sourced the technique with a more detailed writeup [1] and I like to think the game I created with it is pretty fun, [2] but of course that's subjective. You can try it in your browser here. [3]
Cool. Kind of unrelated, but is there anything stopping someone from just generating a sawtooth DPCM sample at runtime and using the channel as normal without having to use crazy timing stuff?
Yes, it comes down to how the DPCM channel encodes sound data. A sawtooth gets most it's energy and harmonics from the sudden jump at one end. This impulse is impossible to encode in 1-bit delta encoding, the closest you can get is a slightly steeper slope. The audible effect is similar to a low pass, with the strength dependent on the intended amplitude, so instead of a nice sharp saw, you get a muddy not quite triangle.
A few commercial games did use the DPCM channel melodically, but the main drawback is the large size of the samples relative to the commonly available ROM chips of the era. Price is a big factor when you need to put one chip in every game. Here's how that sounded in practice:
Further problems! The DPCM channel can only address memory from the region 0xC000 - 0xFFFF, due to how its "address" byte is interpreted. Most cartridges cannot place RAM in this memory region, so you're stuck baking the samples into ROM space. Many cartridges cannot even bank switch this region, so the samples additionally cut into your "fixed" ROM that is usually precious space for interrupt service routines and common framework code.
Ah very interesting, thanks for the explanation! I'll definitely check out your lib if I ever get around to writing a homebrew NES game, I love quirky audio tricks :)
I spilled water on my favorite keyboard and broke it, then let it dry and fixed it by using a pencil to trace over the damaged circuits. It worked fine again after that!
(Graphite in pencil lead is a weak conductor, enough to make the keyboard circuit work)
ep0: 3c509 in test mode. Erase pencil mark! This means that someone has
scribbled with pencil in the test area on the card. Erase the pencil
mark and reboot. (This is not a joke).
Pretty much -- IIRC connecting the pad bypasses the internal EEPROM and loads a default configuration, and from there you can read/write the EEPROM as well.
It is the user’s responsibility (with help from the configuration program) to avoid configuring the boot PROM on the adapter in such a way that the system is not able to boot. If this does occur, you can manually jump the Test Via using a #2 pencil. The Test Via forces the adapter into test mode, which disables the boot PROM so that the adapter configuration program can be run. You must cover the designated area thoroughly with the pencil mark.
Test mode forces the adapter not to perform the Automatic Initialization sequence, which means the EEPROM is not read and the adapter is left in the following configuration:
■ Address Configuration register = 0000h
■ Resource Configuration register = 0000h
■ Product ID register = 0000h
Test mode also shortens the ID sequence to 8 bytes (first is still FFh and last is 69h) and forces it to the active state (that is, the adapter is active and will respond to I/O cycles at base address 0200h even without going through the ID sequence).
After you are done, thoroughly erase the pencil mark.
Not that I'm particularly skilled in this, but for fun I once decompiled an Android app that accompanied cheap electronic door locks we had installed in the office. I found the C files that were generating temporary passwords, manually parsed for what I was looking for, then wrote a shell script (with help from a friend) that could find/generate more temporary passwords from any existing temporary password+approximate timestamp pair.
About a year later an intern showed me that a coffee stirrer also can work to open the lock, but I bet he won't write about that in a forum.
413 comments
[ 3.6 ms ] story [ 346 ms ] threadOnce machine boot and login started Windows want to be activated. There you press Win-U and on popup you can click web link to open default browser.
After we hit a certain number of frames/second, RabbitMQ became a bottleneck. My solution was to write the JPEG frame in the shared memory, then pass around shared memory ID, offset and frame length, instead of the whole frame. Only services that actually needed the frame would read it, others would just pass around a small JSON object. After that was implemented, the bottleneck disappeared.
I don't know if this qualifies as a "hack", but it certainly felt that way in the moment.
If you're using dockerized services (which are a must for NVidia-based CV, since their CV libraries are a dependency hell), you must use some kind of networking solution to communicate. RabbitMQ might be considered overkill, but it does the job and is robust.
It's not nice to talk that way about others' work, especially when your comment insults, but doesn't provide any insight whatsoever.
Eithen the two processes can share memory, in which case they don't need to communicate via network, much less RabbitMQ, or they can't, in which case the hack wouldn't have worked at all.
I suppose what I meant to say is you need to communicate between processes somehow. Shared memory is fast, but it's hard to communicate with it exclusively - message-based protocols are better suited for that, and most of them are implemented over TCP.
I wrote my own browser automation scripts to create our own internal patient API. Ended up reducing claim billing errors by a ton and resulted in 6 figures a month in additional revenue.
We were doing this everyday, so it cut the processing time from many hours to seconds. We swore each other to secrecy about this development and marched off to Dunkin’ Donuts with our giant ice coffee belt-loop holsters to celebrate.
Rewriting a C++ matrix library to change its API back in 1996/1997, for a 100x speedup.
It was a nice library... It had things like a = b + c; ... but back then, C++ really didn't have tools to support that syntax with great performance. Especially mixed with a bad allocator, that prevented multi-threaded allocation.
Reshaped RAID by
* LVM moving entire storage off to external iscsi SAN * wiping the controller config and recreating it from scratch in desired layout * migrating it back from SAN
(before the whiners, it had backups and it was a node in cluster so even if it died no availability loss).
Similar weird admin trick was
* removing all of the nonessential LVs in LVM * creating a big fat file in /dev/shm (essentially ramdisk) * migrating storage to that file * shredding content of hard drives * voila, shredding drives of system without restarting and with still having ability to clean shutdown it.
If you've never worked with stereo vision systems, they have multiple cameras as input. The algorithms need to know the exact position of each camera. These calibrations are extremely sensitive - if the camera moves even a teensy bit, the algorithms start to fail because the image features aren't where they expect. Anytime we had a bad calibration, we needed to rerun calibration. This was a process where we waved a checkerboard in front of the cameras at tons of different angles, and software would process all the images and deduce the pose of each camera. It typically took at least an hour, and sometimes it'd fail and you'd need to redo it. Typically we'd need to recalibrate systems every few weeks, no matter how hard we tried to make the whole rig rigid.
Anyways, one day I accidentally drove the robot's sensor head into a table right before a demo with the people funding the project. The program started spitting out "BAD CALIBRATION" warnings. This would basically mean we'd need to cancel or postpone the demo to recalibrate, which would look really bad since they traveled all the way to our office only to be told "never mind!"
As a last-ditch effort. I grabbed the cameras and started wiggling them back and forth, and managed to force them into an orientation where the calibration worked. The demo went off perfectly. I later told the researchers about it and they hated it. "You should just always do calibration," etc.
My favorite hack that I've seen someone else do was at Google, where some specific project had a weird test that checked some ratio like "lines of tests to lines of code." Someone checked in a test with the comment "If you're not cheating you're not trying", and it just had the same assertion over and over for hundreds of lines to satisfy the metric. I never looked into why the person couldn't just disable the test, but I like the simplicity of the solution.
But that is a calibration. In fact it's exactly how you'd do an automatic calibration of a system like this: mount cameras on robotic arms or some other multi-axis system, then move them around with a feedback loop until cameras produce the wanted image.
https://github.com/bigskysoftware/htmx/blob/a3c414dcee94fd03...
basically, redesign the arguments for a function such that I can call it again at a given spot with one parameter changed and, to a first order approximation, it acts as if the function is resumable.
I've used this trick in a few places now, just recently in idiomorph to allow head elements to load before the rest of the content is morphed:
https://github.com/bigskysoftware/idiomorph/blob/e6dfc189fa3...
Weaponized virsh save/restore because of how Linux handles mounts (mnt_id)
I added support for the '\ ' PostScript escaped space sequence to a custom, high-performance PDF parser.
A former employer used this to derive key figures from financial statements. Any change to the parser had to be Pareto-optimal: so if you modified the parser, it should not fail to parse any key figure that was previously possible to parse. Adding this improved reading word-wrapped text in hundreds of cases and key figures in dozens; I recall that my bosses thought it must be a mistake, and that I had to convince them by finding the right section in some Adobe PDF spec.
I wasn't an expert at the PDF format. But stumbling on a number split in two by apparently nothing, and digging up a 0x5C 0x20 '\ ' with a hex editor, I seemed to recall that PDF was built on top of PostScript, and that TeX / LaTeX syntax was somehow related to PostScript. So it struck me that what was a literal backslash in the PDF must just be an escape sequence.
Oh, your comment reminded me of one of my proudest moments as a high school student!
Norton Utilities was a must for any MS-DOS user, and so, poor students pirated it when they could. The problem was once installed, it asked for a password, and subsequent runs would demand it. My friend got ahold of a diskette with a complete but password-locked copy, and while he knew the password, he found it annoying and wanted to bypass it.
By trial and error, we found a location where the binary stored the password, but it was encrypted. Studying the "encryption", it turned out it was an XOR of the password padded with spaces until I think 20 characters, so you could change that location to XORed spaces to enter the password with a single Enter, or change it to zeros so it behaved like a new install.
I don't know what my friend did with his copy, I just remember the high of beating the copy protection of the legendary Peter Norton.
I have started using xdotool [1] to create bash scripts that send mouse clicks and keystrokes to apps. Interleaving calls to xdotool with the "sleep" command [2] produce a convincing effect. If I need to redo a video to fix typos or after a program update, I just fix the bash script and restart the recording.
Alas, the only thing that is missing in my videos is the sound of keyboard clicks… But nothing is perfect!
[1] https://github.com/jordansissel/xdotool
[2] https://en.wikipedia.org/wiki/Sleep_(command)
For the clicking sound you could add something like the below command on each click.
'aplay click.wav'
Can you share some of these scripts?
https://github.com/ziotom78/tnds-tomasi-notebooks/blob/maste...
And here is the recording, made with asciinema:
https://asciinema.org/a/544981
That led to a second, though lesser, hack. The problem turned out to be code that was allocating way too much memory. (Userland programmers working in the kernel, ugh.) This would sometimes cause the stack pointer for one task to jump all the way over its task structure into the stack of the previous task, which would make that stack very confusing. That's why it took two days to figure out, even with dumps in hand. (Also, putting the stack right next to the task structure was a stupid decision on Linux's part.) To find the dozens of places where this was happening, I wrote a tool to disassemble all of our kernel code and look for the part of the function prolog that allocated stack space, thus creating a list of those that were allocating too much. Then I spent a week fixing them.
It was a grueling process, under lots of pressure at a struggling startup, but ultimately the result was very rewarding.
I wrote a script to capture and replay network traces from Wireshark (then called Ethereal) that included keeping the timings intact. Caught the bug reliably every time.
I still think that's the best thing I every did.
I saw the excel file, asked for 5 minutes, came back after 15 and had solved the problem to such a degree that it went from wasting two hours for two teamleaders on every night we did this job to being almost trivial for one to do in 5 minutes.
And the solution was trivial. Like really trivial. But no one had thought of it before : )
Second best probably when I saved a messed up server in US (an person on site hadn't noticed the . in rm -rf ./bin and had proceeded to use sudo without thinking, as every Linux user does when they go through that dangerous phase).
I realized I still had one ssh connection to the server, realized either scp or rsync or something was in sbin (or somewhere else) and we could use it to copy the necessary binaries to get it back on track.
This easily saved us a 3 days (RHEL with Oracle 11g something easily took days to get right and it also was a massive pain to do).
Basically we produced single packs and two-packs of a product and customers would order 1-n of them, sometimes with customizations.
The trivial but immensely tedious job was to make production and packing lists that took this into account.
I.e. with these orders:
Customer 1: 5 packs Customer 2: 3 packs
That would end up like
Customer 1: 2x2-packs + 1 single pack
Customer 2: 1x2pack + 1 single pack modification x
Total:
5 2-packs
+ 1 single pack
+ 1 single pack modification x
Of course a real production run would have hundreds of these.
What I did once I got hold of the list was just to integer division (or what it is called) by 2 on each row to get the number of double packs in one column, something like (original number - 2x doublePacks) to get a 1 or 0 for single pack and then make a sum at the bottom for all columns.
I might have made som checksums too.
As for modifications I cannot remember anymore, I might have added some color or something, but once the immensely tedious first part was done it wasn't much of a problem IIRC.
Started as a hack, turned into the standard way of how I deploy all my personal projects, and then some.
Great job!
(the code is stable, that's why there are no new features, although I do plan to move up from Python 3.5 to whatever is the least common denominator across distros to clean up a few things)
I've open sourced the technique with a more detailed writeup [1] and I like to think the game I created with it is pretty fun, [2] but of course that's subjective. You can try it in your browser here. [3]
[1] https://github.com/zeta0134/z-saw
[2] https://zeta0134.itch.io/tactus
[3] https://rusticnes.reploid.cafe/wasm/?cartridge=tactus.nes
A few commercial games did use the DPCM channel melodically, but the main drawback is the large size of the samples relative to the commonly available ROM chips of the era. Price is a big factor when you need to put one chip in every game. Here's how that sounded in practice:
https://www.youtube.com/watch?v=LEgoYUzwabI
(Graphite in pencil lead is a weak conductor, enough to make the keyboard circuit work)
----------------------------------------
It is the user’s responsibility (with help from the configuration program) to avoid configuring the boot PROM on the adapter in such a way that the system is not able to boot. If this does occur, you can manually jump the Test Via using a #2 pencil. The Test Via forces the adapter into test mode, which disables the boot PROM so that the adapter configuration program can be run. You must cover the designated area thoroughly with the pencil mark.
Test mode forces the adapter not to perform the Automatic Initialization sequence, which means the EEPROM is not read and the adapter is left in the following configuration:
■ Address Configuration register = 0000h
■ Resource Configuration register = 0000h
■ Product ID register = 0000h
Test mode also shortens the ID sequence to 8 bytes (first is still FFh and last is 69h) and forces it to the active state (that is, the adapter is active and will respond to I/O cycles at base address 0200h even without going through the ID sequence).
After you are done, thoroughly erase the pencil mark.
----------------------------------------
About a year later an intern showed me that a coffee stirrer also can work to open the lock, but I bet he won't write about that in a forum.