Skip to content

Commit

Permalink
new: introduce a new sinsp binary to improve scap-file debugging
Browse files Browse the repository at this point in the history
Signed-off-by: Andrea Terzolo <andreaterzolo3@gmail.com>
  • Loading branch information
Andreagit97 authored and poiana committed Aug 3, 2023
1 parent e2ae8c7 commit 6ddef94
Show file tree
Hide file tree
Showing 4 changed files with 261 additions and 0 deletions.
1 change: 1 addition & 0 deletions userspace/libsinsp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ endif()
option(BUILD_LIBSINSP_EXAMPLES "Build libsinsp examples" ON)
if (BUILD_LIBSINSP_EXAMPLES)
add_subdirectory(examples)
add_subdirectory(sinsp_debug)
endif()

if(NOT DEFINED SINSP_AGENT_CGROUP_MEM_PATH_ENV_VAR)
Expand Down
15 changes: 15 additions & 0 deletions userspace/libsinsp/sinsp_debug/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
include_directories("../../../common")
include_directories("../../")

add_executable(sinsp-debug
sinsp_debug.cpp
)

target_link_libraries(sinsp-debug
sinsp
)

if (APPLE AND NOT MINIMAL_BUILD)
# Needed when linking libcurl
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -framework Foundation -framework SystemConfiguration")
endif()
48 changes: 48 additions & 0 deletions userspace/libsinsp/sinsp_debug/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# sinsp-debug

This simple executable can be used to debug sinsp through scap-files.
Right now it prints relevant info about processes but in the next future it could be enriched:

# Build and run it 🏎️

From the build directory:

```bash
cmake -DBUILD_DRIVER=On -DUSE_BUNDLED_DEPS=Off -DMINIMAL_BUILD=On ..
make sinsp-debug
# It takes just one arg, the path to the scap-file (relative or absolute)
sudo ./libsinsp/sinsp_debug/sinsp-debug <path_to_scap_file>
```

# Example output

