syntax highlight

Showing posts with label Grumpy. Show all posts
Showing posts with label Grumpy. Show all posts

Saturday, 3 August 2019

std::is_constant_evaluated: make debugging a little bit harder for yourself!

Let's pretend you find this:

const int a = foo();
int b = foo();

Would you be tempted to assume that a==b, always? I would. What if 'foo' actually depends on a global variable, and its return value depends on that global setting? Suddenly the code above will raise a few eyebrows in a code review session.

Coming to your friendly c++20 standard now:

constexpr int foo() { 
    return (std::is_constant_evaluated())? 42 : 24;
}

bool a() {
    const int x = foo();
    return x == foo();
}

I'm sure with careful usage, is_constant_evaluated will allow library writers to create much more performant code. I'm also sure I'll lose a lot of hair trying to figure out why my debug code (cout << foo(), anyone?) prints different values than my `production` code.

Tuesday, 2 October 2018

std::byte - great idea. Meh execution?

I love the idea of C++17's std::byte. A data-type that makes it explicit we're dealing with ugly low-level details? What's there not to love! One thing only, turns out.

First, the good part: separating character (human) representation from binary (low-level) representation is brilliant. No implicit conversion between the two separates the domains very well and creates a much clearer interface.

The bad part: std::byte is really really strict. It only accepts other std::bytes as operands(*). You'd hope this would work

auto f() {
  byte b{42};
  return b & 0b11;
}

It doesn't. std::byte only accepts other std::byte's as operands. The design goal behind it is good, sure. In practice, I've noticed this means casts are not limited to the interface between low-level and rest-of-the-world: casts and explicit byte's get sprinkled all over the place.

My prediction: most people will dislike the boilerplate std::byte adds and fall back to unsinged char's, until the type restrictions in std::byte are relaxed. I hope I'm wrong though!

(*) Yes, with the exception of shift operations. That was a good design decision!

Thursday, 8 December 2016

Things you should never do

I think I may start a new series in my "Rants" category: things you shouldn't do. First one: Never ever use "strange" characters on your wifi's AP name, where strange is defined as non-ascii. I made the huge mistake of choosing a name with an ñ on it, then had to spend an entire evening hacking on a printer driver with no unicode support. No, I couldn't have changed the AP's name. That would have required me to physically connect a computer to my router, and I was too lazy to get up from the couch.

Tuesday, 6 December 2016

Self reminder: setting the default boot option in UEFI

Bought a new laptop (*) and I'm 100% sure I'll forget this if I don't put it here:

From http://askubuntu.com/questions/291905/how-can-i-make-ubuntu-the-default-boot-option-on-a-newer-laptop-uefi

To set Ubuntu as the default boot OS in a multi-OS setup (ie, dual boot Windows) with UEFI, goto Windows and exec (as admin) bcdedit /set {bootmgr} path \EFI\ubuntu\grubx64.efi

Why am I using Windows, you may ask? I'm still in the process of discovering which features will be broken and which hardware will work out of the box. So far I'm actually quite surprised, with only the video card and the touchpad not working. Luckily bash doesn't use either of those. Who needs a mouse anyway?

Tuesday, 15 November 2016

Ageing Stack overflow?

Hacking away on a little side project of mine, I found myself checking Stack Overflow for implementation tips about things I don't usually work with. Android UI stuff, mostly, which apparently is a very dynamic and ever changing ecosystem. After more than a few wasted hours, I noticed a worrying trend: in SO, answers tend to age horribly. If you are looking for "How to do X in platform Y", you may find a 4 year old answer that solves the problem, but only for platform Y, version "ancient".

Information ageing is quite a problem on its own. The answer is still valid, and, for people working on that specific platform, probably relevant. This will make it the first answer, leaving a lot of people (like myself) frustrated because the solution won't work in newer platforms. Is there a solution? Implement some kind of ageing time-window for information? Make the date a more prominent search parameter? Explicitly specify your platform and environment's version when asking a question? I have no idea.

While Stack Overflow seems to exacerbate the issue, this is a problem even for products with a company actively maintaining their documentation. A very annoying example; looking for ways to manage the media key I ended up in a page which (as of August 2016) points to a very outdated API (registerMediaButtonEventReceiver, in case you are wondering). If even Google encounters problems when managing documentation ageing for their own products, what can we expect of people like us, who only have a tiny fraction of that budget?

/Rant

Wednesday, 15 June 2016

Shared pointers: don't

Ahh, shared pointers! A nice, magical pointer type that will make all of your memory problems go away. Sprinkle some shared_ptrs here and there and, voilà, Valgrind is now happy. Sounds like a silver bullet, doesn't it? That should be your first clue that something's up with the promise of getting Java-like memory management in your c++ application.

Java and C(++) have a very different concept of memory management. My Java-foo, obviously enough to anyone reading this blog, is not that great, but, from experience, memory management is seen as a chore better left to the bowels of your system, something you don't need (nor want) to care about. Sure, you can tweak and somewhat manage memory allocations if you really want to; the default mindset, however, is to ignore those concerns. The garbage collector will, eventually, find any unused resource and deal with it accordingly.

C++ programs, at least those that have been more or less successfully designed as opposed to organically grown, tend to have a radically different approach. Memory management is an integral part of a program's design and it can't be left to some automagic memory manager. This leads, again, for those more or less successful designs, to programs with a tree-like hierarchy in which a child or dependent object must live at least as long as its parent scope. This hierarchy leads to easier to understand programs. Some idioms (RAII!) depend on this hierarchy. Some tools (like scoped and unique pointers) make its implementation much simpler. I've seen that Rust really builds on this idea (and seems to take it to 11! I'm still trying to figure out if that's a good or a bad thing, but so far I quite like it).

The tree-like structure of the scopes in C++ also implies single ownership (again something Rust seems to be very idiosyncratic about). While you may "use" someone else's objects (for example, via a reference) there is always one single owner. If this owner goes away while someone holds a reference to one of its children... well, you get a bug. But sure enough this bug is clear as long as you can visualize the tree scope structure of your program. Shared pointers completely obliterate this tree.

A shared pointer means an object can have multiple owners. Whoever goes out of scope last needs to clean it. Why is that bad? In my (highly subjective but experience based) opinion:

  • It becomes harder to reason about your program. You never know if all the "pieces" you need are in scope. Is an object already initialized? Who is responsible for building it? If you call a method with side effects, will any of the other owners be affected by it?
  • It becomes harder to predict whether going out of scope is trivial, or an operation that can take a minute. If you're the last one holding a reference to an object through a shared pointer, you may be stuck running its destructor for a long time. That's not necessarily a bad thing, but not being able to predict it can lead to all sort of obscure bugs.

There are also many ways to avoid shared pointer usage:

  • Try restructuring your code. This will usually yield the biggest benefits, you'll end up with a clearer structure and less clutter.
  • Try to use scoped pointers from boost or unique pointers if you can. Way too often shared pointers are used when a scoped pointer would be enough.
  • Don't be scared of copies! Sometimes you can just copy your object and end up with cleaner (and maybe even faster) code. Are you really sure you need to share state?

Does that mean you should never ever use shared pointers? Of course not. In some cases it's unavoidable. Some algorithms are probably impossible to implement without them (or even impossible without GC). A shared pointer is just one more tool. Just like gotos. And, just like gotos - although not quite as dangerous - they have some appropriate use cases. Just try not to make it your default goto (lol) tool for memory management.

// TODO: There is a very good reason I found to use shared pointers: to create weak_ptr's. Is there a good solution without actually using shared_ptr's? I don't know!

Tuesday, 5 April 2016

Ubuntu 15.10: Ubuntu ME

Warning: semi-useless rant ahead. TL;DR: Avoid Ubuntu 15.10 - it's the closest Linux has ever been to Windows ME.

I have been using Ubuntu for a while now. From the time when Canonical actually mailed real, physical CDs of the distro. So get of my lawn.

In all of my Linux years I have never, ever, had such a horrible installation experience as I did this weekend with Ubuntu 15.10. I may go as far as saying not even Windows ME was this horrible to install. I hit dozens of critical show-stopper bugs, from poor UEFI support to an installer that crashed when clicking "Go back". And that's only the installation, don't get me started on the new KDE Plasma 5 desktop... (hint: my big desktop screen is NOT a phone. Swiping to login? Bad idea for a mouse).

