#define CRASH_PATH_CRASH CRASH_OBJECT_PATH"/Crash"
#define CRASH_INTERFACE_CRASH CRASH_INTERFACE_NAME".Crash"
#define PROCESS_CRASHED "ProcessCrashed"
+#define PROCESS_CRASHED_EX "ProcessCrashedEx"
#define ARM_REG_LR 14
#define ARM_REG_PC 15
return g_variant_builder_end(&md_builder);
}
-static bool send_notify(GDBusConnection *conn, const struct NotifyParams *notify_params)
+static bool send_one_signal(GDBusConnection *conn, const char *method_name, GVariant *method_data)
{
- int result = false;
- GError *error = NULL;
-
- GVariant *data = notify_params->legacy_notification
- ? build_legacy_message_data(notify_params)
- : build_message_data(notify_params);
- if (data == NULL) {
- _E("Error while preparing parameters");
- goto out;
- }
+ assert(conn);
+ assert(method_name);
+ assert(method_data);
+ GError *error = NULL;
g_dbus_connection_emit_signal(conn,
NULL,
CRASH_PATH_CRASH,
CRASH_INTERFACE_CRASH,
- PROCESS_CRASHED,
- data,
+ method_name,
+ method_data,
&error);
if (error) {
- _E("Failed to emit signal: %s", error->message);
- goto out;
+ _E("Failed to emit %s signal: %s", method_name, error->message);
+ g_error_free(error);
+ return false;
}
- g_dbus_connection_flush_sync(conn, NULL, &error);
- if (error)
- _E("Failed to flush connection - signal might not be delivered: %s", error->message);
+ return true;
+}
- result = true;
+/* Due compatibility with various Tizen forks this programs emits following signals:
+ * ProcessCrashedEx - using "new" signature (sssssiia{sv})
+ * ProcessCrashed - using either "new" or "old" signature (ssss)
+ *
+ * The signature of ProccessCrashed is controlled by UsingLegacyNotification configuration option.
+ *
+ * New programs should use ProcessCrashedEx only, or best - avoid using signals directly and
+ * depending on APIs (eg Diagnostics API).
+ */
+static bool send_signals(GDBusConnection *conn, const struct NotifyParams *notify_params)
+{
+ GVariant *data = build_message_data(notify_params);
+ if (!data) {
+ _E("Error while preparing data for " PROCESS_CRASHED_EX " signal");
+ return false;
+ }
-out:
- if (error)
+ (void)g_variant_ref_sink(data);
+ send_one_signal(conn, PROCESS_CRASHED_EX, data);
+
+ GVariant *legacy = notify_params->legacy_notification
+ ? build_legacy_message_data(notify_params)
+ : data;
+
+ if (legacy)
+ send_one_signal(conn, PROCESS_CRASHED, legacy);
+ else
+ _W("Error while preparing data for " PROCESS_CRASHED " signal");
+
+ /* No need to free `legacy' GVariant as it's either already freed by the send call
+ * (ie. it's floating ref in legacy case) or referencing sinked ref, which is freed
+ * below.
+ */
+ g_variant_unref(data);
+
+ GError *error = NULL;
+ g_dbus_connection_flush_sync(conn, NULL, &error);
+ if (error) {
+ _E("Failed to flush connection - signal might not be delivered: %s", error->message);
g_error_free(error);
+ }
- return result;
+ return true;
}
static bool parse_cmdline(int ac, char *av[], struct NotifyParams *params)
if (!bus_get(&conn))
return EXIT_FAILURE;
- send_notify(conn, ¶ms);
+ send_signals(conn, ¶ms);
bus_put(conn);
return EXIT_SUCCESS;
sleep 2
kill -6 $pid ) &
-TMPFILE=$(mktemp /tmp/dbus_notify.XXXXXX)
-dbus-monitor --system type=signal,path=/Org/Tizen/System/Crash/Crash,interface=org.tizen.system.crash.Crash,member=ProcessCrashed > $TMPFILE &
-monpid=$!
+TMP1=$(mktemp /tmp/dbus_notify.XXXXXX)
+TMP2=$(mktemp /tmp/dbus_notify.XXXXXX)
+dbus-monitor --system type=signal,path=/Org/Tizen/System/Crash/Crash,interface=org.tizen.system.crash.Crash,member=ProcessCrashed > $TMP1 &
+monpid1=$!
+dbus-monitor --system type=signal,path=/Org/Tizen/System/Crash/Crash,interface=org.tizen.system.crash.Crash,member=ProcessCrashedEx > $TMP2 &
+monpid2=$!
cleanup()
{
- kill $monpid
- rm -f $TMPFILE
+ kill $monpid1 $monpid2
+ rm -f $TMP1 $TMP2
}
trap cleanup 0
sleep 3
+wait_for_app crash-manager
-PATTERN='path=/Org/Tizen/System/Crash/Crash; interface=org\.tizen\.system\.crash\.Crash; member=ProcessCrashed'
-for i in $(seq 1 10); do
+for TMPFILE in $TMP1 $TMP2; do
+ PATTERN="path=/Org/Tizen/System/Crash/Crash; interface=org\.tizen\.system\.crash\.Crash; member=ProcessCrashed"
score=0
if egrep "$PATTERN" $TMPFILE; then
if egrep "string \"kenny" $TMPFILE; then
score=$(($score + 1))
fi
+ if egrep 'ProcessCrashed\b' $TMPFILE; then
+ has_process_crashed=yes
+ fi
+
+ if egrep 'ProcessCrashedEx\b' $TMPFILE; then
+ has_process_crashed_ex=yes
+ fi
+
if [ $score -eq 5 ]; then
- exit_ok
+ continue
fi
fi
- sleep 1
+ fail "dbus signal does not match"
done
-fail "dbus signal does not match"
+[ x$has_process_crashed = xyes ] && [ x$has_process_crashed_ex = xyes ] || fail "necessary signals not matched (ProcessCrashed and ProcessCrashedEx)"
+
+exit_ok