dns-lookup *broken* in linux x86-64 #15

Closed
orthecreedence opened this Issue Oct 7, 2012 · 7 comments

Projects

None yet

1 participant

@orthecreedence
Owner

I do not know why. My gut says it's a type mismatch between 32bit and 64bit, but playing with the types in the bindings for the DNS functions doesn't seem to do any good.

Note that this may also be broken on Windows 64bit (I haven't tested yet).

Any ideas here would be appreciated. My CCL backtrace (slackware x64) is as follows:

*** glibc detected *** ccl: double free or corruption (!prev): 0x0000000000678c10 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x76ce6)[0x7f2951491ce6]
/lib64/libc.so.6(cfree+0x73)[0x7f2951498553]
ccl(_SPffcall+0x75)[0x412855]

but I'm certain I'm not "double freeing."

This works on Windows 32bit.

@orthecreedence
Owner

Note: update tcp-send's documentation about x86_64 after figuring out what the hell is going on...

@orthecreedence
Owner

Ok, I think i have this figured out.

size_t is 4 bytes in x86, and 8 bytes in x86_64. I think I can fix this by using a type that's 8 bytes in x64 and 4 bytes in 32 (unsigned long seems to match)...

@orthecreedence
Owner

No such luck, problem is two fold:

  • The evutil_addrinfo struct returns a null pointer when asking for the actual address object. This is detectable and avoidable, but results in the lookup failing (EVERY time on x64)
  • The call to (free-dns-base) in (release-dns-base) is the place that's segfaulting, saying that it has been freed twice. This is not true, and the *dns-base* pointer is valid (not null) when freeing, so not sure WTH is going on (although I suspect that the evutil_addrinfo and the dns-base problems are related)

This happens even after defining size_t as unsigned long, which has the correct size on both platforms.

@orthecreedence
Owner

AHA! The segfault was my fault, was calling (free-pointer-data dns-base), should have been (free-pointer-data dns-base :preserve-pointer t) in (free-dns-base). This fixes the segfault! Surprised this worked on any platform, but I guess Windows just doesn't care if you double free.

However, the lookup problems still remain on x64.

@orthecreedence
Owner

FIXED. had to manually seek pointers by hand based on whether its windows/linux, and also had to have two separate definitions of addrinfo (addrinfo (linux) and evutil_addrinfo (windows)). this is a messy, shitty way to do things, but from what i got looking directly at addrinfo's memory, it's pretty much a free-for-all as far as who sets what pointer to which location/offset in addrinfo->ai_addr.

now that I think about it, the pointer trickery (*addrinfo-ai-addr-offset*) might be able to be avoided if there was a definition of addrinfo in bindings.i that somehow matched the pointer location with the correct set of fields that match up with 32bit/64bit linux.

this is tested on linux64, win64, win32 (and working) so just need a linux32 test. if linux32 doesn't work, then i will investigate the aforementioned addrinfo struct that works better with linux. in fact, that may be worth looking into now...

for now, this is marked as working

@orthecreedence
Owner

Correction: the struct issues can only fix the location of addrinfo->ai_addr (and for this purpose they perform admirably), but the offset is for the location that ai_addr points to, which on linux64 was ai_addr + 4 instead of just ai_addr for some god damned reason.

In other words, I think the current method I'm using is sound. I don't know if this is a bug in libevent (doubtful, since this is a pretty standard use-case), a weird OS glitch, or if I'm doing something retarded...

@orthecreedence
Owner

Ehhh NVM. The offset bullshit was there because sockaddr_in->sin_addr should have been defined as unsigned int but was defined as unsigned long (even though EVERYONE EVERYWHERE says it's unsigned long....................................................) rrrg.

This one change simplified a lot of the code in dns-cb (including removal of the hacky pointer offset bullshit). God damnit, there goes a few hours.

Still need someone to test linux32 tho

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment