You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am unable to provide a working example for you to use for a few reasons, but I will at least try and explain what the code does. It's not particularly complicated, but it does exist under some uncommon circumstances.
Basically, it's a standard Go HTTP server made to serve a single request for a client that authenticates with a client certificate. The client is POSTing a potentially large file that has been gzipped, and the server is saving it to disk. It does not preload the whole file into memory or anything, at least not in my logic. Here is a snippet from the code within the HTTP response handler.
The server is running with swap space disabled, which may be relevant since I see that the issue seems to occur somewhere in the malloc logic. However, the server should have plenty of RAM. In this case when it failed the server had 8 GiB of RAM and was receiving a payload that decompresses to only 1 GiB. No other programs were running so I expect that nearly all of that 8 GiB should be available to it.
What did you expect to see?
No errors.
What did you see instead?
The following stack traces and no others. Not a single line in these stack traces refers to one of my *.go files. I don't even know how that is possible in Go.
The 3rd argument here, 0x4f337609, looks weird. It's huge - it is an offset into some descriptor information for a function, so it should be small. That huge value is used to index the descriptor information, and it results in an out of bounds error.
That value is coming from funcInfo structures. The pointers shown in the trace seem like reasonable values. The location read is in the read-only section, so I don't see how it could become corrupted.
Could you fire up your binary in a debugger and dump the 64 bytes at the address 0x8c7dd0 and post them here? The weird huge value is generated from a 4-byte load from offset 20 of the data structure at 0x8c7dd0.
While you're at it, dump the 256 bytes at 0x91d720.
In the context where this error occurs I don't think I can actually run the binary in a debugger. Having said that, there is a chance that I have just figured out how it happened.
Some time after the binary is running and serving requests there's a chance that another process is unmounting the device the binary is stored on and writing to it directly as a raw character device. Possibly overwriting the binary itself. It did not initially occur to me that this could cause problems after the binary was loaded into memory, but after thinking about it for a while I've realized that demand-paging could be loading sectors from the disk into the run-time later than I anticipated. After reading your take on the issue this seems even more likely to me.
I've added an mlockall syscall using the MCL_FUTURE and MCL_CURRENT flags at the very beginning of my Go program in an attempt to force Linux to load it all in right away. This change has not been extensively tested, but the error has not reproduced since.
Looks like I might have found a way to corrupt "read-only" memory.
I think I'll close this issue and reopen it if the problem shows up again.
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Unfortunately I do not know. I do not even know how reproducible it is in the release I'm using.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
I am unable to provide a working example for you to use for a few reasons, but I will at least try and explain what the code does. It's not particularly complicated, but it does exist under some uncommon circumstances.
Basically, it's a standard Go HTTP server made to serve a single request for a client that authenticates with a client certificate. The client is POSTing a potentially large file that has been gzipped, and the server is saving it to disk. It does not preload the whole file into memory or anything, at least not in my logic. Here is a snippet from the code within the HTTP response handler.
Note: 'r' is the '*http.Request'.
The server is running with swap space disabled, which may be relevant since I see that the issue seems to occur somewhere in the malloc logic. However, the server should have plenty of RAM. In this case when it failed the server had 8 GiB of RAM and was receiving a payload that decompresses to only 1 GiB. No other programs were running so I expect that nearly all of that 8 GiB should be available to it.
What did you expect to see?
No errors.
What did you see instead?
The following stack traces and no others. Not a single line in these stack traces refers to one of my *.go files. I don't even know how that is possible in Go.
The text was updated successfully, but these errors were encountered: