Actually what I really need is peekCStringLen. This function can surely avoid stack overflow by building up the result from right to left? I think for peekCString the solution might be to get the length using the C function strlen (which is more optimised than a Haskell alternative) and then call peekCStringLen.