Repository: wolfpld/tracy
File: client/TracyProfiler.hpp (C++)

Code before:
    void SendString( uint64_t ptr, const char* str, QueueType type );


    // Allocated source location data layout:
    //  4b  payload size
    //  4b  color
    //  4b  source line
    //  fsz function name
    //  1b  null terminator
    //  ssz source file name
    //  1b  null terminator
    //  nsz zone name (optional)

    static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, const char* function )
    {
        return AllocSourceLocation( line, source, function, nullptr, 0 );
    }

    static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, const char* function, const char* name, size_t nameSz )
    {
        return AllocSourceLocation( line, source, strlen(source), function, strlen(function), name, nameSz );
    }

    static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz )
    {
        return AllocSourceLocation( line, source, sourceSz, function, functionSz, nullptr, 0 );
    }

    static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz )
    {
        const uint32_t sz = uint32_t( 4 + 4 + 4 + functionSz + 1 + sourceSz + 1 + nameSz );
        auto ptr = (char*)tracy_malloc( sz );
        memcpy( ptr, &sz, 4 );
        memset( ptr + 4, 0, 4 );
        memcpy( ptr + 8, &line, 4 );
        memcpy( ptr + 12, function, functionSz );
        ptr[12 + functionSz] = '\0';
        memcpy( ptr + 12 + functionSz + 1, source, sourceSz );
        ptr[12 + functionSz + 1 + sourceSz] = '\0';
        memcpy( ptr + 12 + functionSz + 1 + sourceSz + 1, name, nameSz );
        return uint64_t( ptr );
    }

private:
    enum class DequeueStatus { DataDequeued, ConnectionLost, QueueEmpty };

    static void LaunchWorker( void* ptr ) { ((Profiler*)ptr)->Worker(); }
    void Worker();

    static void LaunchCompressWorker( void* ptr ) { ((Profiler*)ptr)->CompressWorker(); }
    void CompressWorker();

Review comment (bug):
Passing `nullptr` to `memcpy` is undefined behavior.

Code after:
    void SendString( uint64_t ptr, const char* str, QueueType type );


    // Allocated source location data layout:
    //  4b  payload size
    //  4b  color
    //  4b  source line
    //  fsz function name
    //  1b  null terminator
    //  ssz source file name
    //  1b  null terminator
    //  nsz zone name (optional)

    static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, const char* function )
    {
        return AllocSourceLocation( line, source, function, nullptr, 0 );
    }

    static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, const char* function, const char* name, size_t nameSz )
    {
        return AllocSourceLocation( line, source, strlen(source), function, strlen(function), name, nameSz );
    }

    static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz )
    {
        return AllocSourceLocation( line, source, sourceSz, function, functionSz, nullptr, 0 );
    }

    static tracy_force_inline uint64_t AllocSourceLocation( uint32_t line, const char* source, size_t sourceSz, const char* function, size_t functionSz, const char* name, size_t nameSz )
    {
        const uint32_t sz = uint32_t( 4 + 4 + 4 + functionSz + 1 + sourceSz + 1 + nameSz );
        auto ptr = (char*)tracy_malloc( sz );
        memcpy( ptr, &sz, 4 );
        memset( ptr + 4, 0, 4 );
        memcpy( ptr + 8, &line, 4 );
        memcpy( ptr + 12, function, functionSz );
        ptr[12 + functionSz] = '\0';
        memcpy( ptr + 12 + functionSz + 1, source, sourceSz );
        ptr[12 + functionSz + 1 + sourceSz] = '\0';
        if( nameSz != 0 )
        {
            memcpy( ptr + 12 + functionSz + 1 + sourceSz + 1, name, nameSz );
        }
        return uint64_t( ptr );
    }

private:
    enum class DequeueStatus { DataDequeued, ConnectionLost, QueueEmpty };

    static void LaunchWorker( void* ptr ) { ((Profiler*)ptr)->Worker(); }
    void Worker();