alibaba / PhotonLibOS

Probably the fastest coroutine lib in the world!

Home Page:https://PhotonLibOS.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issue building on Ubuntu/ARM

sptrakesh opened this issue · comments

Hello,

I am trying to build Photon on Ubuntu/ARM combination (noble and gcc13). Compilation fails (version 0.7.3) with the following error:

1.814 /opt/PhotonLibOS/include/photon/net/socket.h:168:36: error: static assertion failed: Endpoint size incorrect
1.814   168 |     static_assert(sizeof(EndPoint) == 18, "Endpoint size incorrect");
1.814       |                   ~~~~~~~~~~~~~~~~~^~~~~
1.815 /opt/PhotonLibOS/include/photon/net/socket.h:168:36: note: the comparison reduces to '(20 == 18)’

struct __attribute__ ((packed)) EndPoint {};

gcc 13 doesn't allow this syntax? Could you try to move __attribute__ ((packed)) after {} ?

Yes, moving the attribute does solve the issue. There are a couple of other issues I needed to make. In particular the one related to the alog error shown here probably needs additional investigation, as GCC says it is deprecated behaviour.

/opt/PhotonLibOS/include/photon/common/alog-functionptr.h: In function 'LogBuffer& __printfp__(LogBuffer&, T)':
/opt/PhotonLibOS/include/photon/common/alog-functionptr.h:29:5: error: there are no arguments to 'free' that depend on a template parameter, so a declaration of 'free' must be available [-fpermissive]
   29 |     free(name);
      |     ^~~~
/opt/PhotonLibOS/include/photon/common/alog-functionptr.h:29:5: note: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)

The diff for changes I needed to make to compile Photon:

diff --git a/CMakeLists.txt b/CMakeLists.txt
index ed48b29..d41c9aa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -217,6 +217,10 @@ if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0)
     # This option is enabled by default after -std=c++17
     target_compile_options(photon_obj PRIVATE -faligned-new)
 endif()
+if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13.0)
+    # GCC 13 error: there are no arguments to 'free' that depend on a template parameter, so a declaration of 'free' must be available [-fpermissive]
+    target_compile_options(photon_obj PRIVATE -fpermissive)
+endif()
 
 if (actually_built)
     add_dependencies(photon_obj ${actually_built})
diff --git a/common/ring.cpp b/common/ring.cpp
index b87eafb..2ff5eac 100644
--- a/common/ring.cpp
+++ b/common/ring.cpp
@@ -60,7 +60,7 @@ ssize_t RingBuffer::do_read(void *buf, size_t count)
 ssize_t RingBuffer::readv(const struct iovec *iov, int iovcnt)
 {
     ssize_t size = 0;
-    scoped_lock lock(m_read_lock);
+    photon::scoped_lock lock(m_read_lock);
     for (auto& x: ptr_array(iov, iovcnt))
     {
         auto ret = do_read(x.iov_base, x.iov_len);
@@ -110,7 +110,7 @@ ssize_t RingBuffer::do_write(const void* buf, size_t count)
 ssize_t RingBuffer::writev(const struct iovec *iov, int iovcnt)
 {
     ssize_t size = 0;
-    scoped_lock lock(m_write_lock);
+    photon::scoped_lock lock(m_write_lock);
     for (auto& x: ptr_array(iov, iovcnt))
     {
         auto ret = do_write(x.iov_base, x.iov_len);
diff --git a/net/curl.cpp b/net/curl.cpp
index f2eeb33..9e03925 100644
--- a/net/curl.cpp
+++ b/net/curl.cpp
@@ -19,6 +19,7 @@ limitations under the License.
 #include <shared_mutex>
 #include <vector>
 #include <memory>
+#include <string>
 
 #include <photon/common/alog.h>
 #include <photon/common/event-loop.h>
diff --git a/net/socket.h b/net/socket.h
index 75592a6..555197e 100644
--- a/net/socket.h
+++ b/net/socket.h
@@ -42,12 +42,12 @@ LogBuffer& operator << (LogBuffer& log, const sockaddr& addr);
 namespace photon {
 namespace net {
 
-    struct __attribute__ ((packed)) IPAddr {
+    struct IPAddr {
     public:
         union {
             in6_addr addr = {};
             struct { uint16_t _1, _2, _3, _4, _5, _6; uint8_t a, b, c, d; };
-        };
+        } __attribute__ ((packed));
         // For compatibility, the default constructor is still 0.0.0.0 (IPv4)
         IPAddr() {
             map_v4(htonl(INADDR_ANY));
@@ -141,11 +141,11 @@ namespace net {
             addr._in_addr_field[2] = htonl(0xffff);
             addr._in_addr_field[3] = nl;
         }
-    };
+    } __attribute__ ((packed));
 
     static_assert(sizeof(IPAddr) == 16, "IPAddr size incorrect");
 
-    struct __attribute__ ((packed)) EndPoint {
+    struct EndPoint {
         IPAddr addr;
         uint16_t port = 0;
         EndPoint() = default;
@@ -163,7 +163,7 @@ namespace net {
         bool undefined() const {
             return addr.undefined() && port == 0;
         }
-    };
+    } __attribute__ ((packed));
 
     static_assert(sizeof(EndPoint) == 18, "Endpoint size incorrect");
 

One test fails. Details below:

Test project /opt/PhotonLibOS/build
    Start 25: test-rpc-message
1/1 Test #25: test-rpc-message .................***Failed    0.02 sec
2023/12/18 16:30:28|INFO |th=0000AAAAF2A51930|/opt/PhotonLibOS/io/epoll.cpp:289|new_epoll_engine:Init event engine: epoll
2023/12/18 16:30:28|INFO |th=0000AAAAF2A51930|/opt/PhotonLibOS/io/signal.cpp:265|sync_signal_init:signalfd initialized
[==========] Running 2 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 2 tests from rpc
[ RUN      ] rpc.message
2023/12/18 16:30:28|INFO |th=0000AAAAF2A51930|/opt/PhotonLibOS/rpc/rpc.cpp:472|get_socket:Connect to 127.0.0.1:59413
2023/12/18 16:30:28|DEBUG|th=0000FFFFB2E1C700|/opt/PhotonLibOS/rpc/test/test-rpc-message.cpp:44|check_map_order:val-1
2023/12/18 16:30:28|DEBUG|th=0000FFFFB2E1C700|/opt/PhotonLibOS/rpc/test/test-rpc-message.cpp:44|check_map_order:val-2
2023/12/18 16:30:28|DEBUG|th=0000FFFFB2E1C700|/opt/PhotonLibOS/rpc/test/test-rpc-message.cpp:44|check_map_order:val-3
2023/12/18 16:30:28|DEBUG|th=0000AAAAF2A51930|/opt/PhotonLibOS/rpc/test/test-rpc-message.cpp:44|check_map_order:val-5-1
2023/12/18 16:30:28|DEBUG|th=0000AAAAF2A51930|/opt/PhotonLibOS/rpc/test/test-rpc-message.cpp:44|check_map_order:val-5-2
2023/12/18 16:30:28|DEBUG|th=0000AAAAF2A51930|/opt/PhotonLibOS/rpc/test/test-rpc-message.cpp:44|check_map_order:val-5-3
2023/12/18 16:30:28|INFO |th=0000AAAAF2A51930|/opt/PhotonLibOS/rpc/test/test-rpc-message.cpp:216|TestBody:Test finished, shutdown server...
2023/12/18 16:30:28|ERROR|th=0000FFFFB3621280|/opt/PhotonLibOS/rpc/rpc.cpp:254|read_request:Failed to read rpc header 0000AAAAF2A4D3F0[ret=-1]errno=4(Interrupted system call)
[       OK ] rpc.message (3 ms)
[ RUN      ] rpc.variable_length_serialization
2023/12/18 16:30:28|DEBUG|th=0000AAAAF2A51930|/opt/PhotonLibOS/rpc/test/test-rpc-message.cpp:238|TestBody:send iov ->
2023/12/18 16:30:28|DEBUG|th=0000AAAAF2A51930|/opt/PhotonLibOS/common/iovector.cpp:338|debug_print:iov sum: 281474211218744, {addr: 0xaaaac22acd80, len: 281474211218720}, {addr: 0xffffd25f8470, len: 24}, 
/opt/PhotonLibOS/rpc/test/test-rpc-message.cpp:241: Failure
Expected equality of these values:
  bytes
    Which is: 4096
  s_send.iov.sum()
    Which is: 281474211218744

[  FAILED  ] rpc.variable_length_serialization (0 ms)
[----------] 2 tests from rpc (3 ms total)

[----------] Global test environment tear-down
[==========] 2 tests from 1 test suite ran. (3 ms total)
[  PASSED  ] 1 test.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] rpc.variable_length_serialization

 1 FAILED TEST
2023/12/18 16:30:28|DEBUG|th=0000FFFFB4E39740|/opt/PhotonLibOS/io/signal.cpp:139|wait_for_signal:wait for signalfd failed because errno=4(Interrupted system call), stop watching
2023/12/18 16:30:28|INFO |th=0000AAAAF2A51930|/opt/PhotonLibOS/io/signal.cpp:301|sync_signal_fini:signalfd finished
2023/12/18 16:30:28|INFO |th=0000AAAAF2A51930|/opt/PhotonLibOS/io/epoll.cpp:75|~EventEngineEPoll:Finish event engine: epoll


0% tests passed, 1 tests failed out of 1

Total Test time (real) =   0.02 sec

The following tests FAILED:
	 25 - test-rpc-message (Failed)
Errors while running CTest

/opt/PhotonLibOS/include/photon/common/alog-functionptr.h:29:5: error: there are no arguments to 'free' that depend on a template parameter, so a declaration of 'free' must be available [-fpermissive]

try adding #include <stdlib.h>

/opt/PhotonLibOS/rpc/test/test-rpc-message.cpp:241: Failure

I'll take look at this.

{addr: 0xaaaac22acd80, len: 281474211218720}

This length is not correct.
Is the error deterministically reproducible?
If so, can you add a log output as following to see more detail?

@@ -232,6 +232,7 @@ TEST(rpc, variable_length_serialization) {
     VariableLengthMessage m_send;
     m_send.a = 1;
     m_send.b.assign(send_string);
+    LOG_DEBUG(VALUE(m_send.b._ptr), VALUE(m_send.b._len));

     photon::rpc::SerializerIOV s_send;
     s_send.serialize(m_send);

This is weird. The invalid length looks like the side effect of an uninitialised variable. Adding the log somehow seems to remove that issue. I tried this a few times, without the log statement the test will fail, while with the log statement it will pass.

This sounds like a compiler bug. Can you make another try by replacing the log with an empty inline assembly as follow:

@@ -232,6 +232,7 @@ TEST(rpc, variable_length_serialization) {
     VariableLengthMessage m_send;
     m_send.a = 1;
     m_send.b.assign(send_string);
+    asm volatile ("");

     photon::rpc::SerializerIOV s_send;
     s_send.serialize(m_send);

This acts like a barrier to (hopefully) prevent some aggressive optimization.

This sounds like a compiler bug. Can you make another try by replacing the log with an empty inline assembly as follow:

@@ -232,6 +232,7 @@ TEST(rpc, variable_length_serialization) {
     VariableLengthMessage m_send;
     m_send.a = 1;
     m_send.b.assign(send_string);
+    asm volatile ("");

     photon::rpc::SerializerIOV s_send;
     s_send.serialize(m_send);

This acts like a barrier to (hopefully) prevent some aggressive optimization.

No, does not work. Adding the log still works...

No, does not work. Adding the log still works...

try this:
asm volatile ("" : "+r"(m_send.b._ptr), "+r"(m_send.b._len));

No, does not work. Adding the log still works...

try this: asm volatile ("" : "+r"(m_send.b._ptr), "+r"(m_send.b._len));

Yes, this works.

try this: asm volatile ("" : "+r"(m_send.b._ptr), "+r"(m_send.b._len));

Yes, this works.

So it confirms that the compiler has bugs. This piece of assembly code is actually a noop. It only prevents the optimizer from reordering of load / stores across the line.