A simple C dtrace aggregation consumer

This is a little bit of gluing from other sources, but it’s a simple piece of code to consume the content of an aggregation from dtrace using the `libdtrace` library. I’ve tested it on Mac OSX 10.9 and it works, the usual caveats that it wont work all the time, and you need privileged access to get it to run:

#include <assert.h>
#include <dtrace.h>
#include <stdio.h>

// This is the program.
static const char *progstr =
"syscall::recvfrom:return \
{ @agg[execname,pid] = sum(arg0); }";

// This is the aggregation walk function
static int
aggfun(const dtrace_aggdata_t *data, void *gndn __attribute__((unused)))
{
    dtrace_aggdesc_t *aggdesc = data->dtada_desc;
    dtrace_recdesc_t *name_rec, *pid_rec, *sum_rec;
    char *name;
    int32_t *ppid;
    int64_t *psum;
    static const dtrace_aggdata_t *count;

    if (count == NULL) {
        count = data;
        return (DTRACE_AGGWALK_NEXT);
    }

    // Our agrgegation has 4 records (id, execname, pid, sum)
    assert(aggdesc->dtagd_nrecs == 4);

    name_rec = &aggdesc->dtagd_rec[1];
    pid_rec = &aggdesc->dtagd_rec[2];
    sum_rec = &aggdesc->dtagd_rec[3];

    name = data->dtada_data + name_rec->dtrd_offset;
    assert(pid_rec->dtrd_size == sizeof(pid_t));
    ppid = (int32_t *)(data->dtada_data + pid_rec->dtrd_offset);
    assert(sum_rec->dtrd_size == sizeof(int64_t));
    psum = (int64_t *)(data->dtada_data + sum_rec->dtrd_offset);

    printf("%1$-30s %2$-20d %3$-20ld\n", name, *ppid, (long)*psum);
    return (DTRACE_AGGWALK_NEXT);
}

// set the option, otherwise print an error & return -1
int
set_opt(dtrace_hdl_t *dtp, const char *opt, const char *value)
{
    if (-1 == dtrace_setopt(dtp, opt, value)) {
        fprintf(stderr, "Failed to set '%1$s' to '%2$s'.\n", opt, value);
        return (-1);
    }
    return (0);
}

// set all the options, otherwise return an error
int
set_opts(dtrace_hdl_t *dtp)
{
    return (set_opt(dtp, "strsize", "4096")
        | set_opt(dtp, "bufsize", "1m")
        | set_opt(dtp, "aggsize", "1m")
        | set_opt(dtp, "aggrate", "2msec")
        | set_opt(dtp, "arch", "x86_64"));
}

int
main(int argc __attribute__((unused)), char **argv __attribute__((unused)))
{
    int err;
    dtrace_proginfo_t info;
    dtrace_hdl_t *dtp;
    dtrace_prog_t *prog;

    dtp = dtrace_open(DTRACE_VERSION, DTRACE_O_LP64, &err);

    if (dtp == 0) {
        perror("dtrace_open");
        return (1);
    }
    if (-1 == set_opts(dtp))
        return (1);

    prog = dtrace_program_strcompile(dtp, progstr, DTRACE_PROBESPEC_NAME, 0, 0, NULL);
    if (prog == 0) {
        printf("dtrace_program_compile failed\n");
        return (1);
    }
    if (-1 == dtrace_program_exec(dtp, prog, &info)) {
        printf("Failed to dtrace exec.\n");
        return (1);
    }
    if (-1 == dtrace_go(dtp)) {
        fprintf(stderr, "Failed to dtrace_go.\n");
        return (1);
    }

    while(1) {
        int status = dtrace_status(dtp);
        if (status == DTRACE_STATUS_OKAY) {
            dtrace_aggregate_snap(dtp);
            dtrace_aggregate_walk(dtp, aggfun, 0);
        } else if (status != DTRACE_STATUS_NONE) {
            break;
        }
        dtrace_sleep(dtp);
    }

    dtrace_stop(dtp);
    dtrace_close(dtp);
    return (0);
}

My Heart bleeds, truly…

The world has ended! openssl has this terrible bug which allows an attacker to receive a pot-luck of 64k portions of the memory address space of the SSL server. Thing that are up for grabs include usernames, passwords and SSL private keys; i.e. a veritable grab-bag of things that can be obtained from the server.
You should really change your password.