A few hints for any other poor souls that made the fatal mistake of installing Ubuntu ME:

  • UEFI? Say no. Get a different computer if you can. Try to set it in legacy mode if you can not.
  • Try not to repartition and install Ubuntu on the same go. Even more so if you have UEFI. First install, then rearrange partitions with a live cd.
  • If you get a few (or a few dozen) "system crash notifications" when starting up your GUI, check /var/crash. Delete everything from there.
  • If you want Kubuntu, don't install Ubuntu and then apt-get install kubuntu-desktop. That's broken. If you want Kubuntu just get its install image.
  • Don't install Kubuntu. Really, it's horrible and it crashes. (You though I called 15.10 Ubuntu ME for no reason?)
  • Don't like Gnome? XFCE is usable and can be configured to look more or less like a sane version of KDE. It still crashes but at least it's quick to boot.
  • If you get a disk check on every startup just disable it on fstab. No, it's not nice. I haven't found any other workarounds yet.
I have no idea when has Ubuntu gone so horribly bad, but I'm not looking forward to installing any Ubuntu distro anytime soon. I wonder what Slackware looks like these days.

2016? Still not the year of the Linux desktop.

Update: XFCE is great... except it doesn't really support moving the mouse. Seems Ubuntu is having a nostalgic release and decided to introduce old bugs from 2012!

Tuesday, 22 October 2013

Some gratuitous MSVC bashing

Recently I found out Microsoft's Visual Studio doesn't support alternative tokens (ie "and" instead of "&&"). Even worse than that, apparently they don't think it's even necessary. And by the looks of this thread, the people working on MSVC need to take some time to actually READ the cpp standard. You know... it's kind of like a spec for your product. It's always good to take some time to understand the specs for your product...

I can only imagine how incredibly ugly their lexer must be to say it's not a fixable problem.

Thursday, 18 April 2013

Learning misspells: thanks Vim!

I just noticed a very silly "pattern" I usually fall into: since I like vim (perhaps a bit too much) to work with text, even free-form text like this blog post, most of the times I type a lot of text which then must be spell checked (so far I haven't found a spell checking extension I like for vim). While spell checking I correct the original text in vim, and to do this I usually search for the mispel in Vim, thus typing the wrong spelling one more time. This has the side effect of reinforcing the bad spell instead of forcing me to type the correct spelling.

I wonder how can I fix this problem without a spellchecker for vim.

Thursday, 1 November 2012

stlfilt: read ugly tmpl errors

There's nothing better for Monday mornings than the smell of hundreds of template errors after a make clean all. When using template metaprogramming, a tiny misplaced coma can generate enough error code that, if printed, would crush you under tones of paper. And don't even try to read them, it'll make your head explode.

Luckily STLFilt can be quite a relief when dealing with this kind of errors. Granted, it won't make a steaming pile of poo seem to be a nice poem, but if you have something like the dog in the picture, to use a metaphor, at least it would put a blanket on its face.

Thursday, 20 October 2011

Dell and Ubuntu CPU Scaling

Hi, my name is Nicolás Brailovsky and you may remember me from movies like fixing keyboard problems in Ubuntu JJ, removing the annoying terminal warning, random complaints about dual screen in Buguntu and Ubuntu: sound still fubard. This time, I would like to add a new Ubuntu problem to the list of things which make me want to jump off a cliff, though I must warn you that this is a very old article that got forgotten on the stack of posts to review, so it might be dated. Being an old post means that this problem may be fixed by now, but since I don't have a Dell laptop anymore I cannot try it. Anyway, I'll post it as a reference to anyone who may experience something similar.

To be completely fair, this is a dual fuckup between Dell and Ubuntu: after an upgrade I started noticing that sometimes the CPU slows to a crawl, for no apparent reason. The only fix for this is a complete shutdown, as not even a reboot would make this problem go away. WTF?

A lot of time after I had given up on trying to solve this problem and decided that submitting to the gods seemingly random will was the best option, a coworker told me what this was about: apparently when you have a 3D GUI (say, a screensaver) and a double monitor the graphics card has to "work too much", drawing too much power. When the power consumption reaches 90 watts, the power supply's limit, the CPU enables something called CPU scaling, bringing the CPU clock speed to about the speed of a wristwatch. (No, really: "Even setting aside the negative performance effect of FSB downshifting in II above, the effective processing power is reduced to 1/8 of 798 Mhz = 100 MHz. This is a reduction to less than 5% of full capacity, from http://www.sigmirror.com/files/44490_iweoz/throttlegate.pdf).

Solution? None, thanks. Just shut it down and reboot.

Thursday, 6 October 2011

Open Office, master documents and headless

I have been writing some documentation lately (crazy, I know) and needed due to some bizarre business requirements all the documentation for the application was supposed to be in a single .doc file. That's write, a single file for user manual, technical manual, administration manual and so on. And I had no LaTeX either (damn those MS Office files, I hate them) so using multiple tex files and including them together wasn't an option.

Choosing the least of all evils, I decided to use Open Office and master documents. With them you can create several different .doc files and then join them together in a single .odm file, which can then be exported to pdf (or .doc, if your boss says so). It's a nice feature, but for such a simple thing as having multiple documents #included in a single one you would expect it to work better. From OO manual:

Yes, master documents do work in OOoWriter. However, their use is full of traps for inexperienced users[...]
Oh, thanks a lot OO.org (?). BTW, exporting an odm to pdf with a headless set == FAIL (i.e. don't even try to use this if you intend to autogenerate some documentation with your makefile).

Tuesday, 22 February 2011

I thought we had deprecated regedit

Guys, I thought we had already agreed on this a long time ago. Windows registry sucks. It's a pain in the ass.

Why TF is regedit still used in Gnome? I'd switch to KDE, if only I wasn't so lazy.

Thursday, 30 September 2010

To log or not to log

Logging is nice, we all know that. It saves you from having to stay up all night checking when and why your applications fails. It servers to blame the support guys for not reading it. It's useful to stress test your RAID.

But logging where you shouldn't is a pain in the ass waiting to happen.

When designing an application you should choose between domain level objects, wiring objects, library level objects, helper objects, etc. Your logging should be mostly in the wiring of your applications, not in the helper objects and very rarely in the domain level objects. These objects, when well designed, are supposed to be tested and to be run in a production environment with many different loggers. If you log in the middle of your business object you may end up writing logs through cout when you're testing, or worse, when you're supposed to be logging in syslog.

Tuesday, 3 August 2010

C++ Namespaces and g++

Have you ever tried to leave open a C++ namespace after EOF (that is, openning a namespace in a headerfile but forgetting to close it). It's a little bit like getting your balls caught by the door. The compiler will throw at you an incredible number of seemingly unrelated errors, all of which occur in a different file than the offending header.

Reaching EOF on a C++ file without closing all its namespaces should be ilegal; or at least you should have better error reporting, because right now it's almost impossible to know what's the source of the error (for g++, that is).

Friday, 23 July 2010

Fuuuuuuuuuuuuuu (Opera)

I hate ubuntu, but I hate windows the most. I hate firefox, but internet explorer makes me want to vomit. I don't like gnome, but kde is uglier. But I love Opera. Well, loved it, I guess version 10.60 will be my last version.

It's been a loyal application which I've been using since its 6.x version. Always fast, with all the functionality I needed (some more too) and none of the bloated BS needed to make FF be a usable (though ugly) browser. It had it's ussual screw-ups, everyone does, but after I updated to version 10.60 it has become unusable.

Its new features include random crashe, making gmail work really slow (or not at all: the fucking scrollbar won't work anymore, and keyboard shortcuts in google reader (j & k, next & prev) are foobar'd. Scrolling on a large webpage eats 100% cpu, the upgrade fucked up my nice dark theme (and changed it back to a hellish abomination which seems to be a time-traveller from 1998), and it has random stupid bugs. And I mean STUPID, like, double click a word and the popup menu won't go away.

Fuck. I always liked you Opera, but it seems it may be time to give chrome a chance.

Tuesday, 13 July 2010

The truth about SNMP

Seen @ http://wiki.wireshark.org/SNMP:
After years thinking and reading RFCs and various other documents, today, I finally understood. "Simple" refers to "Network" not to "Management Protocol"! So it is a Management Protocol for Simple Networks not a Simple Protocol for Management of Networks... That explains why it's called "Simple". It was that Simple but it took me years to understand it! -- LuisOntanon

Thank you Luis. That explains a lot.

Thursday, 8 July 2010

Opera borks gmail

Ubuntu sucks, but less than windows. Gmail sucks, but less than hotmail. Opera rocks, but it tends to fuck up gmail every once in a while. After a lot of research and having found no help on the interweb I traced the problem to having a lot of tabs open for a lot of time (weeks, not hours).

In Firefox this shouldn't be a problem as having a FF browser open for a week should hog all the memory on its host computer, forcing you to reboot. In Opera, being a little bit better behaved browser, this may actually be a problem.

Luckly the fix is simple: open a Vim editor or take out pencil and paper, make a list of all your open tabs, close opera and using your favourite console type "rm -rf ~/.opera/sessions" (i.e. delete the sessions folder in your .opera dir). Restart Opera and restore your tabs from your backup list. Problem should be gone.

Wednesday, 23 June 2010

Nooooooooooo

(gvim:13664): Gdk-CRITICAL **: gdk_window_get_user_data: assertion `GDK_IS_WINDOW (window)' failed
Vim: capté una señal de muerte SEGV
Vim: finalizado.

Tuesday, 1 June 2010

Oh shit, the stack

Post from the wayback machine. I wrote this a long time ago but it got way down the posts queue, don't know why

I liked my vacations very much, thank you. Some people enjoyed vacations from me too. At work they even decided to keep this gem for my return. Upon my arrival a nice coredump was waiting at my desk, so to speak. Check it out, isn't it beautiful?

0 0xff05d070 in inflate_fast () from /usr/lib/libz.so
1 0xff05a13c in inflate () from /usr/lib/libz.so
2 0x00146224 in ZDecompress::decompress (this=0xfbc7b300, sauce=@0xfbe7b740, dest=@0x27c910) at Compressor.h:134
3 0x00145e80 in HandleClient::get_client_data (this=0x27c810, output_stream=0x27c910) at IPC/DataReceiver.cpp:54

Yeah, that's getting killed inside zlib. Nice way to start the year, a bug in zlib. What led me to that conclusion? Easy, the same compressed file worked in Ubuntu. Must be a bug in zlib then!

The next step was getting zlib's code and adding enough printf's to know the problem was in the middle of the file, not at the beginning nor the end; indeed, most of the file could be correctly decoded, but then it just died. This looked more and more like a bug in zlib.

I began to scramble things around, trying to isolate the problem. Things just got weirder, the same code worked fine if instead of being inside a thread I was on the main thread. If you have psychic powers you now have enough information to know what the problem was. Although I should have known too (this wasn't even the first time I saw a problem like this one!) I was mindset on finding a bug in zlib, which now, it seems, only appears while interacting with ACE (in my defence, I did see these kind of bugs too).

Fiddling around with the code some more, even stranger backtraces began to appear. First this one:

Program received signal SIGSEGV, Segmentation fault.
[Switching to LWP 10]
0xfd6b88fc in _pollsys () from /usr/lib/libc.so.1
(gdb) bt
#0  0xfd6b88fc in _pollsys () from /usr/lib/libc.so.1
#1  0x696e7661 in ?? ()
#2  0x696e7661 in ?? ()

And then this other one, which led me into the right direction:

Program received signal SIGSEGV, Segmentation fault.
[Switching to LWP 9]
0x000b6784 in std::operator| (__a=Cannot access memory at address 0xfbb7b094
)
    at /usr/local/lib/gcc/sparc-sun-solaris2.10/3.4.6/../../../../include/c++/3.4.6/bits/ios_base.h:124
124       { return _Ios_Openmode(static_cast(__a) | static_cast(__b)); }
(gdb) bt
#0  0x000b6784 in std::operator| (__a=Cannot access memory at address 0xfbb7b094
)
    at /usr/local/lib/gcc/sparc-sun-solaris2.10/3.4.6/../../../../include/c++/3.4.6/bits/ios_base.h:124
#1  0x00152d5c in HandleClient::get_client_data (this=Cannot access memory at address 0xfbb7b088
) at IPC/DataReceiver.cpp:46

That last stack trace got me to think how could it be possible for an otherwise working program to coredump while creating an stdlib object. I mean, stdlib is quite well tested, isn't it? Then it struck me: the keyword isn't stdlib but creating. It was allocating memory from the stack, upon entering the function.

Some more research later I found out that Solaris default thread size is about 1 mb, while in Ubuntu this thread is of about 8 mb. And I also noticed the buffer I was allocating for zlib was taking up space in... the stack.

If there's something to learn from this story is that you should always know what goes in the stack: only small objects should live there, and you should always know the max stack depth a function could reach. Otherwise it may come back and bite you in the ass when you're back from your vacations.