Issues preventing running Go applications in Gramine #2008
Replies: 7 comments
-
Just my two cents, for the syscall interface, there is another possibility: to patch the ELF file after the Go toolchain produces it. And this could be more convenient if the user only has the binary. |
Beta Was this translation helpful? Give feedback.
-
@lejunzhu: This method is super unreliable and hard to maintain, we don't plan to go in this direction. |
Beta Was this translation helpful? Give feedback.
-
Are there any updates on this "waiting for EDMM/SGXv2 solution"? And AFAIK, SGX2 only allows you to manage memory dynamically. I am not sure it can allow dynamically allocating more threads. |
Beta Was this translation helpful? Give feedback.
-
Yes, it's been supported since Gramine v1.6. Pls see the related manifest option, issue #1223 and PR #1451 for details.
Dynamic threading is achieved based on SGX2 that allows TCS to be added at runtime (specifically, by changing regular enclave pages into TCS pages). Pls see above and Section 3.4 of this EDMM paper. |
Beta Was this translation helpful? Give feedback.
-
@mkow @kailun-qin Should this be moved to Discussions? |
Beta Was this translation helpful? Give feedback.
-
Yes, make sense to me. |
Beta Was this translation helpful? Give feedback.
-
Hey Gramine team! Trying to reach a point where the following warning dissapears: And after discussing previously with gramine team, go build (with compiler -gccgo) is not an option for now, because its quite back in compatibility with golang version, current gccgo supports only go 1.18. And currently we need at least support for Go 1.21. So having this said, I have been trying to build the golang application using the gramine binary using gramine glibc instead, but not sure if I am following the correct paths, or if this makes sense at all. Here is a small sample that I am currently testing to build the application inside docker:
However it fails on boot: Am I following the correct path here? Makes sense? |
Beta Was this translation helpful? Give feedback.
-
Go (also known as Golang) is one of the languages currently popular for writing applications in. Ideally it would be possible to run those within Gramine. However, some issues within the Go runtime make that unreliable and slow.
Syscall interface
Gramine needs to be in charge of handling all syscalls made by the application. The recommended way to achieve this is to use a specific
call
instruction instead ofsyscall
. We carry patches for glibc and musl to handle this for most applications. However, because of an interesting decision made by the Go team, Go doesn't use the libc to issue syscalls. This is not the first time this has caused issues.For Gramine, the impact is that the fallback that traps the
syscall
instruction will be used. This causes a significant performance degradation, as many more context switches are required for each syscall. This is signalled by the following message printed during startup:As Go binaries are fully statically linked, the only solution seems to be patching the Go toolchain to create binaries with the Gramine-specific syscall ABI. Apart from the overhead of maintaining the patches, this would be somewhat annoying for users, as for most other stacks, the build system doesn't need to know about Gramine, and the binaries produced can be run on Linux directly for testing.
Go runtime thread count
Due to SGX limitations, we need to specify the total number of threads each process in the enclave might use (this is the
sgx.thread_num
manifest key). However, the number of threads the Go runtime may use is unbounded. The closest we have to limiting this is theGOMAXPROCS
environment variable, however this doesn't count the threads that are blocked on a syscall, so it doesn't solve the problem.Possible solutions:
sgx.thread_num
to a somewhat high number, cross your fingers and hope for the best (this is what's happening in practice right now)Beta Was this translation helpful? Give feedback.
All reactions