Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSAN Errors Reported by Clang Memory Sanitizer #1609

Closed
jlsantiago0 opened this issue Oct 14, 2020 · 6 comments
Closed

MSAN Errors Reported by Clang Memory Sanitizer #1609

jlsantiago0 opened this issue Oct 14, 2020 · 6 comments
Assignees
Labels
[core] Area: Changes in SRT library core Priority: Medium Type: Bug Indicates an unexpected problem or unintended behavior
Milestone

Comments

@jlsantiago0
Copy link
Contributor

Describe the bug

test-msan-2021014-01.log

During global variable initialization before start of main, there are various global variables in different source files that cause other global object variables in other source files to be accessed before the constructor of the object has run. Many of these objects are STL objects and not in a valid state when this happens. A solution to this problem is to consolidate all of the global variables into one source file and list them in the order that their constructors need to run. C++ does not guarantee the order of global variable construction between source files.

For instance the attached log shows this global variable being initialized:

#12 0x48df44 in __cxx_global_var_init.22 /mnt/share/open/srt-testing/srt/apps/logsupport.cpp:102:12

The constructor eventually calls
/mnt/share/open/srt-testing/srt/apps/logsupport.cpp:95

Which uses another global variable: /mnt/share/open/srt-testing/srt/apps/logsupport.cpp:28

Whose constructor has not been called yet.

There are many cases like this.

To Reproduce

Run srt-live-transmit for instance:

./stage/bin/srt-live-transmit udp://239.66.133.30:4902 srt://:12345

Expected behavior

All global objects should have been properly constructed before used.

Screenshots
None.

Desktop (please provide the following information):

  • OS: Linux
  • SRT Current Master Branch.

Additional context
None.

test-msan-2021014-01.log

@jlsantiago0 jlsantiago0 added the Type: Bug Indicates an unexpected problem or unintended behavior label Oct 14, 2020
@maxsharabayko
Copy link
Collaborator

Related to #1547

@maxsharabayko maxsharabayko added the [core] Area: Changes in SRT library core label Oct 22, 2020
@maxsharabayko maxsharabayko added this to the v1.4.3 milestone Oct 22, 2020
@ethouris
Copy link
Collaborator

I don't know exactly how the results from Sanitizer should be interpreted, but my analysis of the code doesn't confirm your statements at all:

During global variable initialization before start of main, there are various global variables in different source files that cause other global object variables in other source files to be accessed before the constructor of the object has run. Many of these objects are STL objects and not in a valid state when this happens. A solution to this problem is to consolidate all of the global variables into one source file and list them in the order that their constructors need to run. C++ does not guarantee the order of global variable construction between source files.

True, but you have actually shown an example where all global variables are in the same source file. In this case, AFAIK, C++ guarantees that they are initialized in the order of declaration (between one another in this unit only).

For instance the attached log shows this global variable being initialized:

#12 0x48df44 in __cxx_global_var_init.22 /mnt/share/open/srt-testing/srt/apps/logsupport.cpp:102:12
The constructor eventually calls /mnt/share/open/srt-testing/srt/apps/logsupport.cpp:95
Which uses another global variable: /mnt/share/open/srt-testing/srt/apps/logsupport.cpp:28

Neither the constructor of LogFANames class (logsupport.cpp:95), nor the Install method (even though it's defined in another file it doesn't matter here) use the srt_level_names global variable (the one defined at logsupport.cpp:28). It's underlated to this variable at all. The only place where this variable is used is SrtParseLogLevel, which OTOH is also unrelated to srt_transmit_logfa_names (the variable defined at logsupport.cpp:102).

As I analyze the call stack you provided, it looks like this call passes down the value that is later accused of not having been initialized (symbols simplified):

    #9 0x5747ec in std::map<std::string, int>::operator[](std::string const&) /usr/lib64/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../include/c++/10.2.0/bits/stl_map.h:497:17

It is unclear from the call stack which of two are being accused, but there are two possibilities:

  • the id local variable (that's also what the announcement says)
  • the map that supplies the node in the operator[] function

The initialization of both takes place:

  • the id variable is of string type, which has a constructor, and as being a class it doesn't have distinct "default construction" and "default initialization". At worst it may be empty, but the next instruction fills it basing on the parameter passed.
  • the map to which it is being inserted is initialized in the overall object constructor before the Install function is called.

Whose constructor has not been called yet.

And referring to this, you are speaking about a variable that is earlier defined as this one, and in the same translation unit, so according to the C++ initialization rules it's not possible that its constructor isn't called yet.

There are many cases like this.

I think in these cases the sanitizer is simply wrong, or at least I have no idea what criteria it has used to define this case as the creation of uninitialized value, but this at least isn't the case according to C++ standard.

Other cases I saw is referring to likely true_names and false_names variables. They are global variables also independent on the others, with explicitly given construction parameters and only used in the code after main(). No idea what exactly the sanitizer can see there uninitialized.

Not analyzed the whole report yet, but others look very similar.

@jlsantiago0
Copy link
Contributor Author

HMM. You are right. The first messages seem to the complaining about using unitialized content of the stack variable string id; at srt/apps/logsupport.cpp:96 in the context of namemap[id] = value; at srt/apps/logsupport.cpp:98. This is either spurious or the result of an implementation detail of the c++ std library.

I guess we should consider this spurious and close the issue.

@ethouris
Copy link
Collaborator

The log, however, contains more information and this likely should be analyzed; I'll continue looking into the rest of them.

@ethouris
Copy link
Collaborator

Ok, per the amount of changes that went in in the meantime, I think the sanitizer analysis should be now repeated. This info is now likely outdated.

@mbakholdina
Copy link
Collaborator

Closing this issue. The work on the sanitizer issues will be tracked under #1813 further.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[core] Area: Changes in SRT library core Priority: Medium Type: Bug Indicates an unexpected problem or unintended behavior
Projects
None yet
Development

No branches or pull requests

4 participants