This page is not available in 繁體中文, as a result the English (en_US) version is shown instead.
Life update
You know life is getting boring when the title of the post is "Life update". I mean, if it's any interesting I would have used a more eyeball grabbing title. I was originally scheduled to go to a everything-paid-for trip to San Diego to visit a customer site earlier this month, the trip didn't work out because the IT person on that site is too busy with other work. Maybe I still get to go in July, or maybe it's canceled, who knows.
Spent most of last week offline, other than during work time. No AIM, MSN, ICQ, minimal email.
Sunday (I managed to miss the midnight again) was Father's Day. Went to Mayflower's for lunch as usual, and cooked dinner as promised. It wasn't much of a dinner but it is the first time I made anything non-trivial for someone else. Everything is actually edible, go figure.
Google Analytics
Finally received my Google Analytics Invitation Code. Will be checking in the next few days to see what kind of statistics it gives, and how it compares with Awstats.
First impression is that the UI is somewhat laggy. The main report pages are driven by flash, and loading the flash content isn't exactly snappy. The latency with Web applications still leave a lot to be desired.
Google Analytics is also targeting business users rather than hobbyists. It has lots of buzzwords like "Marketing Optimization" and "Goal Conversion" that I have no idea about. I don't think I will use this for over a month.
Photos update
Added another album 2006 where I plan to dump all the pictures I take in 2006 to. Want to see what my cube looks like? What about what we at Riverbed (well, some of us anyway) think about Web 2.0?
On the other hand, I am slowly uploading other stuff that I've written to here. It may take a while since I don't type Chinese very fast.
Walking the Stack/Heap/Data Section
Been experimenting with writing a garbage collector lately. One of the problems I faced was how to walk the stack/heap/data section for all the (potential) pointers. The solution that I come up with probably only works for 32bit x86 Linux, and even then maybe making some bad assumption about memory alignment, among other things. Still, this maybe useful for other curious minds out there.
First there are etext
, edata
and end
. Those 3 symbols are not normally defined, so you can define variables with those names if you want. But if you do:
extern unsigned int etext, edata, end;
ld
(or maybe something else, I can't find where I originally read this) will define those symbols if they don't resolve to anything else. Their values are meaningless, only their addresses are useful. &etext
is the starting address for the text section, &edata
is the end of text section and also the beginning of data section. &end
is the end of data section and also the beginning of the heap. The type that you declare etext
et al with is probably unimportant.
For memory allocators that use sbrk()
, you can also use sbrk(0)
to find the end of the heap. I've read that glibc uses mmap for malloc()
s that are over certain sizes, so that may break things if you mix sbrk(0)
and malloc()
.
The stack is a little bit trickier, everywhere I've looked suggests that there is no portable way to walk the stack. Here's the code snippet that I am using:
register gulong *fp __asm ("%ebp");
/* skip the current frame because I don't want to walk the current
function */
gulong *ptr = (gulong *)*fp;
do {
gulong *saved = ptr + 4;
ptr = (gulong *)*ptr;
if (ptr == NULL) {
break;
}
// do something from "saved" to "ptr"
} while (1);
As you can see, I first define a variable for %ebp
, which is the x86 way of saying $fp
. 0(%ebp)
contains the address of the previous frame pointer, the last of which points to NULL
. Incrementing by 4 maybe a bad assumption though, there maybe cases where 2 is more appropriate.