#!/usr/bin/env bash set -e . ./scripts/config.shlib ON_ATTACH=${1:-false} configfile="./scripts/updater-preferences" BACKTRACEFILE=$(ls -t1 /tmp | grep "cathook-$USER-.*-segfault.log" | head -n 1) CATHOOK="./build/bin/libcathook.so" # Test whether debug information is available for a given binary has_debug_info() { readelf -S "$1" | grep -q " \(.debug_info\)\|\(.gnu_debuglink\) " } # Function to request permission on attach function requestPermissions { # Prefer CLI if [ -t 0 ]; then read -p "New (possible) cathook crash report detected. Submit? y/n " -n 1 -r echo if ! [[ $REPLY =~ ^[Yy]$ ]] then exit fi # Fall back to gui elif [ -x "$(command -v zenity)" ] && xset q &>/dev/null; then zenity --no-wrap --question --text="New cathook crash report detected. Submit?" out=$? if [ "$out" != 0 ]; then exit fi else exit fi } if [ "$BACKTRACEFILE" == "" ] || [ "$(cfg_read "$configfile" backtrace_last)" == "$BACKTRACEFILE" ]; then if [ "$ON_ATTACH" == "false" ]; then echo "No (new) crash found." fi exit 0 fi if [ "$ON_ATTACH" == "true" ] && [ "$(cfg_read "$configfile" update_channel)" == "developer" ]; then echo -e "\nRefusing to send crash report because cathook is in developer mode. Run ./report-crash to report the crash manually.\n" exit 0 fi cfg_write "$configfile" backtrace_last "$BACKTRACEFILE" cathookcrash=false while read p; do lib="$(echo "$p" | cut -f 1)" if [ "$lib" = "cathook" ]; then cathookcrash=true fi done < <(sed 1d "/tmp/$BACKTRACEFILE") if [ "$ON_ATTACH" == "false" ]; then echo "$BACKTRACEFILE" else requestPermissions fi if [ "$cathookcrash" == "false" ]; then echo "Crash was not a cathook crash!" exit 0 fi echo "(Possible) cathook crash detected!" SYMBOLS=true has_debug_info "$CATHOOK" || SYMBOLS=false if [ $SYMBOLS == false ]; then echo "No debug symbols detected!" proccount=$(grep -c '^processor' /proc/cpuinfo) pushd build cmake -DInternal_Symbolized=true .. && cmake --build . --target cathook -- -j$proccount popd fi SENTRY_DATA='{"release":"%s","exception":{"values":[{"type":"Crash report","value":"Crash on %s","stacktrace":{"frames":[%s]}}]}}' BREADCRUMBS='' append_crumb() { if [ "$BREADCRUMBS" != "" ]; then BREADCRUMBS=",$BREADCRUMBS" fi BREADCRUMBS="$1$BREADCRUMBS" } while read p; do lib="$(echo "$p" | cut -f 1)" addr="$(echo "$p" | cut -f 2)" if [ "$lib" = "cathook" ]; then while read function; do read addrandline echo "cathook $function $addrandline" FILE="$(realpath --relative-base="${PWD}" "$(echo $addrandline | cut -f 1 -d ":")")" LINE="$(echo $addrandline | cut -f 2 -d ":")" PREFIX="filename" IN_APP=true if [ "${FILE:0:1}" = "/" ]; then PREFIX="abs_path" IN_APP=false fi if [ "$function" == "critical_error_handler(int)" ]; then IN_APP=false fi append_crumb "$(printf '{"%s":"%s","lineno":"%s","package":"cathook","in_app":%s,"function":"%s"}' "$PREFIX" "$FILE" "$LINE" "$IN_APP" "${function//\"/\\\"}")" done < <(addr2line "$addr" -iCfe $CATHOOK) else echo $p append_crumb "$(printf '{"package":"%s","instruction_addr":"%s","in_app":false,"function":"%s"}' "$lib" "$addr" "$addr")" fi done <"/tmp/$BACKTRACEFILE" COMMIT="$(git log -1 --pretty="%h")" FULL_COMMIT="$(git rev-parse HEAD)" if [ "$ON_ATTACH" == "false" ]; then read -p "Do you want to submit this crash? y/n " -n 1 -r echo else REPLY="y" fi if [[ $REPLY =~ ^[Yy]$ ]] then curl --data "$(printf "$SENTRY_DATA" "$FULL_COMMIT" "$COMMIT" "$BREADCRUMBS")" \ -H 'Content-Type: application/json' \ "https://sentry.io/api/5220907/store/?sentry_version=7&sentry_key=44330b6a8c6b481c9fe02e261ca1d761&sentry_client=curl-bash/0.1" echo -e "\n" echo Thank you! echo 'Contact us about this and send us the id above: https://t.me/nullworks https://cathook.club/issues' echo fi