elastic / elastic-otel-java

Apache License 2.0
8 stars 7 forks source link

Hide statically linked libstdc++ symbols and enable compiler to remove unused code. #221

Closed JonasKunz closed 2 months ago

JonasKunz commented 2 months ago

These changes should make the binaries safer to use (preventing symbol-clashing) and also make them slightly smaller. Stumbled across this in this comment.

JonasKunz commented 2 months ago

Size of the uncompressen libs prior to this change: image

Size after the change: image

TBH looks like there still is a lot of room for improvement in the arm64 binary, I don't know why it is that much bigger than the x64 one, but the compressed size isn't that bad that it would justify investing time here.

The jar file size (so all binaries compressed) changes from 552kb to 433kb.

Also the used symbols are now much more manageable and make more sense, which should make the binaries more portable:

nm -gDC elastic-jvmti-linux-x64.so 
0000000000005d10 T Java_co_elastic_otel_JvmtiAccessImpl_createProcessProfilingCorrelationBufferAlias
0000000000005d00 T Java_co_elastic_otel_JvmtiAccessImpl_createThreadProfilingCorrelationBufferAlias
0000000000005cd0 T Java_co_elastic_otel_JvmtiAccessImpl_destroy0
0000000000005d40 T Java_co_elastic_otel_JvmtiAccessImpl_readProfilerReturnChannelSocketMessage0
0000000000005d50 T Java_co_elastic_otel_JvmtiAccessImpl_sendToProfilerReturnChannelSocket0
0000000000005cf0 T Java_co_elastic_otel_JvmtiAccessImpl_setProcessProfilingCorrelationBuffer0
0000000000005ce0 T Java_co_elastic_otel_JvmtiAccessImpl_setThreadProfilingCorrelationBuffer0
0000000000005d20 T Java_co_elastic_otel_JvmtiAccessImpl_startProfilerReturnChannelSocket0
0000000000005d30 T Java_co_elastic_otel_JvmtiAccessImpl_stopProfilerReturnChannelSocket0
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000007e40 T elastic::jvmti_agent::ProfilerSocket::openSocket(JNIEnv_*, _jstring*)
00000000000081c0 T elastic::jvmti_agent::ProfilerSocket::closeSocket(JNIEnv_*)
00000000000089e0 T elastic::jvmti_agent::ProfilerSocket::readMessage(JNIEnv_*, _jobject*)
00000000000093e0 T elastic::jvmti_agent::ProfilerSocket::writeMessage(JNIEnv_*, _jbyteArray*)
0000000000006d40 T elastic::jvmti_agent::ProfilerSocket::State::bindToPath(JNIEnv_*, _jstring*)
0000000000005e00 T elastic::jvmti_agent::ProfilerSocket::State::~State()
0000000000005e00 T elastic::jvmti_agent::ProfilerSocket::State::~State()
0000000000005e60 T elastic::jvmti_agent::ProfilerSocket::destroy()
0000000000005b10 W elastic::jvmti_agent::ProfilerSocket::~ProfilerSocket()
0000000000005b10 W elastic::jvmti_agent::ProfilerSocket::~ProfilerSocket()
0000000000006310 W void elastic::jvmti_agent::raiseExceptionType<char const (&) [24], std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, char const (&) [47], unsigned long&>(JNIEnv_*, char const*, char const (&) [24], std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, char const (&) [47], unsigned long&)
0000000000008b30 W void elastic::jvmti_agent::raiseExceptionType<char const (&) [25]>(JNIEnv_*, char const*, char const (&) [25])
0000000000008250 W void elastic::jvmti_agent::raiseExceptionType<char const (&) [27]>(JNIEnv_*, char const*, char const (&) [27])
0000000000006160 W void elastic::jvmti_agent::raiseExceptionType<char const (&) [30]>(JNIEnv_*, char const*, char const (&) [30])
0000000000006760 W void elastic::jvmti_agent::raiseExceptionType<char const (&) [31]>(JNIEnv_*, char const*, char const (&) [31])
0000000000007000 W void elastic::jvmti_agent::raiseExceptionType<char const (&) [32]>(JNIEnv_*, char const*, char const (&) [32])
0000000000005f70 W void elastic::jvmti_agent::raiseExceptionType<char const (&) [34], std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>(JNIEnv_*, char const*, char const (&) [34], std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&)
0000000000008010 W void elastic::jvmti_agent::raiseExceptionType<char const (&) [41]>(JNIEnv_*, char const*, char const (&) [41])
0000000000008400 W void elastic::jvmti_agent::raiseExceptionType<char const (&) [43]>(JNIEnv_*, char const*, char const (&) [43])
00000000000085b0 W void elastic::jvmti_agent::raiseExceptionType<char const (&) [43], int&>(JNIEnv_*, char const*, char const (&) [43], int&)
0000000000008ce0 W void elastic::jvmti_agent::raiseExceptionType<char const (&) [43], long&, char const (&) [11], int&>(JNIEnv_*, char const*, char const (&) [43], long&, char const (&) [11], int&)
00000000000075e0 W void elastic::jvmti_agent::raiseExceptionType<char const (&) [50], int&>(JNIEnv_*, char const*, char const (&) [50], int&)
00000000000071b0 W void elastic::jvmti_agent::raiseExceptionType<char const (&) [53], int&>(JNIEnv_*, char const*, char const (&) [53], int&)
0000000000006910 W void elastic::jvmti_agent::raiseExceptionType<char const (&) [55], int&>(JNIEnv_*, char const*, char const (&) [55], int&)
0000000000007a10 W void elastic::jvmti_agent::raiseExceptionType<char const (&) [57], int&>(JNIEnv_*, char const*, char const (&) [57], int&)
0000000000005c80 T elastic::jvmti_agent::closeProfilerSocket(JNIEnv_*)
0000000000005c60 T elastic::jvmti_agent::createProfilerSocket(JNIEnv_*, _jstring*)
0000000000005c90 T elastic::jvmti_agent::readProfilerSocketMessage(JNIEnv_*, _jobject*)
0000000000005cb0 T elastic::jvmti_agent::writeProfilerSocketMessage(JNIEnv_*, _jbyteArray*)
0000000000005b60 T elastic::jvmti_agent::setThreadProfilingCorrelationBuffer(JNIEnv_*, _jobject*)
0000000000005bb0 T elastic::jvmti_agent::setProcessProfilingCorrelationBuffer(JNIEnv_*, _jobject*)
0000000000005bf0 T elastic::jvmti_agent::createThreadProfilingCorrelationBufferAlias(JNIEnv_*, long)
0000000000005c30 T elastic::jvmti_agent::createProcessProfilingCorrelationBufferAlias(JNIEnv_*, long)
0000000000005b40 T elastic::jvmti_agent::destroy()
0000000000005ed0 W void std::__detail::__to_chars_10_impl<unsigned long>(char*, unsigned int, unsigned long)
000000000001a3e0 u std::__detail::__to_chars_10_impl<unsigned int>(char*, unsigned int, unsigned int)::__digits
000000000001a300 u std::__detail::__to_chars_10_impl<unsigned long>(char*, unsigned int, unsigned long)::__digits
                 U __cxa_atexit@GLIBC_2.2.5
                 w __cxa_finalize@GLIBC_2.2.5
                 U __errno_location@GLIBC_2.2.5
                 w __gmon_start__
                 w __pthread_key_create
                 U __tls_get_addr@GLIBC_2.3
                 U abort@GLIBC_2.2.5
                 U bind@GLIBC_2.2.5
                 U close@GLIBC_2.2.5
                 U dl_iterate_phdr@GLIBC_2.2.5
