|
Mustach posted:Are you verifying that nsd != -1 before trying to print the address? I wasn't, but tried it after you suggested it. Its definitely > 0 Vanadium posted:cli_addrlen needs to be socklen_t, not int I changed that but its still segfaulting. roomforthetuna posted:Worth doing but I don't think it could be the problem, since any value in the addr is valid enough to print. Is the segfault in the printf or in the accept (or even sooner?)? Have you checked that sd is a valid socket descriptor before calling accept? on the printf() - if I comment it out theres no segfault and the program continues along its merry way. any other ideas?
|
# ? Nov 5, 2010 13:26 |
|
|
# ? Jun 3, 2024 09:50 |
|
Ledneh posted:Is there any quick test, besides reading the compiler documentation (which is proving inconclusive), to see if my compiler is performing return value optimization, named OR unnamed? code:
Hello World! A copy was made. A copy was made. or Hello World! A copy was made. or Hello World!
|
# ? Nov 5, 2010 14:42 |
|
having more issues with my file transfer program. I have two functions used to send/receive a file over the socket send: http://pastebin.com/7bfhSHDh recv: http://pastebin.com/VetaKAh1 basically the client calls the send function, server calls recv function. For small files (< 1kb) this works flawlessly. I've just started testing it on larger files (a ~300 kb file and a ~600 kb file). And now the server is receiving an incorrect file size. If I print the size variable just before it gets converted to network byte order in the send function, and just after it gets converted back in the receive function, the numbers on the server side is vastly lower. client output: sending 336914 bytes server output: receiving 9234 bytes At first I thought i'd just hosed up the data types somewhere but they both look fine to me. Why is it working for low size values but not for higher ones? It sounds screamingly obvious but I can't seem to work it out.
|
# ? Nov 5, 2010 15:18 |
|
tripwire posted:Thanks. I wasn't asking because I need to write some code using tuples, I was just curious because it seemed like there had to be a good reason for only making tuples up to eight long. I wonder, outside of D and C++0x, are there any c-like strongly-typed languages in which its easy to make a tuple which accepts variable numbers of arguments of varying type? Scala and Haskell both support tuples of arbitrary arity (although Scala is only slightly C-like and Haskell is not at all): code:
boak posted:At first I thought i'd just hosed up the data types somewhere but they both look fine to me. Why is it working for low size values but not for higher ones? It sounds screamingly obvious but I can't seem to work it out. You have, in fact, hosed up the data types. - your call to write assumes that unsigned int is always 4 bytes, which may not be the case. (You also have a non-harmful but completely unnecessary cast to char*.) I would say "use sizeof" but if you're running the client and server on different architectures you don't even know that unsigned int is the same size on both. - You're using htons/ntohs to do your network <-> host byte order conversion. You might want to read the man pages for those, especially the bit right at the start that says they have the following signatures: code:
I suggest using uint32_t for your size type, and using htonl/ntohl (Network To Host Long/Host To Network Long) to manipulate it: code:
ToxicFrog fucked around with this message at 16:11 on Nov 5, 2010 |
# ? Nov 5, 2010 15:38 |
|
boak posted:on the printf() - if I comment it out theres no segfault and the program continues along its merry way. code:
code:
|
# ? Nov 5, 2010 16:24 |
|
ToxicFrog posted:You have, in fact, hosed up the data types. Thanks for the advice. Reading the man pages for htons() etc help me work out what was going on. I should have been using htonl() and ntohl() for my current implementation. As for different data types, makes sense. I'll change them over. Thanks for the help. roomforthetuna posted:Split it up more for debugging purposes! Is the crash in inet_ntoa or in printf? now segfaulting on printf("%s",tmp);
|
# ? Nov 5, 2010 17:13 |
|
tripwire posted:Thanks. I wasn't asking because I need to write some code using tuples, I was just curious because it seemed like there had to be a good reason for only making tuples up to eight long. I wonder, outside of D and C++0x, are there any c-like strongly-typed languages in which its easy to make a tuple which accepts variable numbers of arguments of varying type? .Net 4.0 has tuples, although I've never used them from C# and can't speak to their usefulness in that language (it looks like if you want more than eight elements in your tuple, you make the eighth one another tuple, et cetera).
|
# ? Nov 5, 2010 18:11 |
|
boak posted:now segfaulting on printf("%s",tmp); code:
Try code:
Try running it under a debugger so you can look at the variables' states after if crashes? (gdb is pretty useful but not much fun interface-wise. Worth learning though if you're going to be command-line programming much.)
|
# ? Nov 5, 2010 18:15 |
|
Ledneh posted:Is there any quick test, besides reading the compiler documentation (which is proving inconclusive), to see if my compiler is performing return value optimization, named OR unnamed? Hughlander's proposal covers normal RVO. If you want to test for NRVO, I'd test a few cases like these: code:
|
# ? Nov 5, 2010 22:18 |
|
Cool, thanks for the RVO tips, all. Another optimization question. Say I have a program that, for simplicity's sake, uses one string literal (say, "pants") but constructs that literal as a std::string over and over (and over and over ) again in code. This happens because my predecessors hate me. Is it likely to gain me anything in the real world if, instead of repeatedly constructing that same literal, I wrap it in a class that goes something like this contrived-as-hell pseudocode? code:
I'm guessing this can't be determined in the general case, and depends entirely on how many literals we're using/how many string constructions we're doing, but I thought I'd throw it out there. (right now std::string construction is accounting for like 25% of our runtime according to our profiler, which seems like total dogshit) Ciaphas fucked around with this message at 01:18 on Nov 6, 2010 |
# ? Nov 6, 2010 01:13 |
|
If your profile says you're spending a quarter of your time building std::strings, then yes, I would guess that it's telling the truth; consider just making a const global std::string for each of your literals, assuming you can't just avoid needing a std::string for the literal in the first place. A uniquing cache sometimes makes sense (for non-literals), but you should implement it with a real hashtable instead of this crazy map keyed on hashes.
|
# ? Nov 6, 2010 01:27 |
|
Argh, thanks. Why didn't I think of using a hash table in the first place (For what it's worth, the full list of literals that get used over and over and etc changes for every run of the program, it depends on an input file.) (edit- I just realized i may be using the wrong word when I say 'literal.' God damnit it's too late for me to be thinking.) Ciaphas fucked around with this message at 01:58 on Nov 6, 2010 |
# ? Nov 6, 2010 01:53 |
|
A remarkably specific server-programming question - I have a server that loads extra functionality from plugins. The base server code is pretty tight, full of plenty of user-data integrity checks and such. The plugins also should be, but there's probably going to be a lot of them and likely written in haste, so I don't want to be relying on them being bulletproof, and I don't want a bad function crashing the whole server. (It's basically a MMORPG server, so crashing out is not acceptable behaviour for it.) Is there a decent way of doing this? I don't need plugins to be sealed in an indestructible sandbox, since it'll be my own code, I don't need to protect against maliciousness - I just want it to fail gracefully if I have a bad function. It's most likely that if they explode it'll be from something like trying to access a null pointer, or an unsigned array index accidentally going to 0xffffffff, Is there a decent(ish) way to do this? Maybe something like trapping SIGSEGV and throwing an exception from there, and wrapping plugin function calls in a "try {function} catch (...)"? (This is on a Linux system.)
|
# ? Nov 6, 2010 02:00 |
|
Write the plugins in lua
|
# ? Nov 6, 2010 02:32 |
|
Vanadium posted:Write the plugins in lua
|
# ? Nov 6, 2010 02:50 |
|
There are various tools (for both C and C++) that make that a lot less painless by automatically generating bindings. Unfortunately, I haven't used any of them, so the most I can tell you is that they exist and I hear people use them. E: also, even if this is ugly, it's likely to be less ugly than manually signal fiddling and whatnot - which won't protect you if the plugin corrupts something in your server causing it to crash later, either. ToxicFrog fucked around with this message at 03:33 on Nov 6, 2010 |
# ? Nov 6, 2010 03:18 |
|
Boost.python isn't lua, but it's really very well done. I've never used the embedded python functionality myself, but wrapping C++ for Python (the important part) is like magic.
|
# ? Nov 6, 2010 04:21 |
|
rjmccall posted:If your profile says you're spending a quarter of your time building std::strings, then yes, I would guess that it's telling the truth; consider just making a const global std::string for each of your literals, assuming you can't just avoid needing a std::string for the literal in the first place. What I ended up with before I left work code:
(did a drat good job for performance though... can't wait to get some sleep and look at this again in the morning when my brain is fixed and I can make it better) Ciaphas fucked around with this message at 06:20 on Nov 6, 2010 |
# ? Nov 6, 2010 06:04 |
|
ToxicFrog posted:Scala and Haskell both support tuples of arbitrary arity (although Scala is only slightly C-like and Haskell is not at all): code:
Here's how GHC implements tuples: http://www.haskell.org/ghc/docs/6.12.2/html/libraries/ghc-prim-0.2.0.0/src/GHC-Tuple.html An excerpt: GHC.Tuple posted:data (,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,) a b c d e f g h i j k l m n o p q r s t u v w x y z a_ b_ c_ d_ e_ f_ g_ h_ i_ j_ k_ l_ m_ n_ o_ p_ q_ r_ s_ t_ u_ v_ w_ x_ y_ z_ a__ b__ c__ d__ e__ f__ g__ h__ i__
|
# ? Nov 6, 2010 07:09 |
|
Edit: er, I meant this post to be an edit. It's impossible to be generic over tuples with respect to the size of a tuple. Each tuple type is completely independent.
|
# ? Nov 6, 2010 07:10 |
|
roomforthetuna posted:Is there a decent(ish) way to do this? Maybe something like trapping SIGSEGV and throwing an exception from there, and wrapping plugin function calls in a "try {function} catch (...)"? Yeah, sigaction(2) (though you probably know more about how to use it than I do). Might have to be careful if you're combining multithreading with signals, and don't forget that SIGFPE, SIGILL, SIGSEGV and etc. are just a small part of the ways code could go wrong - you could still be hosed over by resource leaks, poor performance or nontermination, memory corruption... so if you do implement this level of protection, better not advertise it so people won't think they can depend on it. Duke of Straylight fucked around with this message at 11:34 on Nov 6, 2010 |
# ? Nov 6, 2010 10:14 |
|
You could go the way Chrome does it and encapsulate each plugin in its own process. That way there's no chance of a crashing plugin going and scribbling over some important data needed by the server itself. Though you'll need to keep in mind that a crashing plugin could still be sending erroneous data to the core, but there's really no way to avoid that except for writing the plugins so they don't crash in the first place. The alternative to full memory-space isolation is to use something "safe" like Lua, which will guarantee that even if the plugin fails, it won't wreck anything outside of its own state.
|
# ? Nov 6, 2010 10:47 |
|
Ledneh posted:Cool, thanks for the RVO tips, all. Speaking as someone who had this problems years ago (Though ours were worse because the function parameters were std::string, no const, no reference.) We got a hell of a lot of performance just analyzing the code paths and changing things to const char* and std::string&. Something else to consider depending on your requirements, though the hashmap should work as well.
|
# ? Nov 6, 2010 14:26 |
|
Ledneh posted:Another optimization question. Say I have a program that, for simplicity's sake, uses one string literal (say, "pants") but constructs that literal as a std::string over and over (and over and over ) again in code. This happens because my predecessors hate me.
|
# ? Nov 6, 2010 16:30 |
|
Duke of Straylight posted:Yeah, sigaction(2) (though you probably know more about how to use it than I do). Might have to be careful if you're combining multithreading with signals, and don't forget that SIGFPE, SIGILL, SIGSEGV and etc. are just a small part of the ways code could go wrong - you could still be hosed over by resource leaks, poor performance or nontermination, memory corruption... so if you do implement this level of protection, better not advertise it so people won't think they can depend on it. roomforthetuna fucked around with this message at 20:28 on Nov 6, 2010 |
# ? Nov 6, 2010 17:31 |
|
shrughes posted:Edit: er, I meant this post to be an edit. What about dependent typed languges
|
# ? Nov 6, 2010 17:51 |
|
tef posted:What about dependent typed languges I was talking about Haskell, specifically. Besides, for different implementations of tuple types, it is possible to be generic, anyway.
|
# ? Nov 6, 2010 18:16 |
|
shrughes posted:Tuples in Haskell Consider me enlightened (and somewhat disappointed). I tried the same test in Scala. It chokes once it hits size 22. Yeah, realistically a tuple with that many elements is a sign that you should be using an immutable list or a class instance or something, but still.
|
# ? Nov 6, 2010 19:11 |
|
shrughes posted:I was talking about Haskell, specifically. Do you happen to know of any languages that do tuple-as-cons where (a,b,c) is just sugar for the type (a,(b,(c,())))?
|
# ? Nov 6, 2010 19:25 |
|
Standish posted:Yes, this is a fairly widespread pattern called string interning. Ah, I am enlightened! Thanks. And thanks to everyone else for the ideas and suggestions, I've got more ammo for Monday now (edit) A couple of related questions. One, I just saw boost::flyweight, and uh, would it do what I just did automagically? Second, while reading about string interning I saw Copy-on-Write mentioned. Is that a compiler optimization, or is that something one has to code for? Ciaphas fucked around with this message at 21:32 on Nov 6, 2010 |
# ? Nov 6, 2010 19:55 |
|
Ledneh posted:(edit) A couple of related questions. One, I just saw boost::flyweight, and uh, would it do what I just did automagically? quote:Second, while reading about string interning I saw Copy-on-Write mentioned. Is that a compiler optimization, or is that something one has to code for? In this context it's a "code for" optimization. It's useful in the case where you have a bunch of objects representing e.g. an array or list or something and the objects present an interface to mutate that data, but you don't actually mutate the data often. With copy-on-write instead of copying all the data when you copy the object you copy the pointer to that data instead. You put off copying that data until you absolutely have to, i.e. when someone tries to mutate it. If you make lots of copies but don't mutate your data often it can significantly reduce your memory consumption and the amount of copying you do. Here's a small example: code:
Mr.Radar fucked around with this message at 01:41 on Nov 7, 2010 |
# ? Nov 7, 2010 01:20 |
|
Just in case someone else was interested in the idea, it turns out that sigaction won't really help with recovering after a SIGSEGV - you can't throw an exception from inside the signal handler, nor do anything that will take you back to a relatively safe point in the code, except by crazy horrible direct stack pointer manipulation. So it seems I'm stuck with either "rewrite everything so I can use some sort of scripting language for the plugins" or "just write the dynamic plugin functions even more carefully". Who'd have thought I'd wish for something like Microsoft's __try and __catch.
|
# ? Nov 7, 2010 22:31 |
|
setjmp() and longjmp() maybe? Or sigsetjmp() and siglongjmp(), it appears that Wikipedia warns about using setjmp() and longjmp() together with signal handling.
|
# ? Nov 7, 2010 22:58 |
|
Duke of Straylight posted:setjmp() and longjmp() maybe? Or sigsetjmp() and siglongjmp(), it appears that Wikipedia warns about using setjmp() and longjmp() together with signal handling.
|
# ? Nov 8, 2010 01:36 |
|
What do you expect siglongjmp() to do to the stack that it isn't doing for you?
|
# ? Nov 8, 2010 05:22 |
|
pseudorandom name posted:What do you expect siglongjmp() to do to the stack that it isn't doing for you? code:
code:
|
# ? Nov 8, 2010 15:20 |
|
roomforthetuna, I was wondering what you were trying to scheme with that kind of recovery. I don't mean to attack what you're doing, but rather I'm curious since I'm scheming some stuff with plugins and c++ too. I'm a bit paranoid of a plugin blowing up everything. What I am planning to do is to run untrusted plugins in a seperate process space. But the idea there is eventually one would get cozy with them and let the main process load them up to reduce overhead of copying stuff back and forth. The only (and big) downside is even after trusting the plugin, it could very well go out of its way to blow everything up.
|
# ? Nov 8, 2010 19:52 |
|
roomforthetuna posted:I think I was hoping it would restore the stack length and contents, but it just rewinds the length, or something, such that this works okay: All the man pages I'm finding say that you can't return from a function that calls setjmp (or sigsetjmp) and expect a corresponding longjmp to work correctly.
|
# ? Nov 8, 2010 20:50 |
|
Yep, that's one of the major restrictions on setjmp. The other is that, if you modify a non-volatile local variable after a setjmp, it will have indeterminate state after a longjmp. Basically, setjmp is specifically designed to allow the implementation to only capture register state.
|
# ? Nov 8, 2010 21:01 |
|
|
# ? Jun 3, 2024 09:50 |
|
Rocko Bonaparte posted:roomforthetuna, I was wondering what you were trying to scheme with that kind of recovery. I don't mean to attack what you're doing, but rather I'm curious since I'm scheming some stuff with plugins and c++ too. I'm a bit paranoid of a plugin blowing up everything. What I am planning to do is to run untrusted plugins in a seperate process space. But the idea there is eventually one would get cozy with them and let the main process load them up to reduce overhead of copying stuff back and forth. The only (and big) downside is even after trusting the plugin, it could very well go out of its way to blow everything up. These things are plugins because they're likely to update a lot more frequently than the core server (both for changes to game scoring and for new games being added), and as dynamically loaded plugins I can even switch them out while the server is still running, thus sparing the "hey everyone, you're all going to get disconnected for an update!" messages common in many MMORPGs. But because they'll be frequently changed and easily switched out, there's a very good chance I'll also screw something up occasionally, hence the wish for a "don't crash out and disconnect everyone" solution. quote:All the man pages I'm finding say that you can't return from a function that calls setjmp (or sigsetjmp) and expect a corresponding longjmp to work correctly.
|
# ? Nov 9, 2010 02:10 |