DynamoRIO / drmemory

Memory Debugger for Windows, Linux, Mac, and Android
Other
2.42k stars 260 forks source link

Potential false positives reported by Dr.Memory within Threading Building Blocks (Intel® TBB) #2004

Open alexei37 opened 7 years ago

alexei37 commented 7 years ago

Even when used on a toy example (from https://software.intel.com/en-us/node/506153):


#include "stdafx.h"

#include "tbb/parallel_for.h"
#include "tbb/blocked_range.h"

using namespace tbb;

struct Average
{
    const float* input;
    float* output;
    void operator()(const blocked_range<int>& range) const 
    {
        for (int i = range.begin(); i != range.end(); ++i)
            output[i] = (input[i - 1] + input[i] + input[i + 1])*(1 / 3.f);
    }
};

// Note: Reads input[0..n] and writes output[1..n-1]. 
void ParallelAverage(float* output, const float* input, size_t n) 
{
    Average avg;
    avg.input = input;
    avg.output = output;
    parallel_for(blocked_range<int>(1, n), avg);
}

int main()
{
    const float  input[]  = { 1.0, 2.0, 3.0 };
          float  output[] = { 0.0, 0.0, 0.0 };
          size_t n        = sizeof(output) / sizeof(float);

    ParallelAverage(output, input, n);

    return 0;
}

one gets the following report with UNADDRESSABLE ACCESS beyond heap bounds errors:


"\drmemory.exe" -debug -dr_debug -pause_at_assert -unaddr_only -no_summary -logdir "logs\drmemorylogs" -- "\.exe"

<Starting application ...>
<Early threads found>
<Initial options = -no_dynamic_options -logdir 'C:\Users\akovalyov\logs\drmemorylogs\dynamorio' -client_lib 'C:\Program Files (x86)\Dr. Memory\bin64\debug\drmemorylib.dll;0;`-pause_at_assert` `-unaddr_only` `-no_summary` -logdir `C:\Users\akovalyov\logs\drmemorylogs` -symcache_dir `C:\Users\akovalyov\logs\drmemorylogs\symcache` -lib_blacklist `C:\WINDOWS*.d??,C:\Program Files\Common Files\Microsoft Shared*.d??,C:\Program Files (x86)\Common Files\Microsoft Shared*.d??` -resfile 13620 ' -code_api -probe_api -stack_size 56K -disable_traces -no_enable_traces -max_elide_jmp 0 -max_elide_call 0 -max_bb_instrs 256 -no_shared_traces -bb_ibl_targets -bb_single_restore_prefix -no_shared_trace_ibl_routine -no_enable_reset -no_reset_at_switch_to_os_at_vmm_limit -reset_at_vmm_percent_free_limit 0 -no_reset_at_vmm_full -reset_at_commit_free_limit 0K -reset_every_nth_pending 0 -vm_size 262144K -no_inline_ignored_syscalls -native_exec_default_list '' -no_native_exec_managed_code -no_indcall2direct -pad_jmps_mark_no_trace >
~~Dr.M~~ Error #1: UNADDRESSABLE ACCESS beyond heap bounds: writing 0x000000e3284d08c5-0x000000e3284d08c6 1 byte(s)
~~Dr.M~~ # 0 tbb::task::task                                                           [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\task.h:569]
~~Dr.M~~ # 1 tbb::interface9::internal::flag_task::flag_task                           [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\partitioner.h:130]
~~Dr.M~~ # 2 tbb::interface9::internal::allocate_sibling                               [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:117]
~~Dr.M~~ # 3 tbb::interface9::internal::start_for<>::offer_work                        [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:106]
~~Dr.M~~ # 4 tbb::interface9::internal::partition_type_base<>::execute<>               [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\partitioner.h:251]
~~Dr.M~~ # 5 tbb::interface9::internal::start_for<>::execute                           [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:127]
~~Dr.M~~ # 6 tbb.dll!tbb::internal::custom_scheduler<>::local_wait_for_all             [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\externalprojects\source\ep-tbb\src\tbb\custom_scheduler.h:501]
~~Dr.M~~ # 7 tbb.dll!tbb::internal::generic_scheduler::local_spawn_root_and_wait       [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\externalprojects\source\ep-tbb\src\tbb\scheduler.cpp:676]
~~Dr.M~~ # 8 tbb.dll!tbb::internal::generic_scheduler::spawn_root_and_wait             [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\externalprojects\source\ep-tbb\src\tbb\scheduler.cpp:684]
~~Dr.M~~ # 9 tbb::task::spawn_root_and_wait                                            [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\task.h:749]
~~Dr.M~~ #10 tbb::interface9::internal::start_for<>::run                               [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:90]
~~Dr.M~~ #11 tbb::parallel_for<>                                                       [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:186]
~~Dr.M~~ #12 ParallelAverage                                                           [c:\users\akovalyov\documents\visual studio 2015\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp:30]
~~Dr.M~~ #13 main                                                                      [c:\users\akovalyov\documents\visual studio 2015\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp:39]
~~Dr.M~~ Note: @0:00:01.049 in thread 6048
~~Dr.M~~ Note: next higher malloc: 0x000000e3284d08d0-0x000000e3284d08d0
~~Dr.M~~ Note: instruction: mov    $0x01 -> 0x2d(%rax)
~~Dr.M~~
~~Dr.M~~ Error #2: UNADDRESSABLE ACCESS beyond heap bounds: reading 0x000000e3284d0898-0x000000e3284d08a0 8 byte(s)
~~Dr.M~~ # 0 tbb::task::set_parent                                                     [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\task.h:797]
~~Dr.M~~ # 1 tbb::interface9::internal::allocate_sibling                               [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:118]
~~Dr.M~~ # 2 tbb::interface9::internal::start_for<>::offer_work                        [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:106]
~~Dr.M~~ # 3 tbb::interface9::internal::partition_type_base<>::execute<>               [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\partitioner.h:251]
~~Dr.M~~ # 4 tbb::interface9::internal::start_for<>::execute                           [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:127]
~~Dr.M~~ # 5 tbb.dll!tbb::internal::custom_scheduler<>::local_wait_for_all             [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\externalprojects\source\ep-tbb\src\tbb\custom_scheduler.h:501]
~~Dr.M~~ # 6 tbb.dll!tbb::internal::generic_scheduler::local_spawn_root_and_wait       [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\externalprojects\source\ep-tbb\src\tbb\scheduler.cpp:676]
~~Dr.M~~ # 7 tbb.dll!tbb::internal::generic_scheduler::spawn_root_and_wait             [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\externalprojects\source\ep-tbb\src\tbb\scheduler.cpp:684]
~~Dr.M~~ # 8 tbb::task::spawn_root_and_wait                                            [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\task.h:749]
~~Dr.M~~ # 9 tbb::interface9::internal::start_for<>::run                               [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:90]
~~Dr.M~~ #10 tbb::parallel_for<>                                                       [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:186]
~~Dr.M~~ #11 ParallelAverage                                                           [c:\users\akovalyov\documents\visual studio 2015\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp:30]
~~Dr.M~~ #12 main                                                                      [c:\users\akovalyov\documents\visual studio 2015\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp:39]
~~Dr.M~~ Note: @0:00:01.063 in thread 6048
~~Dr.M~~ Note: prev lower malloc:  0x000000e3284d0680-0x000000e3284d0888
~~Dr.M~~ Note: instruction: mov    (%rax) -> %rax
Assertion !p || prefix().context == p->prefix().context failed on line 797 of file f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\task.h
Detailed description: The tasks must be in the same context
<Application changing protections of system memory at least once (0x00007fffe7ed7000-0x00007fffe7edb000)>
<legacy process creation detected: may miss child>
<Stopping application C:\Users\akovalyov\Documents\Visual Studio 2015\Projects\ConsoleApplication1\x64\Debug\ConsoleApplication1.exe (13620)>
~~Dr.M~~ WARNING: application exited with abnormal code 0xc0000005

Here is the log:



D_r. Memory version 1.11.0 build 2 built on Aug 29 2016 02:41:42
Dr. Memory results for pid 22152: "ConsoleApplication1.exe"
Application cmdline: "<...>.exe""
Recorded 115 suppression(s) from default C:\Program Files (x86)\Dr. Memory\bin64\suppress-default.txt

Error #1: UNADDRESSABLE ACCESS beyond heap bounds: writing 0x0000002c74de08c5-0x0000002c74de08c6 1 byte(s)

0 tbb::task::task [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\task.h:569]

1 tbb::interface9::internal::flag_task::flag_task [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\partitioner.h:130]

2 tbb::interface9::internal::allocate_sibling [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:117]

3 tbb::interface9::internal::start_for<>::offer_work [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:106]

4 tbb::interface9::internal::partition_type_base<>::execute<> [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\partitioner.h:251]

5 tbb::interface9::internal::start_for<>::execute [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:127]

6 tbb.dll!tbb::internal::custom_scheduler<>::local_wait_for_all [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\externalprojects\source\ep-tbb\src\tbb\custom_scheduler.h:501]

7 tbb.dll!tbb::internal::generic_scheduler::local_spawn_root_and_wait [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\externalprojects\source\ep-tbb\src\tbb\scheduler.cpp:676]

8 tbb.dll!tbb::internal::generic_scheduler::spawn_root_and_wait [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\externalprojects\source\ep-tbb\src\tbb\scheduler.cpp:684]

9 tbb::task::spawn_root_and_wait [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\task.h:749]

10 tbb::interface9::internal::start_for<>::run [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:90]

11 tbb::parallel_for<> [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:186]

12 ParallelAverage [c:\users\akovalyov\documents\visual studio 2015\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp:30]

13 main [c:\users\akovalyov\documents\visual studio 2015\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp:39]

Note: @0:00:00.992 in thread 25840 Note: next higher malloc: 0x0000002c74de08d0-0x0000002c74de08d0 Note: instruction: mov $0x01 -> 0x2d(%rax)

Error #2: UNADDRESSABLE ACCESS beyond heap bounds: reading 0x0000002c74de0898-0x0000002c74de08a0 8 byte(s)

0 tbb::task::set_parent [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\task.h:797]

1 tbb::interface9::internal::allocate_sibling [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:118]

2 tbb::interface9::internal::start_for<>::offer_work [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:106]

3 tbb::interface9::internal::partition_type_base<>::execute<> [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\partitioner.h:251]

4 tbb::interface9::internal::start_for<>::execute [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:127]

5 tbb.dll!tbb::internal::custom_scheduler<>::local_wait_for_all [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\externalprojects\source\ep-tbb\src\tbb\custom_scheduler.h:501]

6 tbb.dll!tbb::internal::generic_scheduler::local_spawn_root_and_wait [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\externalprojects\source\ep-tbb\src\tbb\scheduler.cpp:676]

7 tbb.dll!tbb::internal::generic_scheduler::spawn_root_and_wait [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\externalprojects\source\ep-tbb\src\tbb\scheduler.cpp:684]

8 tbb::task::spawn_root_and_wait [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\task.h:749]

9 tbb::interface9::internal::start_for<>::run [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:90]

10 tbb::parallel_for<> [f:\projects\matsdk_vs2015_64bit\branchmain\binaries\m\thirdparty\install\tbb-2017_u5-msvc14u3-x64\include\tbb\parallel_for.h:186]

11 ParallelAverage [c:\users\akovalyov\documents\visual studio 2015\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp:30]

12 main [c:\users\akovalyov\documents\visual studio 2015\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp:39]

Note: @0:00:01.012 in thread 25840 Note: prev lower malloc: 0x0000002c74de0680-0x0000002c74de0888 Note: instruction: mov (%rax) -> %rax


FINAL SUMMARY:

DUPLICATE ERROR COUNTS:

SUPPRESSIONS USED:

ERRORS FOUND: 2 unique, 2 total unaddressable access(es) 0 unique, 0 total invalid heap argument(s) 0 unique, 0 total warning(s) ERRORS IGNORED: Details: <...>\results.txt


___

This is probably due to nonstandard functions, **NFS_Allocate()** and **NFS_Free()** (which do not seem to be among
_[o A call to malloc (or calloc or realloc, or Windows equivalents HeapAlloc or HeapReAlloc or the Local or Global versions) inside of a heap region](http://drmemory.org/docs/page_unaddr.html)_
tracked by _Dr. Memory_),
being used to allocate/free a padded (by **task_prefix_reservation_size** = **sizeof(task_prefix)** [bytes in front](https://github.com/jckarter/tbb/blob/master/include/tbb/task.h#L180) ) data structure, [**task**](https://github.com/jckarter/tbb/blob/master/include/tbb/task.h#L520) , in task& **[generic_scheduler::allocate_task()](https://github.com/jckarter/tbb/blob/master/src/tbb/scheduler.cpp#L352)**. As soon as we access the prefix memory (by invoking the **task::prefix()** method), _Dr. Memory_ complains about unaddressable access (see the stacks above).

I'm having trouble figuring out whether this is a real issue within _TBB_, or indeed a false positive reported due to current _Dr. Memory_ limitations; in the latter case, it may make sense to suppress them (e.g., by automatically putting them into **potential_errors.txt**) until _Dr. Memory_ learns to handle these calls correctly.

Your advice will be much appreciated!

-- Aleksey 
18C '96
alexei37 commented 7 years ago

TBB developers seem to concur that this is a false positive: here is their response in the 01org/tbb repository's issue tracker (x-referenced above):


alexey-katranov commented 15 hours ago I suppose it is a false positive because a pointer to a task is not a pointer to the first byte of allocated memory. You can see in scheduler.cpp:322 that a task pointer is shifted to the right on the task_prefix_reservation_size number of bytes. Therefore, when we calculate a prefix pointer in task.h:904 we shift to the left safely (sizeof(task_prefix)<=task_prefix_reservation_size scheduler_common.h:163)


Please confirm that this is indeed the case (time permitting).

derekbruening commented 7 years ago

Yes, a custom allocator that pads can result in problems tracking which addresses are addressable. The typical solution is to annotate the allocator so that the tool knows which range of memory it allocated. That feature is not yet present in Dr. Memory (https://github.com/DynamoRIO/drmemory/issues/107). Do your custom allocators already have Valgrind annotations? If so the plan is for Dr. Memory to support those.

alexei37 commented 7 years ago

Thanks for your response!

As the issue is with a third-party library (TBB), i.e. the custom allocators are in their code, I've readdressed your question to them (in this thread).

alexey-katranov commented 7 years ago

As far as I know, Valgrind does not raise the discussed issue. Moreover, Intel TBB library does not have any Valgrind annotations at all. You can contribute the required annotations but I cannot promise if they will become a part of the Intel TBB library because it will be the first example and they are not required for Valgrind. How Dr. Memory detect the issue? Does it have some knowledge about source code or does it capture user-defined operator new? Can Intel TBB runtime help somehow not to detect the issue?

Nekto89 commented 6 years ago

"Assertion !p || prefix().context == p->prefix().context failed on line 797 of file ..........include\tbb\task.h Detailed description: The tasks must be in the same context" this leads to crash.

I understand how to suppress results but are there some options to completely ignore TBB custom allocations so that it won't crash with lots of false memory leaks?