```
🧵 CLONE CALLER EXIT: 2704891
📜 Task Lineage for tid: 48694
⬇️ [apt-check] t: 48694, p: 48694, rpt: 5022, vt: 48694, vp: 48694, vs: 1921, vpg: 1921, ct: 0, e: /usr/lib/update-notifier/apt-check
⬇️ [update-notifier] t: 5022, p: 5022, rpt: 1921, vt: 5022, vp: 5022, vs: 1921, vpg: 1921, ct: 0, e: /usr/bin/update-notifier
⬇️ [gnome-session-b] t: 1921, p: 1921, rpt: 1406, vt: 1921, vp: 1921, vs: 1921, vpg: 1921, ct: 0, e: /usr/libexec/gnome-session-binary
⬇️ [systemd] t: 1406, p: 1406, rpt: 1, vt: 1406, vp: 1406, vs: 1406, vpg: 1406, ct: 0, e: /usr/lib/systemd/systemd
⬇️ [systemd]💀 t: 1, p: 1, rpt: 0, vt: 1, vp: 1, vs: 1, vpg: 1, ct: 0, e: /usr/lib/systemd/systemd
END
🟢 EXECVE EXIT: 2704902
📜 Task Lineage for tid: 48812
⬇️ [lsb_release] t: 48812, p: 48812, rpt: 48694, vt: 48812, vp: 48812, vs: 1921, vpg: 1921, ct: 0, e: /usr/bin/lsb_release
⬇️ [apt-check] t: 48694, p: 48694, rpt: 5022, vt: 48694, vp: 48694, vs: 1921, vpg: 1921, ct: 0, e: /usr/lib/update-notifier/apt-check
⬇️ [update-notifier] t: 5022, p: 5022, rpt: 1921, vt: 5022, vp: 5022, vs: 1921, vpg: 1921, ct: 0, e: /usr/bin/update-notifier
⬇️ [gnome-session-b] t: 1921, p: 1921, rpt: 1406, vt: 1921, vp: 1921, vs: 1921, vpg: 1921, ct: 0, e: /usr/libexec/gnome-session-binary
⬇️ [systemd] t: 1406, p: 1406, rpt: 1, vt: 1406, vp: 1406, vs: 1406, vpg: 1406, ct: 0, e: /usr/lib/systemd/systemd
⬇️ [systemd]💀 t: 1, p: 1, rpt: 0, vt: 1, vp: 1, vs: 1, vpg: 1, ct: 0, e: /usr/lib/systemd/systemd
END
💥 THREAD EXIT: 2712161
📜 Task Lineage for tid: 48812
⬇️ [lsb_release] t: 48812, p: 48812, rpt: 48694, vt: 48812, vp: 48812, vs: 1921, vpg: 1921, ct: 0, e: /usr/bin/lsb_release
⬇️ [apt-check] t: 48694, p: 48694, rpt: 5022, vt: 48694, vp: 48694, vs: 1921, vpg: 1921, ct: 0, e: /usr/lib/update-notifier/apt-check
⬇️ [update-notifier] t: 5022, p: 5022, rpt: 1921, vt: 5022, vp: 5022, vs: 1921, vpg: 1921, ct: 0, e: /usr/bin/update-notifier
⬇️ [gnome-session-b] t: 1921, p: 1921, rpt: 1406, vt: 1921, vp: 1921, vs: 1921, vpg: 1921, ct: 0, e: /usr/libexec/gnome-session-binary
⬇️ [systemd] t: 1406, p: 1406, rpt: 1, vt: 1406, vp: 1406, vs: 1406, vpg: 1406, ct: 0, e: /usr/lib/systemd/systemd
⬇️ [systemd]💀 t: 1, p: 1, rpt: 0, vt: 1, vp: 1, vs: 1, vpg: 1, ct: 0, e: /usr/lib/systemd/systemd
END
```
197 changes: 197 additions & 0 deletions userspace/libsinsp/sinsp_debug/sinsp_debug.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@

#include <sinsp.h>
#include <iostream>
#include <csignal>

static bool g_interrupted = false;

static void sigint_handler(int signum) { g_interrupted = true; }

std::string thread_info_to_string(sinsp_threadinfo* tinfo)
{
std::ostringstream out;
if(tinfo->is_main_thread())
{
/* Main thread notation */
out << "[" << tinfo->get_comm() << "]";
}
else
{
/* Secondary thread notation */
out << "{" << tinfo->get_comm() << "}";
}

/* if it is a reaper add (R)*/
if(tinfo->m_tginfo && tinfo->m_tginfo->is_reaper())
{
out << "💀";
}

out << " t: " << tinfo->m_tid;
out << ", p: " << tinfo->m_pid;
out << ", rpt: " << tinfo->m_ptid; // rpt (real parent tid)
out << ", vt: " << tinfo->m_vtid;
out << ", vp: " << tinfo->m_vpid;
out << ", vs: " << tinfo->m_sid; // vs (we call it sid but it is a vsid)
out << ", vpg: " << tinfo->m_vpgid;
out << ", ct: " << tinfo->is_in_pid_namespace();
out << ", e: " << tinfo->get_exepath();

return out.str();
}

void display_thread_lineage(sinsp_threadinfo* tinfo)
{
sinsp_threadinfo::visitor_func_t scap_file_visitor = [](sinsp_threadinfo* pt)
{
if(pt == nullptr)
{
printf("X - Null thread info detected\n");
}

printf("⬇️ %s\n", thread_info_to_string(pt).c_str());

/* The parent could be 0 when we don't find the real parent */
if(pt->m_tid == 1 || pt->m_ptid == 0 || pt->is_invalid())
{
printf("END\n\n");
return false;
}
return true;
};

printf("📜 Task Lineage for tid: %ld\n", tinfo->m_tid);
printf("⬇️ %s\n", thread_info_to_string(tinfo).c_str());

/* If the thread is invalid it has no parent */
if(tinfo->is_invalid() || tinfo->m_ptid == 0)
{
printf("END\n\n");
return;
}

tinfo->traverse_parent_state(scap_file_visitor);
}

