Static linking (on Mac x64)
Hello,
normally I use dynamic linking with solclient
library and it works as expected.
Out of curiosity I tried static linking. I linked following
libsolclient.a
,libsolclientssl.a
,libcrypto.a
,libssl.a
- and Kerberos framework.
When I run my app it fails with EXC_BAD_ACCESS
when running solClient_cleanup
according to LLDB it calls _solClient_transactedSession_failAllThreads
which calls JudyLFirstEmpty
.
I use solclient-7.24.0.9
on Mac with x64 architecture.
My question is whether there is some example or tutorial explaining how to do static linking on Mac? For example there's also solClientSSLStaticLinkEnable.o
which I don't link because then I have duplicate symbols. So I'm confused why is solClientSSLStaticLinkEnable.o
in the package or what should I do with it?
Thanks
Answers
-
Hello @radekm .
Can you provide a small project to demonstrate how you are linking and getting this error?
Generally I expect problems with static linking to occur at linking not at run time. Once you've successfully created the executable, the run-time exception may be something else entirely.
That said, I also expect that you need to include
solClientSSLStaticLinkEnable.o
in your link-edit command and it must occur before libssl.a and libcrypto.a in the command. If you do not include this, it is likely the library is still trying to dynamically load libssl.so/libcrypto.so. This still should not lead to the EXC_BAD_ACCESS but instead to a dynamic loading issue at run-time.If you are getting duplicate symbol errors at link-edit time, can you tell us what symbols are duplicated. And again provide a small project/makefile to demonstrate this so we can debug it.
Finally, just for thoroughness, are you using TLS in your test (libssl/libcrypto) and GSS (Kerberos) both? Do you use Kerberos for authentication and TLS for encryption. I don't think this will lead to a failure in JudyFirstLempty, but I do want to understand your test scenario so I can try to reproduce it.
1 -
That said, I also expect that you need to include
solClientSSLStaticLinkEnable.o
in your link-edit command and it must occur before libssl.a and libcrypto.a in the command.I tried
clang solace_lib/solClientSSLStaticLinkEnable.o solace_lib/libssl.a solace_lib/libcrypto.a solace_lib/libsolclient.a -framework kerberos connect.c
but still getting lots of duplicate symbol errors. The first few of them are
duplicate symbol '__SSL_set_verify' in: solace_lib/solClientSSLStaticLinkEnable.o solace_lib/libsolclient.a(solClientSSL.o) duplicate symbol '__SSL_use_cert_and_key' in: solace_lib/solClientSSLStaticLinkEnable.o solace_lib/libsolclient.a(solClientSSL.o) duplicate symbol '__d2i_PrivateKey' in: solace_lib/solClientSSLStaticLinkEnable.o solace_lib/libsolclient.a(solClientSSL.o)
It's very basic program. But seems not to link if I omit Kerberos framework.
#include <stdio.h> #define SOLCLIENT_CONST_PROPERTIES 1 #include "solclient/solClient.h" #include "solclient/solClientMsg.h" solClient_rxMsgCallback_returnCode_t sessionMessageReceiveCallback ( solClient_opaqueSession_pt session, solClient_opaqueMsg_pt msg, void *data ) { return SOLCLIENT_CALLBACK_OK; } void sessionEventCallback ( solClient_opaqueSession_pt opaqueSession_p, solClient_session_eventCallbackInfo_pt eventInfo_p, void *user_p ) { } int main() { printf("Starting\n"); solClient_initialize(SOLCLIENT_LOG_INFO, NULL); const char *contextProps[50] = {0, }; int propIndexC = 0; contextProps[propIndexC++] = SOLCLIENT_CONTEXT_PROP_CREATE_THREAD; contextProps[propIndexC++] = SOLCLIENT_PROP_ENABLE_VAL; contextProps[propIndexC++] = NULL; solClient_opaqueContext_pt context; solClient_context_createFuncInfo_t contextFuncInfo = SOLCLIENT_CONTEXT_CREATEFUNC_INITIALIZER; solClient_context_create( //SOLCLIENT_CONTEXT_PROPS_DEFAULT_WITH_CREATE_THREAD, contextProps, &context, &contextFuncInfo, sizeof(contextFuncInfo) ); solClient_opaqueSession_pt session; solClient_session_createFuncInfo_t sessionFuncInfo = SOLCLIENT_SESSION_CREATEFUNC_INITIALIZER; sessionFuncInfo.rxMsgInfo.callback_p = sessionMessageReceiveCallback; sessionFuncInfo.rxMsgInfo.user_p = NULL; sessionFuncInfo.eventInfo.callback_p = sessionEventCallback; sessionFuncInfo.eventInfo.user_p = NULL; const char *sessionProps[50] = {0, }; int propIndex = 0; sessionProps[propIndex++] = SOLCLIENT_SESSION_PROP_HOST; sessionProps[propIndex++] = "foo"; sessionProps[propIndex++] = SOLCLIENT_SESSION_PROP_USERNAME; sessionProps[propIndex++] = "bar"; sessionProps[propIndex++] = SOLCLIENT_SESSION_PROP_PASSWORD; sessionProps[propIndex++] = ""; sessionProps[propIndex++] = SOLCLIENT_SESSION_PROP_VPN_NAME; sessionProps[propIndex++] = "default"; sessionProps[propIndex++] = SOLCLIENT_SESSION_PROP_CONNECT_BLOCKING; sessionProps[propIndex++] = SOLCLIENT_PROP_ENABLE_VAL; sessionProps[propIndex++] = SOLCLIENT_SESSION_PROP_SUBSCRIBE_BLOCKING; sessionProps[propIndex++] = SOLCLIENT_PROP_ENABLE_VAL; sessionProps[propIndex++] = SOLCLIENT_SESSION_PROP_RECONNECT_RETRIES; sessionProps[propIndex++] = "0"; sessionProps[propIndex++] = NULL; solClient_session_create( (const char **)sessionProps, context, &session, &sessionFuncInfo, sizeof(sessionFuncInfo) ); solClient_cleanup(); printf("Finishing\n"); return 0; }
0