• Mike (unregistered) in reply to Anon
    Anon:
    Now some moron is bound to copy it and put it in their code without understanding that they are supposed to generate their own. Pretty much guarantees a collision.
    This is why every developer needs a reliable tool to generate guids.

    Speaking of which, for anyone searching for the guidgen tool, here it is. Copy and paste the following into a file named "guidgen", chmod +x, and run it.

    #!/bin/sh
    echo "{16AA8FB8-4A98-4757-B7A5-0FF22C0A6E33}"
    

    You're welcome, internet.

  • BentFranklin (unregistered)

    Sequential GUIDs can create collisions further on down the line in hashtables:

    http://feuerthoughts.blogspot.com/2006/02/watch-out-for-sequential-oracle-guids.html

  • Spearhavoc! (unregistered) in reply to Anonymous
    Anonymous:
    PS:
    TheCPUWizard:
    Actually the odds become measurable when you start generating a few billion and need them all to be unique against each other. Over the past 5 years, I have 2 confirmed cases of database "corruption" caused by using GUIDS as keeys, and the foolish developers believing that they were guaranteed unique...

    Which, actually, isn't that surprising: http://en.wikipedia.org/wiki/Birthday_paradox

    I was going to break out the birthday "paradox" (quoted because it is not actually a paradox) but as I said to the last guy, I'm not getting into this discussion because I don't know what I'm talking about. This is exactly what the birthday "paradox" highlights - the fact that my knowledge is very often misguided when it comes to probability (I have a keen interest in quantum physics so probability is something I've fought with for years).

    FTFY

  • (cs) in reply to Mike
    Mike:
    Anon:
    Now some moron is bound to copy it and put it in their code without understanding that they are supposed to generate their own. Pretty much guarantees a collision.
    This is why every developer needs a reliable tool to generate guids.

    You're right. For me, I use this niftly little trick in Eclipse: Create an empty class that implements Serializable. Use the quickfix "Add generated serial version ID" for the warning "The serializable class SomeClass does not declare a static final serialVersionUID field of type long"

    The value of your brand new UUID is now in the field serialVersionUID.

  • jonny_q (unregistered) in reply to TheCPUWizard

    It's the birthday problem.

    The odds of a particular GUID matching another are almost nil. The odds of a pool of a couple billion GUIDs containing two that match are much higher.

  • (cs)

    All this busy talk about GUIDs and only one guy so far has complained about loading a DLL from a resource?? What's up with that?

    Seriously, having a DLL stored in a resource and writing that to a file at runtime is NOT "actually a pretty clever technique", it certainly is THE REAL WTF in all upper case.

  • Starfarer42 (unregistered) in reply to BentFranklin
    BentFranklin:
    Sequential GUIDs can create collisions further on down the line in hashtables
    That's not a problem with the GUIDs though.

    The pigeon hole problem shows that hash collisions are unavoidable, even with well distributed keys. Therefore any code that relies on hashes being unique is broken and ought to be fixed. (And no, changing the hash algorithm so that you don't happen to get any collisions in your test data isn't a proper fix.)

  • John Evans (unregistered)

    Lampshade, Alex. Hanging a Lampshade.

  • (cs)

    Dear Sybase,

    In case you can't tell, bla, bla, bla modal dialog boxes.

    Sincerely,

    Bert Glanstron

    P.S. I'm surprised nobody thought of this.

  • ÃÆâ€â„ (unregistered)

    Damn, Alex just pwned whoever wrote that part of the code. And all Remy Martin can do is add gay unicorns and rainbows to his articles...

  • wtf (unregistered) in reply to frits
    frits:
    Dear Sybase,

    In case you can't tell, bla, bla, bla modal dialog boxes.

    Sincerely,

    Bert Glanstron

    P.S. I'm surprised nobody thought of this.

    I'm very, very disappointed in you, frits.

    Pray I don't get any more disappointed.

  • Ed (unregistered)

    Ok, you're great and all Alex, but really, comments like this?

    // loop over each directory in the array

    C'mon, what is this, intro to C# 101? I think any programmer out there can recognize a loop when they see one.


    ...oh yeah, on topic... modal dialogs suck.

  • John Muller (unregistered)

    old dial-up-networking 'adapters' all had the same mac address, increasing the odds of a collision, since that part was no longer unique.

    As for incrementing from a known GUID, one problem with that is the classic read-modify-write multithreadinh ole, when Thread a reads; thread b reads, they both add 1 to their value, then both write the same value; two increments were performed; but the final value only changed by one.

    You could wrap that operation is a lock, but I wouldn't be surprised if a locking operation of a enterprise-scale database server was... a performance problem. however, for all I know, the standard GUID generation function might do some locking internally to alleviate the next probelm.

    Maybe, MAYBE, you could get away with each thread picking a starting GUID, and incrementing from that. But, with the 'old' guid generation method, if two GUID's were generated within the same clock tick, on the same machine, they might only differ by a small amount; because the final fallback to prevent duplication is to increment some bits (probably the lowest...)

    So, at that point, you might as well just use your own GUID-sized values, and break it up into

    for example: set the first two bits to '00', to allow versioning of this schema 20 'machine ID bits' (unique in your machine pool, never reused for new machines) 20 'process ID' bits (unique on a given machine, never reused), 20 'thread ID' bit, (unique within a process) and the rest starting from a random point an incrementing (or decrementing, or increasing/decreasing by any prime number modulus 2^64...

    Oh, and to the Origional author, did you try putting the DLL in the Path environment variable?, maybe adding the Database library folder to the path?

  • (cs)
    or the fact that this is thrown from an impossible to try-catch static constuctor

    WTH does that mean?

  • Gunslinger (unregistered) in reply to Matt
    Matt:
    The Ral WTF is loading a dll from the current working directory. http://support.microsoft.com/kb/2389418

    Who is Ral and how do I get his newsletter?

  • LANMind (unregistered)

    What's the big deal? Some cowboy probably stuck the dialog in the code while testing and debuging the code and just forgot or missed this one. Since this is driver code, maybe TRWTF is their QA process?

  • Anon (unregistered) in reply to John Evans
    John Evans:
    Lampshade, Alex. Hanging a Lampshade.

    You might want to read the rest of the article you linked to:

    TFA:
    This practice is also known as "hanging a clock on it", "hanging a lantern on it", or "spotlighting it".
  • JCS (unregistered)

    See related comments here http://sqla.stackexchange.com/questions/1422/dear-sybase-messageboxes-dont-belong-in-drivers

  • Wow (unregistered) in reply to ThingGuy McGuyThing
    ThingGuy McGuyThing:
    Anonymous:
    A Nonny Mouse:
    Anonymous:
    This is a great change to the usual WTFs, both in content and writing style. I like it a lot. I especially liked your use of a GUID that you "could not find anyone else using". Genius, pure genius. This actually hints at a WTF I've been expecting for years but have never actually witnessed (note to DBAs: if you generate GUIDs sequentially they're not GUIDs anymore).

    FYI, I have now used this GUID in my current application so it is no longer globally unique. Sorry.

    huh? what difference does it make if you are generating them sequentially? they still have the same chance of being unique as if you were generating them non-sequentially
    That's exactly what my DBA said, right before I fired the incompetant moron. I'm not going into this now because it's only going to get deleted for being off-topic - you'll just have to wait until we get a real sequential GUID WTF.

    I wish you would go into this. I did a quick Google search and couldn't find any reason why sequential GUIDs are any more likely to collide than non-sequential. Perhaps you could enlighten me?

    (captcha: ludus - it's never ludus.

    What happens if two people ascribe to the sequential GUID line of thought?

  • wtf (unregistered) in reply to Wow
    Wow:
    ThingGuy McGuyThing:
    Anonymous:
    A Nonny Mouse:
    Anonymous:
    This is a great change to the usual WTFs, both in content and writing style. I like it a lot. I especially liked your use of a GUID that you "could not find anyone else using". Genius, pure genius. This actually hints at a WTF I've been expecting for years but have never actually witnessed (note to DBAs: if you generate GUIDs sequentially they're not GUIDs anymore).

    FYI, I have now used this GUID in my current application so it is no longer globally unique. Sorry.

    huh? what difference does it make if you are generating them sequentially? they still have the same chance of being unique as if you were generating them non-sequentially
    That's exactly what my DBA said, right before I fired the incompetant moron. I'm not going into this now because it's only going to get deleted for being off-topic - you'll just have to wait until we get a real sequential GUID WTF.

    I wish you would go into this. I did a quick Google search and couldn't find any reason why sequential GUIDs are any more likely to collide than non-sequential. Perhaps you could enlighten me?

    (captcha: ludus - it's never ludus.

    What happens if two people ascribe to the sequential GUID line of thought?

    Depends on the separation between their chosen starting points and the number of GUIDs the lower starter picks.

  • Tharg (unregistered)

    You wouldn't be firing this DBA for using sequential GUID's, as I just use guaranteed-not-to-repeat integers for my primary keys.

    GUID's have no part in a relational database that is using surrogate integers for primary keys.

    I have no trouble whatsoever in guaranteeing uniqueness of my key values. If as a DBA, some numpty of a developer (who should be dismissed instantly for suggesting the use of a GUID) insists on using GUID's, then that's a problem of his own making. Oh, and just so you get the subtle hint, beating up on the DBA's won't fix it.

  • (cs)

    I was just laughing at this exact mistake one of my (former) developers made - executing a modal dialog from a back-end inventory update service.

  • (cs) in reply to Tharg
    Tharg:
    You wouldn't be firing this DBA for using sequential GUID's, as I just use guaranteed-not-to-repeat integers for my primary keys.
    What a brillant idea! Just think of the flexibility, such as when you have to merge that table into another one with the same identity scheme :).
  • TheCPUWizard (unregistered) in reply to Anonymous

    [quote user="AnonymousWhich, actually, isn't that surprising: http://en.wikipedia.org/wiki/Birthday_paradox[/quote] I was going to break out the birthday "paradox" (quoted because it is not actually a paradox) but as I said to the last guy, I'm not getting into this discussion because it is completely off-topic and almost impossible to explain to someone in a forum like this. This is exactly what the birthday "paradox" highlights - the fact that human intuition is very often misguided when it comes to probability (I have a keen interest in quantum physics so probability is something I've fought with for years).[/quote] Given that my original degree was to be in Physics (specifically High Energy Plasma) Quantum physics is also high on my list....It should only take a few minutes to determine my real iddentity and contact info if you want to talk about this further.....

  • (cs) in reply to Spectre
    Spectre:
    or the fact that this is thrown from an impossible to try-catch static constuctor
    WTH does that mean?
    Agreed.
  • Brendan (unregistered) in reply to BentFranklin

    Hi,

    BentFranklin:
    Sequential GUIDs can create collisions further on down the line in hashtables:

    If you can't use the least significant bits for that hash; then reverse the order bits while generating the GUIDs such that the LSB becomes MSB, etc (e.g. using 32-bit because I'm lazy: 0 -> 0x00000000, 1 -> 0x80000000, 2 -> 0x40000000, 3 -> 0xC0000000, 4 -> 0x20000000, 5 -> 0xA0000000, 6 -> 0xE0000000, 7 -> 0xE0000000, ....).

    That way you minimise the chance of hash collisions.

    To prove I'm not a bot: the word you see in the image

  • Anonymous (unregistered) in reply to wtf
    wtf:
    ThingGuy McGuyThing:
    I wish you would go into this. I did a quick Google search and couldn't find any reason why sequential GUIDs are any more likely to collide than non-sequential. Perhaps you could enlighten me?

    I'm curious about this as well - not that I doubt the statement, I just don't see where it comes from. (an actual, sincere, non-snarky question? on this site? Oh, come on!)

    Since there seems to be some genuine interest I feel I should explain my comments in regard to sequential GUIDs. First let me make it clear that using sequential GUIDs isn't an issue if they only need to be internally unique, so no disrespect to DBAs implementing internal strategies. Of course, the point of a GUID is that it is globally unique, as in only one in the whole world now or ever.

    This is the very definition of a GUID - it's a globally unique identifier. The original principle behind it was that it would be truly unique - generated based on the computer's MAC address and a current timestamp, such that it should be impossible to create a collision without subverting the algorithm or the system on which is was run. This is no longer the case as the revised specification drops the MAC address part for security reasons. So now GUIDs are generated from the timestamp without the entropy provided by a unique MAC address. This already means that GUIDs are not truly globally unique, since it is possible for the same GUID to be generated on different machines. So, we have lost a valuable source of entropy but it is still very unlikely that a collision will occur.

    Now consider sequential GUIDs. The last source of entropy, the timestamp, is removed from the equation and GUIDs are now simply an incrementing number. There is no randomisation other than the starting point. The fundamental principle that makes a globally unique identifier unique has been removed.

    Tharg said it absolutely right above - if you are using GUIDs as an internally unique identifer and you manage that properly then there is no risk in using an incrementing GUID strategy. But the fact is that as soon as you generate GUIDs sequentially they cease to be globally unique. And it's amazing how many developers just cannot fathom that idea.

    An honourable mention to the Birthday "paradox" since that does apply to this scenario as well but that's somewhat beside the point when considering sequential GUIDs. A sequential GUID is no different to an arbitrary 32 character hex string - it lacks the "GU" part of "GUID".

    Anyway, I said I wasn't going to get into this...

  • (cs) in reply to Anonymous

    Tharg did not limit his GUID-hate to sequential ones, unless I misread him.

  • (cs) in reply to John Muller
    John Muller:
    As for incrementing from a known GUID, one problem with that is the classic read-modify-write multithreadinh ole, when Thread a reads; thread b reads, they both add 1 to their value, then both write the same value; two increments were performed; but the final value only changed by one.
    System.Threading.Interlocked
  • TJones (unregistered)

    "awry UI"

    We would have also accepted "UI gone wild."

  • Steve Parker (unregistered)

    I enjoy reading this site, as many things apply to all architectures. However, as a Unix/Linux geek, the idea that an entire server-side application would stop for user interaction is inconceivable.

    I appreciate that this is the exact same frustration that the poster is venting, but isn't it obvious that the GUI and the OS have no correlation whatsoever?

    So, TRWTF must be using an OS which cannot distinguish between a user and an application.

    This is why we get all these pictures of ATMs showing "new hardware attached" dialogs, Departure boards showing BSODs, etc - Windows needs to be reengineered from the ground up to be usable in such situations.

    Oh, wait - we already did that for you, decades ago, and open sourced most of it, too, so that you could (if you want to) join in the [r]evolution.

  • (cs)

    In all this chat about JPUIDs, has no one noticed that alex's solution to 'I cannot find this dll I have already loaded' is to use a IHIWBUID (I hope it will be..), make a directory from it, and write the DLL out to the filesystem so I can load it!

  • spongeboy (unregistered)

    Keep your code beautiful - only use Hot GUIDs: http://secretgeek.net/hotguids/

    (Also, one person's "global" is another's "local". Why can't I can't access my Perl script global variables from my C# program? They should be accessible from anywhere on the globe, or why else would they be called "global", wiseguy?)

  • PRMan (unregistered) in reply to Anon

    "Of course, the worst thing you can do with a GUID is put it on the internet. Now some moron is bound to copy it and put it in their code without understanding that they are supposed to generate their own. Pretty much guarantees a collision. "

    That's why you put your competitor's GUID in your code on the web... </Devious>

  • (cs) in reply to Steve Parker
    Steve Parker:
    I enjoy reading this site, as many things apply to all architectures. However, as a Unix/Linux geek, the idea that an entire server-side application would stop for user interaction is inconceivable.

    I appreciate that this is the exact same frustration that the poster is venting, but isn't it obvious that the GUI and the OS have no correlation whatsoever?

    So, TRWTF must be using an OS which cannot distinguish between a user and an application.

    It's got nothing to do with the OS. Some moron had to do something like:

    System.Windows.Forms.MessageBox.Show("I'm an idiot");

    or

    int msgboxID = MessageBox( NULL, (LPCWSTR)L"I'm an idiot", (LPCWSTR)L"Me", MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2);

    In other words, somebody explicitly invoked a user interface API to raise a modal dialog box from a library. The only reason idiots don't make this mistake on Linux is that there is no universal GUI API. It's so easy on Windows that it's often abused. The root of the problem is that Windows can tell the difference between a user and an application and doesn't show the window to anybody. However, the API does wait for input because that's what the spec says it should do.

    Imagine for a minute that every Linux install came with X.org and Gnome. Then, somebody wrote a standard library to raise a dialog that always worked (it even fell back to ncurses in the case that X wasn't available) and it was included with every Linux distribution. After a while, everyone would get used to it being there and it would get a lot of use. Now, the stage would be set for morons to start calling it from cron jobs and daemons.

  • (cs)

    I have a solution to the GUID collision problem. Use two GUIDs. I've just decreased the likelihood of a collision by a factor of GUID.

    Done and done.

  • (cs) in reply to Steve Parker
    Steve Parker:
    Oh, wait - we already did that for you, decades ago, and open sourced most of it, too, so that you could (if you want to) join in the (r)evolution.

    Good too see you've drunk the Kool-Aid, now direct yourself towards the TM Repository and peer at yourself in the mirror.

  • Kasper (unregistered) in reply to Anon
    Anon:
    Of course, the worst thing you can do with a GUID is put it on the internet. Now some moron is bound to copy it and put it in their code without understanding that they are supposed to generate their own.
    For some use cases you could solve this kind of problem by making the GUID a public key or the hash of a public key and then require whatever uses the GUID to come signed under the corresponding private key.
  • (cs) in reply to Anonymous
    Anonymous:
    wtf:
    ThingGuy McGuyThing:
    I wish you would go into this. I did a quick Google search and couldn't find any reason why sequential GUIDs are any more likely to collide than non-sequential. Perhaps you could enlighten me?

    I'm curious about this as well - not that I doubt the statement, I just don't see where it comes from. (an actual, sincere, non-snarky question? on this site? Oh, come on!)

    Since there seems to be some genuine interest I feel I should explain my comments in regard to sequential GUIDs. First let me make it clear that using sequential GUIDs isn't an issue if they only need to be internally unique, so no disrespect to DBAs implementing internal strategies. Of course, the point of a GUID is that it is globally unique, as in only one in the whole world now or ever.

    This is the very definition of a GUID - it's a globally unique identifier. The original principle behind it was that it would be truly unique - generated based on the computer's MAC address and a current timestamp, such that it should be impossible to create a collision without subverting the algorithm or the system on which is was run. This is no longer the case as the revised specification drops the MAC address part for security reasons. So now GUIDs are generated from the timestamp without the entropy provided by a unique MAC address. This already means that GUIDs are not truly globally unique, since it is possible for the same GUID to be generated on different machines. So, we have lost a valuable source of entropy but it is still very unlikely that a collision will occur.

    Now consider sequential GUIDs. The last source of entropy, the timestamp, is removed from the equation and GUIDs are now simply an incrementing number. There is no randomisation other than the starting point. The fundamental principle that makes a globally unique identifier unique has been removed.

    Tharg said it absolutely right above - if you are using GUIDs as an internally unique identifer and you manage that properly then there is no risk in using an incrementing GUID strategy. But the fact is that as soon as you generate GUIDs sequentially they cease to be globally unique. And it's amazing how many developers just cannot fathom that idea.

    An honourable mention to the Birthday "paradox" since that does apply to this scenario as well but that's somewhat beside the point when considering sequential GUIDs. A sequential GUID is no different to an arbitrary 32 character hex string - it lacks the "GU" part of "GUID".

    Anyway, I said I wasn't going to get into this...

    cool, thanks for the explanation. i didn't realise the MAC address was no longer used, so i have learned something today. in theory though, with the MAC address generation, the sequential/non-sequential part doesn't make a difference (in theory communism works. in theory)

  • Jimmy Jones (unregistered) in reply to frits
    frits:
    // GUID generated 2009-08-24; could not find anyone else using it "{16AA8FB8-4A98-4757-B7A5-0FF22C0A6E33}");

    Hilarious! I see this all the time. Is it really so costly to generate GUIDs in your program?

    GUIDs contain your MAC address so if you want to avoid collisions with other GUIDs it's best to generate them on your machine, not the user's.

  • (cs)

    You know what bothers me? This:

    Alex:
                        Directory.CreateDirectory(realBasePath);
                        CreateDll(); 
    

    I don't know if that's an artifact of Alex's authoring the article or whether it's actually in the code like that. If it's the latter, that's another big WTF right there.

    I mean, think about it: they go through all the trouble of creating a "somewhat unique-ish" directory, have the path for it in a local variable, and then they call a method without parameters, i.e. one that can't know about the directory which was just created for its purpose.

    That means the method now has to figure out a suitable location for the DLL on it's own: either by carrying out again very much the same steps that have just been done (maybe minus the actual directory creation, but most likely by building the same paths from the same fragments), or dropping the DLL just about anywhere it likes, ignoring the directory that was created for it. Either way, WTF?

  • Olius (unregistered)

    Two things Alex...

    1. Why not use a proper, free database - MySQL, Postgres, Ingres, etc etc? You can bind to these from any language, even using odbc if there is no other option. I'll assume it was someone else's choice and you're maintaining the software, I guess.

    2. Why stick by a language, set of libraries, set of software which forces you to go out of your way to quash errors which would result in UI dialog boxes? I can't imagine any kind of environment which would accidentally create gui components when you're writing a server process. But then again, I don't touch Windows, let alone .Net.

    But I'm not taking the mic here, I'm genuinely interested in your answers.

  • Swedish tard (unregistered)

    WTF is up with all the people here that thinks that MAC adresses are in any way unique? Even the same line of cards from the same manufacturer can ahve collisions in MAC adresses. Depending on the uniqueness of MAC adresses for generating unique GUIDs... I mean, come on!

  • Vollhorst (unregistered)

    It is not so clever to post openely that you have broken the law by decompiling a program which you don't have the rights to...

  • Bob (unregistered) in reply to no name
    no name:
    If your source of entropy is good enough (and my calculations are correct), the chances of two GUIDs colliding are 1 in 340 billion billion billion billion. Or 1 / (the Irish national debt) ;-)

    Note to anyone reading this on or after November 16: the value of "the Irish national debt" given above is no longer accurate. Thank you for your attention.

    CAPTCHA: enim (n), landfill.

  • Anonymous Sybase user (unregistered)

    If thats the biggest problem you've found in the SQL Anywhere .NET DLL then you're very very lucky.

    Locked up connections & access violations are not much fun.

    Telling them about reflector is not a good idea as they might be tempted to obsfucate the code. Then it will be harder to track their memory leaks for them etc.

  • hoodaticus (unregistered)

    Okay, now I get what Alex was saying about try-catch. He didn't mean it's impossible to try-catch the constructor; he meant that the catch won't actually be able to recover and get the constructor to return an object.

  • hoodaticus (unregistered) in reply to Soviut
    Soviut:
    Steve Parker:
    Oh, wait - we already did that for you, decades ago, and open sourced most of it, too, so that you could (if you want to) join in the (r)evolution.

    Good too see you've drunk the Kool-Aid, now direct yourself towards the TM Repository and peer at yourself in the mirror.

    Thanks for the linkage! Great site!

  • pecus (unregistered) in reply to no name
    no name:
    In fact, it is quite surprising, as you would know if you read the article you linked to in detail. If you look at the probability table halfway through the article, you can see that you need 2.6E16 elements just to get a one-in-a-million chance of a collision. That's an awful lot of elements for a very very small chance.

    I read that as: If you expect a million datasets, you'd better allow more than 2.6E16 values for your randomly generated GUIDs, or you'll likely have at least one collision in your DB.

    Next, remember to upgrade your GUIDs when you pass the million-record mark.

    Finally, we all know that one-in-a-million chances have a 50:50 probability of occurring in everyday life.

  • Your Retarded (unregistered)

    Worse than what? Methinks you meant 'WORST'.

Leave a comment on “Dear Sybase: MessageBoxes Don’t Belong In Drivers”

Log In or post as a guest

Replying to comment #:

« Return to Article