int main(int argc, char** argv)
{
signal(SIGINT, sigint_handler);
signal(SIGTERM, sigint_handler);

if(argc != 2)
{
std::cerr << "You need to provide the scap-file path. Bye!" << std::endl;
exit(EXIT_FAILURE);
}
std::string file_path = argv[1];
sinsp inspector;
inspector.open_savefile(file_path);

std::cout << "-- Start capture" << std::endl;

inspector.start_capture();

std::cout << "-- Read from the loop" << std::endl;

sinsp_evt* ev = nullptr;
int32_t res = 0;
while(!g_interrupted)
{
res = inspector.next(&ev);
if(res == SCAP_EOF)
{
std::cout << "-- EOF" << std::endl;
g_interrupted = true;
break;
}

if(res != SCAP_SUCCESS)
{
continue;
}

auto tinfo = ev->get_thread_info();
if(tinfo == nullptr)
{
continue;
}

// Print all interesting events
uint16_t evt_type = ev->get_type();
switch(evt_type)
{
case PPME_SYSCALL_CLONE_11_X:
case PPME_SYSCALL_CLONE_16_X:
case PPME_SYSCALL_CLONE_17_X:
case PPME_SYSCALL_CLONE_20_X:
case PPME_SYSCALL_FORK_X:
case PPME_SYSCALL_FORK_17_X:
case PPME_SYSCALL_FORK_20_X:
case PPME_SYSCALL_VFORK_X:
case PPME_SYSCALL_VFORK_17_X:
case PPME_SYSCALL_VFORK_20_X:
case PPME_SYSCALL_CLONE3_X:
if(ev->get_param(0)->m_val == 0)
{
printf("🧵 CLONE CHILD EXIT: %ld\n", ev->get_num());
}
else
{
printf("🧵 CLONE CALLER EXIT: %ld\n", ev->get_num());
}
display_thread_lineage(tinfo);
break;

case PPME_SYSCALL_EXECVE_8_X:
case PPME_SYSCALL_EXECVE_13_X:
case PPME_SYSCALL_EXECVE_14_X:
case PPME_SYSCALL_EXECVE_15_X:
case PPME_SYSCALL_EXECVE_16_X:
case PPME_SYSCALL_EXECVE_17_X:
case PPME_SYSCALL_EXECVE_18_X:
case PPME_SYSCALL_EXECVE_19_X:
case PPME_SYSCALL_EXECVEAT_X:
printf("🟢 EXECVE EXIT: %ld\n", ev->get_num());
display_thread_lineage(tinfo);
break;

case PPME_PROCEXIT_E:
case PPME_PROCEXIT_1_E:
printf("💥 THREAD EXIT: %ld\n", ev->get_num());
for(const auto& child : tinfo->m_children)
{
if(!child.expired())
{
auto child_shr = child.lock().get();
printf("- move child, tid: %ld, ptid: %ld (dead) to a new reaper.\n",
child_shr->m_tid, child_shr->m_ptid);
}
}
display_thread_lineage(tinfo);
break;

default:
break;
}
}

inspector.stop_capture();

std::cout << "-- Stop capture" << std::endl << std::endl;

std::cout << "📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜" << std::endl;
std::cout << "📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜" << std::endl;
std::cout << "-- Print all lineages of the table" << std::endl;
std::cout << "📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜" << std::endl;
std::cout << "📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜📜" << std::endl << std::endl;

// Print lineage for all threads in the table
inspector.m_thread_manager->get_threads()->loop(
[&](sinsp_threadinfo& tinfo)
{
display_thread_lineage(&tinfo);
return true;
});

return 0;
}

0 comments on commit 6ddef94

Please sign in to comment.