Skip to content
This repository has been archived by the owner on Dec 20, 2023. It is now read-only.

Bug: gCASEAuthDelegate was constructed twice #560

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/adaptations/device-layer/CASEAuth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,6 @@ class CASEAuthDelegate : public WeaveCASEAuthDelegate
uint8_t *mServiceConfigBuf;
};

CASEAuthDelegate gCASEAuthDelegate;

WEAVE_ERROR AddCertToContainer(TLVWriter& writer, uint64_t tag, const uint8_t *cert, uint16_t certLen);
WEAVE_ERROR MakeCertInfo(uint8_t *buf, uint16_t bufSize, uint16_t& certInfoLen,
const uint8_t *entityCert, uint16_t entityCertLen,
Expand All @@ -95,7 +93,7 @@ namespace Internal {

WEAVE_ERROR InitCASEAuthDelegate()
{
new (&gCASEAuthDelegate) CASEAuthDelegate();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new of placement new was intentional, to support systems that do not run global constructors.

Is there a particular problem with this you're trying to work around?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no obviously problem yet, but currently it may not be the best solution, with following reasons.

  1. There are more platforms which support global constructors, the the constructor will be called twice.
  2. With the PR changes, the static variable will still be allocated in the global segment, and the constructor will be called at the first time InitCASEAuthDelegate is called, it solves the problem on all platforms with or without global constructors being called.
  3. The singleton design pattern is widely used after C++11 has introduced thread-safe static variable construction.

After all, I think that using C++11 singleton pattern is better than global variable + placement new.

BTW, I'm interested in the fact that there are platforms which doesn't run global constructors.

I know that for dynamic linked program or library, global constructors are compiled and linked into .init_array section of the ELF file. and the .init_array section contains lots of library initializing code, not only used for C++, but also C programs, it will be executed by the loader (ld-linux).

For static linked program, I think it will be directly linked and called after program start. I don't think it is platform related feature, it is decided by the toolchain.

static CASEAuthDelegate gCASEAuthDelegate;
SecurityMgr.SetCASEAuthDelegate(&gCASEAuthDelegate);
return WEAVE_NO_ERROR;
}
Expand Down