Pages

Saturday, August 31, 2013

Cheers Mate

Man! The past three years (a little more) have been amazing. I have met some of the brightest and nicest people on the planet. So, I am moving back to the US. In fact, I sit here now in the Auckland, New Zeeeland airport clicking this out. It's sad to leave, but I can't want to turn on a new adventure. Matt 3.0.

I left with a nice bang though! Last night was the monthly Ruxmonsecurity/hacker talks in Melbourne, and I delivered a talk: "An Organized Talk on Disorder: Defeating Address Randomization to Make the Universe Boring." I must say that it was one of the best talks I have ever delivered. I talked about a technique I discovered to defeat address space layout randomization. Anyways, I have not publicly published anything on this... yet.

I love Melbourne, Ruxmon, and having made some of the best friends, I will miss this/that place. But In three years, I only saw two kangaroos in the wild, no snakes, no drop bears, one big-ass monster spider, and killed a single jar of Vegemite. Good on me mate.

-Matt

Wednesday, August 14, 2013

Non-deterministic Trash Pick-up, or Why a Garbage Collector Might Influence Itself

Determinism is a sexxy property for software verification. Given a known input a deterministic program should produce the same output, consistently. This makes testing trivial, simply match the program's output with what has been previously been determined as the correct output. If the two outputs match, *bang bang* we passed output verification and the PHB is pleased. This is, of course, assuming that the program is void of any side effects that would cause some bit of non-pure/non-deterministic output. For a deterministic program, any unexpected output is a clear sign of a bug. For other types of programs, non-deterministic output can result from the program relying on clock values, random values, or other input which can be hard to replicate in testing (such as mouse or other device interrupts). However, a proper verification setup should have a way to statically set such variables so that the program can have a proper output testing. For instance, seeding the random number generator used in the program to a known value during testing.