00000000000232b0 B elastic_apm_profiling_correlation_process_storage_v1
0000000000000000 B elastic_apm_profiling_correlation_tls_v1
                 U fcntl@GLIBC_2.2.5
                 U fputc@GLIBC_2.2.5
                 U fputs@GLIBC_2.2.5
                 U free@GLIBC_2.2.5
                 U fwrite@GLIBC_2.2.5
                 U gettext@GLIBC_2.2.5
                 U malloc@GLIBC_2.2.5
                 U memcmp@GLIBC_2.2.5
                 U memcpy@GLIBC_2.14
                 U memset@GLIBC_2.2.5
                 w pthread_mutex_lock@GLIBC_2.2.5
                 w pthread_mutex_unlock@GLIBC_2.2.5
                 w pthread_once
                 U realloc@GLIBC_2.2.5
                 U recv@GLIBC_2.2.5
                 U sendto@GLIBC_2.2.5
                 U socket@GLIBC_2.2.5
                 U sprintf@GLIBC_2.2.5
                 U stderr@GLIBC_2.2.5
                 U strcmp@GLIBC_2.2.5
                 U strerror@GLIBC_2.2.5
                 U strlen@GLIBC_2.2.5
                 U strncpy@GLIBC_2.2.5
                 U unlink@GLIBC_2.2.5
JonasKunz commented 2 months ago

Ok so I checked, adding -s (to strip debug symbols from the binaries) reduces the size of the ARM binary to just 72kb. However, like the name says core dumps / debuging / profiling won't work anymore. So for now let's just keep them in :)

athre0z commented 2 months ago

Ok so I checked, adding -s (to strip debug symbols from the binaries) reduces the size of the ARM binary to just 72kb. However, like the name says core dumps / debuging / profiling won't work anymore. So for now let's just keep them in :)

You could strip DWARF debug info but keep ELF symbols. Should provide most of the upsides at a fraction of the cost.