Actually, don’t bother; it’s not like it actually matters in the long run. You’re probably going to change your password from bunny2 to bunny3 anyway and it’s not like that was the most likely point of escape of your password in the first place. It’s probably that toolbar that installed when you installed that video player that was needed to watch that movie; you know the one? The one with the kittens? The one that you never got to see because you got distracted.

It’s been a really bad few months for security, and while people have been pointing fingers in various directions, deploying a Nelson-style ‘Ha Ha’, the only lesson that has been found in this case is that the bible has a great thing to say about this:

Do not gloat when your enemy falls; when they stumble, do not let your heart rejoice, or the Lord will see and disapprove and turn his wrath away from them.

… and then you’re in trouble.

As for me, I’m going to wait a few weeks and then change the passwords that are in any way connected to money. It would be nice if I could get some form of toolbar that would check sites as I go to them in a database and reveal if they were subject to the bug and prompt me to change the password once they’ve been declared clear. Someone get on that; it sounds like a fun project

.

Code to change assert behaviour when running under a debugger

In Linux, you can create a __assert_fail routine which will be triggered when an assert is encountered in code compiled with asserts enabled. Using some debugger detection, you can have the code behave differently in that situation. The code to accomplish detection at load-time looks like:

#include <assert.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/ptrace.h>

static int ptrace_failed;

static int
detect_ptrace(void)
{
    int status, waitrc;

    pid_t child = fork();
    if (child == -1) return -1;
    if (child == 0) {
        if (ptrace(PT_ATTACH, getppid(), 0, 0))
            exit(1);
        do {
            waitrc = waitpid(getppid(), &status, 0);
        } while (waitrc == -1 && errno == EINTR);
        ptrace(PT_DETACH, getppid(), (caddr_t)1, SIGCONT);
        exit(0);
    }
    do {
        waitrc = waitpid(child, &status, 0);
    } while (waitrc == -1 && errno == EINTR);
    return WEXITSTATUS(status);
}

__attribute__((constructor))
static void
detect_debugger(void)
{
    ptrace_failed = detect_ptrace();
}

void __assert_fail(const char * assertion, const char * file, unsigned int line, const char * function) {
    fprintf(stderr, "Assert: %s failed at %s:%d in function %s\n", assertion, file, line, function);
    if (ptrace_failed)
        raise(SIGTRAP);
    else
        abort();
}

This code, because it uses an __attribute__((constructor)) will detect a program being started under a debugger.

You could move the detect_debugger() call into the __assert_fail function, and this provides full run-time detection of the debugger and behaviour alteration. On the assumption that not a lot of asserts() get triggered, you have an effective behaviour alteration of your code when run under a debugger. In this case the __assert_fail looks like:

void __assert_fail(const char * assertion, const char * file, unsigned int line, const char * function) {
    fprintf(stderr, "Assert: %s failed at %s:%d in function %s\n", assertion, file, line, function);
    if (detect_ptrace())
        raise(SIGTRAP);
    else
        abort();
}

ascii progress bars

Sometimes you want to display a progress routine in C/C++, without resorting to termcap/curses. The simplest mechanism you can use is:

for (i = 0; i < 10000; i++){
    printf("\rIn Progress: %d", i/100);
}
printf("\n");

This yields flickering on the display as the cursor moves back and forth over the entire line reprinting it. This gets worse with larger amounts of display data. If your progress routine is simple like this, then you can use another mechanism – the backspace \b, rather than the reset \r. You take advantage of printf reporting the number of characters it displayed as a return code, and then only display the required number of backspace characters.

So for example:

printf("In Progress: ");
int lastprinted = 0;
for (i = 0; i < 10000; i++){
    while (lastprinted--) printf("\b");
    lastprinted = printf("%d", i/100);
}
printf("\n");

This way you get to only print a few characters every refresh, which minimizes the flicker.

The Disappointment of New Features

I’m reading articles on new features in the CSS media queries level 4 spec. Items such as luminosity, which allow you to adjust the styling on your app depending on three grades of environmental brightness. This means you could adjust that bright white as it gets darker, so that it doesn’t blind someone who’s trying to read it in a darkened room (I had this experience this morning when the auto-brightness setting on my nexus decided that full-on-bright was what I needed while triaging my email at 6am, with the lights off).

It’s a pretty nifty feature, and once people start using it we’ll probably all reap the benefit.

