I am trying to use
drwrap_skip_call to skip calls to
pthread_create. It, unfortunately, breaks the application unexpectedly after the 2nd skip (not really sure why 2nd, but consistently so).
This is the simple test app:
#include <iostream>
#include <pthread.h>
#include <string>
pthread_t all_threads[8];
uint32_t all_data[7];
void* foo(void* data)
{
std::cout << "FOO CALLED\n";
return nullptr;
}
void* bar(void* x)
{
int32_t val = *(int32_t*)x;
std::cout << "BAR CALLED WITH " + std::to_string(val) + "\n";
return nullptr;
}
int main(int argc, char** argv)
{
std::cout << "Starting thread\n";
pthread_create(&all_threads[0], nullptr, &foo, nullptr);
for (uint32_t i = 1; i < 8; i++)
{
std::cout << "Starting thread\n";
all_data[i-1] = i;
pthread_create(&all_threads[i], nullptr, &bar, &all_data[i-1]);
}
for (uint32_t i = 0; i < 8; i++)
{
std::cout << "Ending thread\n";
pthread_join(all_threads[i], nullptr);
}
return 0;
}
And this is the simple client causing the issue, I track all module loads, and when the pthread module gets loaded I wrap the pthread_create function with only a pre-wrapper:
#include <dr_api.h>
#include <drwrap.h>
#include <drmgr.h>
#include <string>
void PrePThreadCreateAction(void* wrapctx, void** user_data)
{
dr_printf("CLIENT: Before skipping\n");
drwrap_skip_call(wrapctx, (void*)0, sizeof(void*)*4);
}
void ModuleLoadAction(void* drcontext, const module_data_t* info, bool loaded)
{
std::string module_name = dr_module_preferred_name(info);
if (module_name.rfind("libpthread.", 0) == 0)
{
uint64_t pthread_create_address = (uint64_t)dr_get_proc_address(info->handle, "pthread_create");
drwrap_wrap((app_pc)pthread_create_address, PrePThreadCreateAction, nullptr);
}
}
void ExitAction()
{
drwrap_exit();
drmgr_exit();
}
DR_EXPORT void dr_client_main(client_id_t id, int argc, const char** argv)
{
drmgr_init();
drwrap_init();
drmgr_register_module_load_event(ModuleLoadAction);
dr_register_exit_event(ExitAction);
}
If I comment out the drwrap_skip_call the application executes successfully:
<Starting application /home/mewais/PlayGround/Build/Test (36018)>
<Initial options = -no_dynamic_options -client_lib '/home/mewais/PlayGround/Build/libPlayClient.so;0;' -code_api -stack_size 56K -signal_stack_size 32K -max_elide_jmp 0 -max_elide_call 0 -early_inject -emulate_brk -no_inline_ignored_syscalls -native_exec_default_list '' -no_native_exec_managed_code -no_indcall2direct >
<Paste into GDB to debug DynamoRIO clients:
set confirm off
add-symbol-file '/home/mewais/PlayGround/Build/libPlayClient.so' 0x00007fb9b0072580
add-symbol-file '/work/mewais/projects/DCArch/DynamoRIO/lib64/debug/libdynamorio.so' 0x0000000071040fe0
add-symbol-file '/work/mewais/projects/DCArch/DynamoRIO/ext/lib64/debug/libdrwrap.so' 0x00007fb9b00c1150
add-symbol-file '/work/mewais/projects/DCArch/DynamoRIO/ext/lib64/debug/libdrmgr.so' 0x00007fb9b02d05f0
add-symbol-file '/lib/x86_64-linux-gnu/libstdc++.so.6' 0x00007fb9f3cb12e0
add-symbol-file '/lib/x86_64-linux-gnu/libm.so.6' 0x00007fb9f3eff3c0
add-symbol-file '/lib/x86_64-linux-gnu/libc.so.6' 0x00007fb9f3864650
add-symbol-file '/usr/lib64/ld-linux-x86-64.so.2' 0x00007fb9f3eba090
add-symbol-file '/lib/x86_64-linux-gnu/libgcc_s.so.1' 0x00007fb9f3ea05e0
>
<(1+x) Handling our fault in a TRY at 0x000000007129f6b2>
<spurious rep/repne prefix @0x00007fb9f4040e80 (f3 0f 1e fa): >
<curiosity: rex.w on OPSZ_6_irex10_short4!>
<get_memory_info mismatch! (can happen if os combines entries in /proc/pid/maps)
os says: 0x00007fb9f3e86000-0x00007fb9f3e9d000 prot=0x00000001
cache says: 0x00007fb9f3e86000-0x00007fb9f3ea0000 prot=0x00000001
>
Starting thread
CLIENT: Before skipping
FOO CALLED
Starting thread
CLIENT: Before skipping
Starting thread
CLIENT: Before skipping
Starting thread
CLIENT: Before skipping
Starting thread
CLIENT: Before skipping
Starting thread
CLIENT: Before skipping
Starting thread
CLIENT: Before skipping
Starting thread
CLIENT: Before skipping
Ending thread
Ending thread
BAR CALLED WITH 3
BAR CALLED WITH 1
BAR CALLED WITH 7
BAR CALLED WITH 2
BAR CALLED WITH 4
BAR CALLED WITH 5
BAR CALLED WITH 6
Ending thread
Ending thread
Ending thread
Ending thread
Ending thread
Ending thread
<Stopping application /home/mewais/PlayGround/Build/Test (36018)>
If I leave it on, it breaks. Here is the output from a run:
<Starting application /home/mewais/PlayGround/Build/Test (35243)>
<Initial options = -no_dynamic_options -client_lib '/home/mewais/PlayGround/Build/libPlayClient.so;0;' -code_api -stack_size 56K -signal_stack_size 32K -max_elide_jmp 0 -max_elide_call 0 -early_inject -emulate_brk -no_inline_ignored_syscalls -native_exec_default_list '' -no_native_exec_managed_code -no_indcall2direct >
<Paste into GDB to debug DynamoRIO clients:
set confirm off
add-symbol-file '/home/mewais/PlayGround/Build/libPlayClient.so' 0x00007fb7403415a0
add-symbol-file '/work/mewais/projects/DCArch/DynamoRIO/lib64/debug/libdynamorio.so' 0x0000000071040fe0
add-symbol-file '/work/mewais/projects/DCArch/DynamoRIO/ext/lib64/debug/libdrwrap.so' 0x00007fb740390150
add-symbol-file '/work/mewais/projects/DCArch/DynamoRIO/ext/lib64/debug/libdrmgr.so' 0x00007fb74059f5f0
add-symbol-file '/lib/x86_64-linux-gnu/libstdc++.so.6' 0x00007fb783f802e0
add-symbol-file '/lib/x86_64-linux-gnu/libm.so.6' 0x00007fb7841ce3c0
add-symbol-file '/lib/x86_64-linux-gnu/libc.so.6' 0x00007fb783b33650
add-symbol-file '/usr/lib64/ld-linux-x86-64.so.2' 0x00007fb784189090
add-symbol-file '/lib/x86_64-linux-gnu/libgcc_s.so.1' 0x00007fb78416f5e0
>
<(1+x) Handling our fault in a TRY at 0x000000007129f6b2>
<spurious rep/repne prefix @0x00007fb78430fe80 (f3 0f 1e fa): >
<curiosity: rex.w on OPSZ_6_irex10_short4!>
<get_memory_info mismatch! (can happen if os combines entries in /proc/pid/maps)
os says: 0x00007fb784155000-0x00007fb78416c000 prot=0x00000001
cache says: 0x00007fb784155000-0x00007fb78416f000 prot=0x00000001
>
Starting thread
CLIENT: Before skipping
Starting thread
<Application /home/mewais/PlayGround/Build/Test (35243). Application exception at PC 0x00007fb78034054a.
Signal 11 delivered to application as default action.
Callstack:
0x00007fb78034054a </home/mewais/PlayGround/Build/Test+0x154a>
0x00007fb783730565 </usr/lib/x86_64-linux-gnu/libc-2.33.so+0x28565> >
<Stopping application /home/mewais/PlayGround/Build/Test (35243)>
<Application /home/mewais/PlayGround/Build/Test (35243). Internal Error: DynamoRIO debug check failure: /home/travis/build/DynamoRIO/dynamorio/core/heap.c:1913 IF_WINDOWS(doing_detach ||) vmh->num_free_blocks == vmh->num_blocks - unfreed_blocks || ((ever_beyond_vmm IF_WINDOWS(|| get_os_version() >= WINDOWS_VERSION_8_1)) && vmh->num_free_blocks >= vmh->num_blocks - unfreed_blocks)
(Error occurred @3820 frags)
version 8.0.0, build 1
-no_dynamic_options -client_lib '/home/mewais/PlayGround/Build/libPlayClient.so;0;' -code_api -stack_size 56K -signal_stack_size 32K -max_elide_jmp 0 -max_elide_call 0 -early_inject -emulate_brk -no_inline_ignored_syscalls -native_exec_default_list '' -no_native_exec_managed_code -no_indcall2direct
0x00007fb6c03e7e10 0x00000000710dc095
0x00007fb6c03e8060 0x000000007116f1dd
0x00007fb6c03e80a0 0x000000007116f268
0x00007fb6c03e80b0 0x00000000710535d2
0x00007fb6c03e80f0 0x000000007105390e
0x00007fb6c03e8120 0x0000000071053a94
0x00007fb6c03e8140 0x00000000712e2f29
0x00007fb6c03e82a0 0x00000000712e32fe
0x00007fb6c03e82d0 0x00000000712d9b98
0x00007fb6c03e8340 0x00000000712dff40
0x00007fb6c03e84d0 0x00000000712dcc09
0x00007fb6c03e87e0 0x00000000712dfac2
0x00007fb6c03e89b0 0x000000007129f1d3
0x00007ffe6a4f8c50 0x00007fb783730565>
Unfortunately, I could not gdb that as gdb breaks right away on the first SIGILL (looks irrelevant though). But the DR printed backtrace shows it happens in the app not the client (even though the second dr_printf isn't shown, but I am assuming that's just buffering!).