I was recently surprised to find one of my memory management test cases producing non-deterministic output, even though the program is trivial and relies on little or few external libraries, and no obvious random or non-deterministic input. Actually, I discovered this a while back, but recently revisited it. Simply, I was gathering data for my thesis work, region-based memory management (RBMM), and found that the garbage collector I was comparing my RBMM system against kept producing different collection counts (the number of times the collector executed during my test case's run). See, both garbage collection and RBMM are forms of automatic memory management and I wanted to see how well my RBMM system compares to the more common garbage collection. My research is based on implementing an RBMM system in Go and then comparing my work against the stable garbage collector that Go ships with.

Anyways, I was able to replicate the effect I had previously witnessed in a simpler test (below) using the Go runtime provided by gcc-4.8.1. Remember that Go is garbage collected, thus its garbage collector was producing different collection counts (NumGC below) for each execution of the test.

package main
import "runtime"

func main() {
    for i:=0; i<10000000; i++ {
        f := new(float64)
        *f++
    }

    var m runtime.MemStats
    runtime.ReadMemStats(&m)
    println("NumGC: ", m.NumGC)
}

Why would Go's collector be producing non-deterministic collection counts? This program obviously does the same thing every execution, and generates the same amount of garbage each execution. Well, a couple things could be happening. Perhaps Go's collector was looking at overall system resources, and not just for the test case, and deciding when to collect. Or, perhaps it uses a random value which might affect collection. As it turns out, the latter was the case. Go, by default, enables some statistics/profiling information during runtime. What tipped me off was that I ran a grep for "rand" within the runtime source and I found the following in its memory allocation function "runtime_mallocgc" located in gcc-4.8.1/libgo/runtime/malloc.goc. Note that I modified the whitespace some:

if(!(flag & FlagNoProfiling) && (rate = runtime_MemProfileRate) > 0) {
    if(size >= (uint32) rate)
        goto profile;
    if((uint32) m->mcache->next_sample > size)
 m->mcache->next_sample -= size;
    else {
        // pick next profile time
 // If you change this, also change allocmcache.
 if(rate > 0x3fffffff) // make 2*rate not overflow
     rate = 0x3fffffff;
 m->mcache->next_sample = runtime_fastrand1() % (2*rate);
 profile:
     runtime_setblockspecial(v, true);
     runtime_MProf_Malloc(v, size);
    }
}

So their profiler is having an affect on the amount of memory pressure on the garbage collector, thus causing the collector to kick-in more often than a non-profiled runtime. So, what does this mean? Well, if you do not need any profiling support (probably not if you are running production) then disable the profiler! What I did, was just that, and then executed my simple test multiple times. Bingo! With the profiler disabled I was able to achieve consistent predictable garbage collection counts from Go's collector. To disable the profiler, simply add this line to your main()

    runtime.MemProfileRate = 0
The latter flag will set the profiling rate to zero, thus the runtime will not collect allocation metadata. Otherwise, this collection of metadata will influence the garbage collector, and that probably is not wanted if you run a production executable (or are performing some verification/testing).

-Matt

Thursday, July 11, 2013

11 Years

That's right faithful readers (all two of you). You have been digesting my blabberings for three years now. I have been in Melbourne for 3 years as of yesterday (July 10)!

-Matt

Tuesday, July 9, 2013

First Class, and I Don't Mean Data

After my trip to Seattle to present at MSPC 2013, which I think went "OK," I headed back to the 757 to chill for a bit, visit my ole dentist, recharge my batteries (I am a machine... duh), and to well just get "home" for a tad. With that said, I did think about garbage collection some, and continued to work on my thesis. But that's probably not a good topic for this post, since the title mentions "First Class," and I don't mean higher-order language constructs.

So the story goes like this: When I was heading back to Melbourne, my flight plan took me from Norfolk, VA to Dallas, and from Dallas to Brisbane. The latter leg, by the way, is the 6th longest non-stop flight according to the wikipedia's entry on longest non-stop flights. Anyways, my Norfolk to Dallas ticket had no seating assignment. I was a bit baffled, but continued to play the game. Anyways, as I get ready to board, the ticket agent at the gate handed me a first class ticket! WTF?!? REALLY!?! Sometimes, you just take things and ask questions later. Anyways, this free upgrade comes with decent coffee in a ceramic mug, a steamed towel to wash my face with (travelling first class is hard work), and a free dinner. I rejected the dinner, because I had a prepared hummus sandwich awaiting me, and they didn't have much vegan awesomeness except for some nuts and salad. Oh, and the nuts come in a ceramic ramekin. The salad was pretty damn first class... and it came with a cloth napkin, freshly pressed rainbow milk straight from the nipples of an albino unicorn, a free yoga lesson, and shiatsu massage given by supermodels on their way to Maui for a photo-shoot. (Just lying about the milk (I'm vegan duh!).

So how did this first class upgrade happen? Maybe they oversold crap-class and had to choose a few suckers to ride pimp style? In fact, my neighbor is pretty cool here. But first class still doesn't score you free wifi. Oh, hold on, the lovely flight attendant is now offering a desert... I have to say no; I think I'll go for more coffee, because my bladder is definitely of infinite volume.

Anyways, I must say that I think the people in first class looked at me and were wondering if I were some rich famous musician, or hacker seeking asylum. I can't really say I am dressed to the nines here. And... my coffee is here; yet another ceramic mug! Oh, and the seat is spacious and I have enough leg-room for me to not even think about using the recliner feature on my chair. Just to think, my butt cheeks are sitting in the same seat that a thousand other well-off cheeks have graced. I am spoiled.

-Matt

Wednesday, June 19, 2013

I met... GCus

The title in this post is pronounced GCus like jesus but with GC. The latter being the abbreviation for Garbage Collection. This post is just to say that I met Richard Jones at PLDI this year (he is the guru of garbage collection) and his work has made up a huge portion of my thesis. He deserves infinite beers. I also chatted a bit with Hans Boehm again. I also met David Gay and Emery Berger, both whom I have cited in my thesis work. It's way cool to see these people, notable names of memory management! Way cool! Oh, and I had Mr. Jones sign a piece of trash for me, effectively he "marked some garbage" ... but since it has been marked, it shouldn't be reclaimed.
-Matt

Monday, June 17, 2013

jmp 0xSeattle

Wow! So that was one helluva flight. Actually, the flights were nice, since the Uni hooked me up with Quantas (I am a cheapskate and probably would have gone with a cheaper option if it were my wallet being genocided-upon by the airline industry). I finally got the chance to watch The Social Network and Tarintino's more recent Django Unchained. All I gotta say is that I was thoroughly entertained and I think I need to see more Tarintino flicks. Anyways, I am in Seattle for the Memory Systems Performance and Correctness (MSPC) workshop to present our research into garbage collection and region-based memory management, black magic, and the digital alchemical fusion of these two aforementioned dark sciences. Anyways, I think I'll go stroll around this city! My stomach cannot hold any more caffeinated beverages.
-Matt

Tuesday, May 14, 2013

Monkeys like Logs

So I needed a way to fight boredom this weekend. So I decided to start work on a new side project. I had an idea that evolved into a pretty simple concept, to create a console program that monitors text files (log files) and displays their most recent line. It was an excuse to do more curses hackery and to take a break from garbage collection and memory management (which I still hacked on anyways :-). With that said, I have an alpha version of the aforementioned log-viewer TreeTop which you can snag here. "Monkeys like trees, climb to the top."

-Matt

Tuesday, April 30, 2013

Seattle and Nacho

Well, the paper my advisers and self have been laboring over was submitted and accepted to the ACM SIGPLAN Workshop on Memory Systems Performance and Correctness (which is in Seattle this year). More so, I wrote the original draft (with some incomplete pieces). It ended-up being rewritten by my advisers (and a ton of things were added!). Needless to say, it represents hours and hours of work, and composes ideas from their genius. It was great to work on this paper with them, and I am humbled that it was accepted. I have been implementing code for ages now to represent these ideas, basically a combination of region-based memory management and garbage collection.

On another front, I have been working on more PDF hackery. I wanted to make a PDF-grepping utility. I have a basic implementation cooked-up but the key piece is the simplistic PDF text-extraction library that I wrote (note that it is not fully featured and does not account for all encodings and compression schemes). I present upon the world libnachopdf because it ain't yo' PDF. Well, maybe it is your PDF, but that doesn't matter. Get 'yo nacho on over here.
-Matt

Monday, April 15, 2013

I miss industry...

So many of you are probably wondering, because I know I am the keystone in your lives, what is Matt up to? Well, not much, just some thesis writing and stuff. Yes, I am being vague. Anyways, I am ready to knock this PhD out. I have had fun, but personally I find industry more fulfilling, and I long for the day where I can return to that. With that said, here is what trying-to-get-a-PhD looks like.
-Matt

Saturday, March 16, 2013

UniWireless and ArchLinux

No, this is not a memory-management related post. With that said, I decided to actually spend some time and try to get my Linux box running on the the University of Melbourne's wireless network, as they do not have much help regarding low-level settings, at least I didn't seem to find too much help on the aforementioned site. The links at the end of this post are what got me rocking. Personally, I run ArchLinux with netctl (as a replacement for netcfg). The syntax that both of the aforementioned network configuration utilities use is similar. Simply, here is my config, I have a feeling this is going to be similar for many other institutions. Please note that I have not spent any time to tweak or remove any redundant options below.
Interface=wlan0
Connection=wireless
Security=wpa-configsection
IP=dhcp
ESSID=UniWireless
WPAConfigSection=(
    'scan_ssid=1'
    'ssid="UniWireless"'
    'key_mgmt=WPA-EAP'
    'eap=PEAP'
    'identity="MrSexxy"'
    'password="ILikeGoats"'
)
And that's it. Of course, you will need to use your proper uni username and password (the same one you use when logging into the library's online database). Please make sure the permissions on this file are proper so that any-old user cannot read your password.

The uni's website mentions that students can use either a manual or automatic proxy. I choose the manual, which will also request your username/password again. With that said chromium supports both th automatic (pac) proxy configuration and the old-school manual configuration (as follows):
chromium --proxy-server=wwwproxy.student.unimelb.edu.au:8000
... Now fire them torrents up (oh, yeah, I'm pretty sure you are being watched).
Special thanks to these very insightful/helpful posts.

-Matt

Sunday, March 10, 2013

From the Mothership

Last night I went to see the god of funk, George Clinton, along with the Parliament Funkadelic at Billboard. Fantastic show. It's funny, I was thinking, due to being asked: What is it about funk/soul that I like... I mean, I am a metal head, love some blues, and have an inner hippie in me (I dig jam rock). Well, I don't think humans know why they really like something. Sure, I like music that was generated using some bit of talent, and sprinkled with creativity. But, really, why does a person really "like" something? I think it's hard to answer in words... "I like it just because!" It's probably the result of some brain/chemical order in the head.

-Matt

Sunday, March 3, 2013

Bird Trajectory Miscalculation

I personally believe that we as humans take many things in nature for granted, or we just totally ignore them. I have to say, I do not believe that many people consider how awesome birds are. But, they are not perfect. Have you ever wondered: do birds ever screw-up? Surely they must. They are not born bad-ass fliers. They have to learn. They are animal, as we are too. With that said, I am sure that even the most experienced of our avian friends mess-up their calculations on occasion. I am sure that it is not uncommon for an experienced bird to over-correct, or possibly approach a landing site too fast. Do their wings ever get cramped mid-flight and just stop functioning like a Boeing 777 down a man and running on one engine? Sure, they are animals, and subject to some kind of mean-time between failure. Well, as I was leaving uni today a bird just hit me in the head. It wasn't firm or painful, more like a bump. Maybe it was an accident? I should have contacted FAA. Anyways, my hair is a bit frazzled, but it doesn't really look like a nest. Now, it is common for magpies (and other birds) here to attack dogs and people (especially cyclists). In fact, the gov't maintains a "Swoop-off" website where you can download eye pictures to put on your cycling helmet. Often, you will see cyclists with zip-ties sticking out of their helmets for protection from the swoop. Well, I was walking, no helmet, and no eyes on my head. This little bird either decided to attack me, miscalculted one of the numerous variables required for safe and accurate flight, or got a cramp. Either way, I was humbled as nature ran into me.

-Matt

Tuesday, February 12, 2013

Picking up the Trash and Caller vs Callee Saved Registers

So there are a few posts around the internet about caller vs callee saved registers. Just check my references at the end of this post. Basically, I want to define in a concise way what the difference is and why I'm blabbering about stuff that most developers do not have to consider.

To me the difference between caller and callee saved registers matters. Why is that? Well, for one, I am writing a garbage collector and registers along with stack variables and global variables make up the root-set. The root-set is a set of variables that the garbage collector knows about and it is where the collector begins tracing. In short, for each variable in the root set, the collector follows any pointers that variable might have. For any variable that can be reached, starting from the root-set, that variable is said to be alive, and its memory cannot be reclaimed. Any variables not found through tracing can have their memory reclaimed. There it is, garbage collector 101, see you next semester.

As I mentioned, registers make up the root-set. Since the registers can contain pointers to data that was allocated, it is necessary to trace them at garbage collection time. If that allocated data can't be reached, the collector can recycle it and conserve memory resources. But an interesting thing occurs, and this is based on calling convention, how the compiler (or assembly-level programmer) constructs calls to functions. Some registers must be traced and some should be ignored. This, my friends, is the difference between caller and callee saved registers. The callee-saved registers must be traced. You will see why in just a jiffy!

These caller vs. callee registers are defined by the calling convention such as the Sys-V ABI for Intel Processors and/or another calling convention standard. For instance, the former is similar to the cdecl calling convention, and is the convention we will investigate here, as my work space is gcc and it constructs programs in a somewhat similar manner (similar enough to convey the message in this post). These conventions specify how certain registers are to be used. Since registers are global, all functions can see and access/modify them. So, it goes to say that specifying which registers a callee (subroutine) function can manipulate and which registers a caller must save is probably a good thing. As there are times where a caller wants to reclaim data it never stored on the stack, but left lying around in a register.

A caller-saved register is a register that a calling function must save before it calls any other function. As the other function, the callee, can use this fiddle with the register. These are "volatile" and if the data is not stored elsewhere before a function call, they could be lost. That is why these registers are typically stored on the stack.

A callee-saved register is a register that a callee must preserve if it wants to further use the register to store other information. A non-volatile register.

Given my environment (linux on a x86-64bit CPU and compile using gcc), and according to my references the caller and callee saved registers for such a configuration are as follows:
Caller-saved registers: rax, rcx, rdx
Callee-saved registers: rbp, rsp, rdi, rsi, rbx, r12, r13, r14, r15, rip

This is a pretty clear distinction, but a simple example goes a long way... here goes, in pseudo-assembly code. The function foo adds 123 to 456 and then calls bar. The result of calling bar is then added to 123 + 456:

                   # Comments:
foo:               # Function foo entry
    mov 123, rax   # rax = 123
    add rax, 456   # rax = 123 + 456
    push rax       # Caller saved
    call bar       # bar()
    pop rbx        # Restore the saved value (123 + 456 or 579)
    add rax, rbx   # rax = rax + rbx (whatever bar returned + 579)
The common calling convention here cdecl, which is similar to the SysV ABI for Intel and what gcc uses, mentions that return values are stored in the rax register. rax is a caller-saved register, it's volatile. If foo doesn't save it, bar might fiddle with it and change its value. While I don't show a body for bar, suppose it uses register r12 to do some of its math. r12 is a callee-saved register, meaning that the data in r12 is preserved by the callee. Suppose bar looks like:
bar:
    push r12      # Saving whatever is in r12
    mov 789, r12  # r12 = 789
    add r12, 42   # r12 = r12 + 42
    mov r12, rax  # rax = r12
    pop r12       # Restore r12
    return        # return rax
A keen eye will notice that r12 is being used in bar as a callee-saved register, as what the calling convention requires. bar is free to use r12 but it must restore it before it returns. This means that foo does not have to push anything to the stack, in fact foo could be written as follows:
foo:               # Function foo entry
    mov 123, rax   # rax = 123
    add rax, 456   # rax = 123 + 456
    mov rax, r12   # rax is caller saved
    call bar       # bar()
    mov r12, rbx   # Restore the saved value (123 + 456 or 579)
    add rax, rbx   # rax = rax + rbx (whatever bar returned + 579)
Instead of pushing to the stack, foo in this case knows that r12 is a callee-saved, non-volatile, register and makes use of that fact. Now, a keener eye might be saying, well... foo might be a callee of another function. Maybe main called foo well, yes, foo should follow convention and preserve r12.

This is the message for garbage collectors. The garbage collection function is called (probably from the memory allocator, when it notices that memory is low). When the collector function begins to execute, it knows of the callee-saved registers as the caller should have already stashed the data it cared about on its stack or in a callee-saved register.

A few ways to programmatically access the registers is via the setjmp, sigsetjmp, and/or ucontext glibc function calls. For instance, the sigsetjmp is one method that the Bohem collector uses to access registers for his garbage collector (libgc). If you were to look at the setjmp family you would learn that it returns only callee-saved registers, and not the full register set. Why is that? setjmp stores the environment into a structure. This includes just the callee-saved registers, since the caller should have preserved its caller-saved registers onto the onto the stack or in a callee-saved register. Consider the flow: main() --> functionA() --> functionB() --> setjmp(). setjmp would return the callee-saved registers and functionA can make use of these. As the registers values relevant for main, and functionA would be stored elsewhere (stack or callee-saved).

I am pretty sure this post is not free from flaws, but I hope it made sense, or that any flaws do not crush the integrity of the data in this post. Thanks for reading.

Resources:

Monday, February 4, 2013

TBL in Melb

So I was lucky enough to hear the highly regarded Tim Berners-Lee speak here in Melbourne today. In fact, it's kinda neat that I have his name hyper-linked in the previous sentence. His talk covered openness of data and the Aaron Swartz story. I wanted to ask a few questions, but I held off. I wanted to know what browser he uses, and what are the content/site(s) he has loaded-up in his browser. I also wanted to ask if he composes html-formatted email (a sure sign of the devil). Anyways, that's it for this post.

-Matt

Monday, January 14, 2013

History Lesson

So I caught up with some Swedish badassery last night. That's right my sexxies (you the reader) I got my ass handed to me by Sabaton. Ok, in all honesty, I didn't rock out too hard, I took it easy, no mosh pits for me. I just chilled and enjoyed watching everyone else rock their asses off. It was like a history lesson, delivered in metal. Take the song Cliffs of Gallipoli, which has a special significance to Australians. Great show! The openers, Eyefear and Black Majesty, both whom I have seen before, also kicked ass. Lots of asses, lots of kicking. Oh, and to the dude dressed as a WWI ANZAC soldier: your uniform kicked butt!

-Matt

Monday, December 31, 2012

3...2..1... Collect the Trash!

Ok so y'all probably remember wayyyyy back in October when I was discussing writing a garbage collector. Well, I really don't expect you to remember that. "You" being the pronoun referring to my two subscribers (one being a stalker). Ok, yeah I flatter myself, in reality, it's probably not a stalker of physical attraction, rather a psychotic blood thirsty individual. *waves*

Well, why do I want to dance with a garbage collector? Isn't that the evil-bastard-child/antithesis to region based memory management (RBMM), what I have been working on the past two years or so? Nope! Garbage collection can be a compliment. See, RBMM works by analyzing a program at compile-time (my system uses a gcc-plugin). From this analysis the compiler can insert memory allocation and reclaim calls (think malloc/free) at compile time. My system automatically free's memory, based on which objects point to which other objects. These groupings of objects can come from the same region of memory. A region cannot be reclaimed until all objects in it are no longer needed. Then, in one quick swoop, the memory of the region (the space that all the objects take-up) can be reclaimed. This fast memory reclaim is a key benefit of RBMM, as there is no need to visit each object and reclaim its memory individually.

Unfortunately, not all object lifetimes can be decided at compile time, such as global variables, or values pointed to/aliased by globals. This means that some objects cannot be reclaimed based on a compile-time static analysis. If these undecidable-lifetime objects are in a region, then that region lives for the entire lifetime of the program. Static analysis cannot force a region to die, unless it can be 100% sure that the region contents (objects) are never needed again. Global nastyness creates region bloat, as some objects might be reclaimable, and not others. As I previously mentioned, a region cannot be removed until ALL of its objects are no longer alive. If a global variable pops into the region, then that region now lives forever. Like a virus.

The above issue means that a garbage collector can actually benefit an RBMM system. That is what I have been working on: a combining of RBMM and garbage collection. This is not unique, and has been done before; however, the way we implement our collector is unique, but that is not discussed in this post.

Disclaimer: Grammar nuts please note that this is a blog post, so I am immediately relieved of any misuse of narrative modes. This is a design for my PhD and something that I have worked on with my advisers quite a bit (the "we"). The code is mine.

What I want to discuss in this post is how we locate stack variables. Stack variables form a subset of the root-set. The root-set being a collection of variables that are live at the time of garbage collection. If any data is accessible through the root-set then that object is also alive and must survive garbage collection. Else, the memory for data/objects that is not reachable can be collected. I will not go into details, or even the collector type I have chosen (e.g. mark-sweep, or copy, etc). Instead, I just want to talk about finding the stack variables; as I said a sub-set of the root set. Globals and registers also can be part of the root-set, but this post is only about stack variables </redundancy>.

When the garbage collector kicks-in the collector needs to start somewhere. It starts by scanning the root-set. Well, how does the collector get this root set? Specifically, what this post is concerned with is obtaining a sub-set of the roots, the stack variables. If you are familiar with stack-frames or activation records, the values there in the stack must be scanned. If any of those variables point to objects dynamically allocated (e.g. heap variables or variables from a region), then such objects must survive collection, and their memory cannot be recycled.

I have implemented a compiler modification (gcc-plugin) which provides hints to the garbage collector as to how to trace the stack of the program. This is how the collector gets the subset of the root-set, the stack variables. Actually, it is so cool and nifty I warranted this entire blog post to the notion.

My aim is to provide, at compile-time, a table that can be read by the garbage collector at runtime. During compile-time, as the source-code is being processed my plugin locates all function calls in the program. At the return of each function call a label is inserted (think assembly goto/label). This label is unique for each callsite, and makes up the key into a table that I am building. This key points to information about the function that the label is inside. For the example just below, the three labels are unique, but all point to the same function information. Information about my_function(), which specifies what local variables it has (x, y, z), if the variables are pointers, and how big the variables are.

void my_function(void)
{
    int x;
    float y;
    double z;

    foo();
__label0:

    bar();
__label1:

    baz();
__label2;
}
The function above has three callees (foo, bar, baz). At each call site, my plugin inserts a label. Now, why do I insert labels? Well, at runtime we need a way of associating the return point for each function call (foo, bar, baz). At compile time I do not have any addresses to use, hell, addresses are created by the OS when the executable is loaded; we haven't even finished compiling the source code yet! The solution is to insert a label which can be used at compile time to build a table of stack-variable information. The loader will fix-up the addresses, and at runtime the labels will have the correct address that the function call returns to. Recall that each time a function is called, the return instruction pointer RIP or return address will be stored on the stack. This value will be the same as the respected label. For instance, consider that my_function() is being executed, and the line which calls bar() is executed. When bar() gets called, the return point, which now happens to also match __label1, is placed onto the stack. And when bar() returns, the return point is now the same as __label1. The only thing we have done so far is insert labels. No big deal. Note: I doubt anyone except for maybe one person has read this far, if you do, email me, you kick so much ass, that next time we meet, I will buy you coffee produced from the most lavish and rare of coffee seeds: unicorn digested coffee. I will then serenade you with a ear-piercing song and proclaim you Captain Badassery and dance around bear-chested wearing a Burger-King crown and throw pennies at your feet.

As mentioned, the labels are entries into a table that contains function information (variables, stack size, etc). When the garbage collector kicks-in, it looks at the stack and locates the return point. That value is a key into a function table my plugin generated, remember the RIP coincides with the added labels. The collector uses the RIP/label as a key to get function information, and then processes the variables (figuring out which heap values can be accessed though the local variables in that function). Once that function is scanned, its caller function is scanned, and so on... it's turtles all the way down... until the collector hits main(). Then this portion of garbage collection is complete.

TLDR; Anyways, the above diatribe is an expose into the use of labels for providing a means of accessing stack variables, and providing a compile-time generated way of performing a runtime stack trace.

Have an awesome New Year and may all of your garbage be collected properly!

-Matt

Monday, December 24, 2012

Have a Happy Astrophysical Season!

Happy holidays. Just to inform y'all, my true holiday, the science holiday (which I totally forgot to celebrate), the solstice, was 3 days ago. It happens to be that the aforementioned day also marks the start of the Summer down here in the underworld. And... whooo whee, yesterday, the second day of summer was a blaze. So, frikkin' hot; it was as if you could just bottle up the heat, and drink it. Anyways. Much love, enjoy whatever holiday you celebrate.

-Matt

Tuesday, December 4, 2012

What What?! More Graffiti!

So, I decided to change pace this past Sunday and go out in the morning, grab coffee, chill, and take some pics. I ended up lounging out at Federation Square, listening to an acoustic guitarist at the Fair Trade Festival. On my way there, I went down Hosier Lane and took some pics of the awesome graffiti. Check out the pics on my flickr (pictures uploaded on December 4, 2012).

-Matt

Friday, November 30, 2012

New Version of PDFResurrect... Now with enhanced EOF locating.

The title, while any computer scientist will immediately think is a joke... is in-fact not a joke. The latest release (Version 0.12) is a bug fix release and is now available here. The main fix regards how the tool was locating the EOF token that PDF writing utilities place at the end of different versions of PDFs. Previously, if an EOF token was split across a 256-byte boundary, then Mr. Resurrect would not have found it. The new algorithm might be a tad slower; however, it is more precise.

-Matt

Monday, November 26, 2012

Answering a begging question... what does the heap look like?

So I was curious. What does a process' heap look like? If I were to take a hint from conservative garbage collectors, and scan the memory of a process, what would it look like? Well, to answer this, I threw together some software here, and ran a few GNU programs to see what they look like. I then try to relate memory allocation calls with the heap layout. The conservative garbage collector hint I used was merely the following. When my tool scans the heap, address by address, if the value at each address looks like another address residing in the heap, then my tool says the heap address points to the other address. Anyways the results are munged to crap out a .dot file. More details and such are here.

-Matt