The problem is that as of now, it’s pretty much only in a limited set of web browsers. Even though I have a laptop with an ambient lighting sensor, I’ll never see this work properly anytime in the near future.

The next thing I was reading was about making non-rectangular clipping areas for text so that it would flow around images. Looks pretty awesome, and makes things look more like a desktop publishing environment. Only available in Chrome Canary (which means, at the moment, the most bleeding-edge version of Chrome). Which makes it another feature that we have to wait for.

C++11 introduced some nice features such as Lambdas, which allow you to define the work to be done on something in the same place as the request to perform the work. It’s pretty nice as you can in-line work quite easily, whereas in previous languages you relied on an external function, typically with pointers to a data blob… the whole thing was quite tedious and leads to difficult to understand code. Again, you need a modern compiler that understands the C++11 syntax, but once you have it, it’s plain sailing. You ever tried to compile gcc… it’s fun times for all 😉

Again, a new feature, but it generally comes with a whole bunch of things that have to change to support it.

This is where the disappointment comes in. All these shiny features are available on the shiniest of newest systems. As developers, we like having the newest stuff – from operating systems to development environments, to programming languages. They all provide us with the ability to do our jobs better, and in a more efficient manner. It also allows us to royally screw things up much more rapidly, and then fix it so you almost don’t notice that it happened.

That’s not where most of the world lies. Most folks are living in the ‘it got installed, I’m not touching it’ world. It makes things difficult for us developers as we have to match up our work to what functions in their environment. That means we can’t use the newest version of X, because that’s not going to be present on the end-user’s system.

There is a sliver of bright light in the form of the automatic update. If you’re using Google Chrome, or any recent version of Firefox then unless you change something, it will always be silently updating to the newest version behind your back. This means that the next time you start it up, you’ve got the latest and greatest available. All the features are present. Unfortunately, this also means that the changes can trigger failures. This can be caused by a lack of testing, or a lack of backwards compatibility.

When it happens because of a lack of backwards compatibility, then people get genuinely angry – it used to work and now it simply doesn’t, and for no reason whatsoever. On Internet Explorer we have the ‘do the wrong thing’ switch, which causes the browser to act in the old, bad way, so that a user’s experience does not change when they install the newer browser.

I don’t think this is really going anywhere, so I’ll leave it as-is then.

There is a reason that it gets called an interface.

I’ve been writing commercial software since 1996. Since then the Microsoft API for WIN32 has been extended to support the 64bit platform, but most of everything I learned while writing to that platform is just as applicable now as it was back then.

I’ve written apps for the JIRA SOAP API. They work well; as long as the soap interface doesn’t throw a wobbler. It throws a wobbler every effing day now. The SOAP API for Jira has been deprecated for the newer, shiner, REST API.

Fuck you.

Fuck you and your spurious deprecation of APIs because it’s not something that fits into your grand design.

This is not how you write an API.

Dave Winer had it right many years ago with the RSS API. It was really fucking simple, and I wrote a parser for it in ass-clown perl that worked well for everything I wanted it to do. Even when people started to put incorrect entities in their feeds I could deal with it. It still runs, and I’ve not changed it in over 7 years.

Oh no, they say, look at the major version they say, it keeps incrementing and they only have a limited obligation to support something once the major number increments.

Fuck you.

Version number increments are meaningless. When we have a Firefox 17 in January and a Firefox 23 in August, a Chrome 18 in January and a Chrome 28 in August I mean seriously, you’re making a fucking argument here? Every one of those goddamned browsers can still read HTML. They may not all *render* it the same way, but a <div> is a <div> is a fucking <div>.

One of the most stable APIs in computers is the concept of time(). Time is counted as the number of seconds since 12:00, Jan 1, 1970. Many have written alternative APIs for time, but all of them provide some call that allows you to translate that special structure into a number representing the number of seconds since that point in time. That is an API.

I’m full certain that somewhen in the 40th century, some piece of code will depend on a 64bit version of the time() call, and it will work.

You people have no fucking idea how to write an interface.

There is a reason why they call it an interface, it’s meant to be something you can program against for a reasonable amount of time.

Not like Facebook.

Someone asks ‘I like the way python has a None return value for I didn’t find something’

Yes, that’s the title, no, that’s not what it does.

Python’s primary control mechanism is the exception. Nine times out of ten, if something is not found, python throws an exception. If you’re looking for a value and it’s not found, python throws an exception. If it’s Tuesday and your function call expects it to be Thursday, python throws an exception.

The entire language is designed around the fact that an exception is not exceptional, it’s just par for the course. What. The. Fuck.

Python’s None value is the definitive False, it means No, Non, False, Empty, Not there. The only issue with it is that it actually matches on simple equality tests. If you have an ‘if foo’ case, and foo is None, then it matches the false case. This is not right. None means ‘Neither True nor False’, you should be required to test against it explicitly, not be allowed to pass it through from the ‘not True’ case.

SQL has the NULL value, which is a special ‘does not exist’ value, and it doesn’t operate in the usual mechanism. Equality tests against NULL *always* fail – you must check against ‘is NULL’ or ‘is not NULL’, you cannot check against a string or value, it just doesn’t operate in that way.

The fact that python uses exceptions when it doesn’t find a value is because of the weakness of the None value, it doesn’t act like NULL, it acts like False, and that is lame.

How to ruin the lines of your device

Ultrabook With VGA portSo this is a screen grab from the Microsoft store of a Sony Ultrabook. For some odd reason, this UltraBook has a VGA port. It doesn’t look too hideous when you’re looking at it from this angle, but once you get into the store and have a gander at the device, the VGA port is this ugly looking port jutting out of the side of your machine.

It’s adjacent to an HDMI port.

I’d even recommend using a DisplayPort port before putting a damned VGA port. DisplayPort has adaptors for DVI, HDMI and VGA.

I’d much prefer to have to carry around an adaptor for the laptop rather than have such an ugly port ruining the lines of my UltraBook.

Then the VAIO DUO laptop, which has a touch screen and a slide-up keyboard; reminding me of those odd phones from the past. It too has a fugly VGA port on the side, while including a HDMI port and two USB 3.0 ports.

W.T.F. Sony, seriously, I do realize that everything is driven from the hardware team, but get back to them with the message that the 80’s called and they want their VGA port back.

Knee jerk reactions to closed source software being purchased

Most of my work is closed source – it’s been done within/for companies that have no real interest in releasing the software to the wide community.

There is one primary reason for this – a lot of the power in the software is directly tied into the software itself – things are done that are difficult or tricky. The trick is in the doing, and it gives us a competitive advantage when selling, and gives our customers an advantage against their competitors that use the oppositions’ solution.

I love open source software – it means that I’ve got a huge amount of software that I can draw on to get things accomplished that I don’t have to pay a metric ass-ton of money for so I can get my work done. If open source software did not exist, I would be missing tools like flex, bison, perl, python, ruby and bash all of which get my job done.

But I still use closed source software – java (from snoracle), but there is a huge layer of open source software that we’re using to get the language itself to do the things we need it to do.

So, I read an article that mentions ‘Sparrow’s acquisition highlights the dangers of closed source’ which highlights that there were some bad reactions to the software being purchased.

To those people, I will have to say tough shit. I’ve been shafted year on year by proprietary software companies for the last 30 years. You have no entitlement to updates, you have no entitlement to new major versions. If I bought a car and the newer one came out the next year, would I expect to get the newer one automatically? No, I would not. Yet, for some reason, people expect the newest, shiniest version of the software they bought 5+ years ago. If you want the free upgrade train then hook yourself up with Debian, who have a very strong opinion on proprietary/closed source software, otherwise understand that you only paid for a pass for the train system now, not the jetpack and hovertrain system that will exist in the future.

I use open source software when I can. The reasons are simple. It’s pretty well documented if you can understand nerd, and it generally does what I want it to do without any complaints; and if it doesn’t then I have the facility to mess with it in whatever way I want to get the results I want without issue. All the changes I have made to open source software are available openly. As required by some of the licenses, but I make them available for all pieces of software I modify because #1, I’m not a prick (#2 is because it complies with most of the licenses).

I’d love it if all software was open source – it would make my life easier as I’d be able to use solutions to problems that I need whenever I wanted, using the best solution available. I work on such exciting projects as ‘PAM authentication for TACACS+ users’ that I’m sure there’s a huge, burgeoning community of like minded individuals that need this problem solved. Like f**k there is – I work on topics where there is probably 2 people (external to work) who actually care about the changes I make.

The perils of closed source software are simple – no real user actually cares if it’s open source or closed source. If it’s broken, then they bitch. They have no interest in how it’s broken or why; they just want it to work.