%{_bindir}/crash-worker-system-tests-run
%{_libexecdir}/crash-worker/system-tests/bugreport_crash_info_json/bugreport_crash_info_json.sh
+%{_libexecdir}/crash-worker/system-tests/bugreport_created/bugreport_created.sh
%{_libexecdir}/crash-worker/system-tests/check_minicore_mem/check_minicore_mem.sh
%{_libexecdir}/crash-worker/system-tests/check_minicore_mem/cp.sh
%{_libexecdir}/crash-worker/system-tests/clean_temp/clean_temp.sh
%{_libexecdir}/crash-worker/system-tests/utils/btee
%{_libexecdir}/crash-worker/system-tests/utils/kenny
%{_libexecdir}/crash-worker/system-tests/utils/libbugreport-servicetest
+%{_libexecdir}/crash-worker/system-tests/utils/diagnostics_bugreporttest
%{_libexecdir}/crash-worker/system-tests/utils/minicore-utils.sh
%{_libexecdir}/crash-worker/system-tests/wait_for_opt_usr/wait_for_opt_usr.sh
%{_libexecdir}/crash-worker/system-tests/without_so_info_file/without_so_info_file.sh
${CMAKE_SOURCE_DIR}/src/shared/util.c
${CMAKE_SOURCE_DIR}/src/shared/spawn.c
${CMAKE_SOURCE_DIR}/src/shared/config.c
+ ${CMAKE_SOURCE_DIR}/src/shared/bugreport-util.c
)
INCLUDE(GNUInstallDirs)
#include "bugreport-service.h"
#include "crash-manager/crash-manager.h"
+#include "shared/bugreport-util.h"
#include "shared/log.h"
#include "shared/util.h"
#include "diagnostics/diagnostics.h"
}
if (!error_sent) {
- int res = diagnostics_send_event("BugreportCreated", NULL);
- if (res != DIAGNOSTICS_ERROR_NONE)
- _E("Send diagnostics event error: %d", res);
-
+ send_bugreport_created_event(report_path);
g_dbus_method_invocation_return_value(cb_data->invocation,
g_variant_new("(s)", report_path));
}
if (list == NULL) {
if (as_json)
dprintf(fd, "{\"error\": \"Internal error.\"}");
+ else
+ dprintf(fd, "Internal error\n");
return false;
}
if (list == NULL) {
if (report_type == BR_CRASHINFO_JSON)
dprintf(fd, "{\"error\": \"Internal error.\"}");
+ else
+ dprintf(fd, "Internal error\n");
return false;
}
);
}
-static bool diagnostics_call_parse_options(int out_fd, char **params, int params_size, struct diagnostics_call_options *dco)
+static bool get_file_from_ctx(diagnostics_ctx_h ctx, char **report_file)
+{
+ assert(report_file);
+
+ if (ctx == NULL)
+ return false;
+
+ bool result = false;
+ char *event_name = NULL;
+ bundle *event_data = NULL;
+
+ int ret = diagnostics_get_event_name(ctx, &event_name);
+ if (ret != DIAGNOSTICS_ERROR_NONE) {
+ _E("Get event name error: %d", ret);
+ goto out;
+ }
+ if (strcmp(event_name, "BugreportCreated") != 0) {
+ _E("Unknown context: %s", event_name);
+ goto out;
+ }
+
+ ret = diagnostics_get_event_data(ctx, &event_data);
+ if (ret != DIAGNOSTICS_ERROR_NONE) {
+ _E("Get event data error: %d", ret);
+ goto out;
+ }
+
+ char *tmp_report_file;
+ ret = bundle_get_str(event_data, "report_file", &tmp_report_file);
+ if (ret != BUNDLE_ERROR_NONE) {
+ _E("Can not get report_file from event data: %d", ret);
+ goto out;
+ }
+
+ *report_file = strdup(tmp_report_file);
+ if (*report_file == NULL) {
+ _E("Out of memory: %m");
+ goto out;
+ }
+ _D("Report file from event data: %s", *report_file);
+
+ result = true;
+out:
+ if (event_name != NULL)
+ free(event_name);
+ if (event_data != NULL)
+ bundle_free(event_data);
+
+ return result;
+}
+
+static bool diagnostics_call_parse_options(int out_fd, char **params, int params_size, diagnostics_ctx_h ctx, struct diagnostics_call_options *dco)
{
struct timespec cur_time;
clock_gettime(CLOCK_REALTIME, &cur_time);
memcpy(&nparams[1], params, params_size*sizeof(char*));
nparams[0] = "n";
while ((opt = getopt_long_only(params_size+1, nparams, "", long_options, NULL)) != -1) {
- switch(opt) {
+ switch (opt) {
case PN_TYPE:
if (strcmp(optarg, "bugreport") == 0) {
dco->report_type = BR_BUGREPORT;
}
}
- if (optind < params_size+1)
- dco->arg = nparams[optind];
+ if (optind < params_size+1) {
+ dco->arg = strdup(nparams[optind]);
+ if (dco->arg == NULL) {
+ _E("Out of memory: %m");
+ return false;
+ }
+ } else {
+ get_file_from_ctx(ctx, &dco->arg);
+ }
return true;
}
}
struct diagnostics_call_options dco;
- if (!diagnostics_call_parse_options(fd, params, params_size, &dco))
+ if (!diagnostics_call_parse_options(fd, params, params_size, ctx, &dco))
return;
if ((dco.last_set && (dco.from_set || dco.to_set)) || (dco.to_set && !dco.from_set)) {
_E("Incorrect parameters set");
dprintf(fd, "Incorrect parameters set.\n");
- return;
+ goto out;
}
if (dco.arg != NULL) {
if (dco.last_set || dco.from_set || dco.to_set) {
_E("Incorrect parameters set.");
dprintf(fd, "Incorrect parameters set.\n");
- return;
+ goto out;
}
write_single_file(fd, dco.report_type, dco.arg);
- return;
+ goto out;
}
switch(dco.report_type) {
default:
_E("Unknown report type\n");
}
+out:
+ if (dco.arg != NULL)
+ free(dco.arg);
}
bool diagnostics_init()
${CMAKE_SOURCE_DIR}/src/shared/util.c
${CMAKE_SOURCE_DIR}/src/shared/spawn.c
${CMAKE_SOURCE_DIR}/src/shared/config.c
+ ${CMAKE_SOURCE_DIR}/src/shared/bugreport-util.c
)
SET(CRASH_MANAGER_SRCS
#include <sys/ptrace.h>
#include <sys/vfs.h>
#include <unistd.h>
-#include <diagnostics.h>
#include <pkgmgr-info.h>
#include <tzplatform_config.h>
#include "defs.h"
#include "shared/log.h"
#include "shared/config.h"
+#include "shared/bugreport-util.h"
#include "shared/spawn.h"
#include "shared/util.h"
#include "so-info.h"
if (move_dump_data(temp_report, cinfo)) {
_I("Report for pid %d created at %s", cinfo->pid_info, cinfo->result_path);
- diagnostics_send_event("BugreportCreated", NULL);
+ send_bugreport_created_event(cinfo->result_path);
}
if (cinfo->print_result_path)
--- /dev/null
+/*
+ * bugreport-util
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <diagnostics.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <strings.h>
+
+#include "shared/log.h"
+
+bool send_bugreport_created_event(const char *report_path)
+{
+ char *result_file = rindex(report_path, '/');
+ if (result_file == NULL) {
+ _E("Out of memory: %m");
+ return false;
+ }
+
+ bundle *event_data = bundle_create();
+ bundle_add_str(event_data, "report_file", ++result_file);
+ int res = diagnostics_send_event("BugreportCreated", event_data);
+ if (res != DIAGNOSTICS_ERROR_NONE)
+ _E("Send diagnostics event error: %d", res);
+
+ bundle_free(event_data);
+ return res == DIAGNOSTICS_ERROR_NONE;
+}
+
--- /dev/null
+/*
+ * bugreport-util
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __BUGREPORT_UTIL_H__
+#define __BUGREPORT_UTIL_H__
+#include <stdbool.h>
+
+bool send_bugreport_created_event(const char *report_path);
+
+#endif // __BUGREPORT_UTIL_H__
*/
#include <assert.h>
+#include <diagnostics.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
cmake_minimum_required(VERSION 2.6)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src)
ADD_SUBDIRECTORY(utils)
macro(CONFIGURE_TEST_FILE dir_name file_name)
endmacro()
configure_test("bugreport_crash_info_json")
+configure_test("bugreport_created")
configure_test("check_minicore_mem")
configure_test("clean_temp")
configure_test("cmp_backtraces" "cp")
--- /dev/null
+#!/bin/bash
+
+# Check the BugreportCreated signal
+
+if [ -z "${CRASH_WORKER_SYSTEM_TESTS}" ]; then
+ CRASH_WORKER_SYSTEM_TESTS="@CRASH_SYSTEM_TESTS_PATH@"
+fi
+
+. ${CRASH_WORKER_SYSTEM_TESTS}/utils/minicore-utils.sh
+
+( ${CRASH_WORKER_SYSTEM_TESTS}/utils/kenny &
+ pid=$!
+ sleep 2
+ kill -6 $pid ) &
+
+TMP=$(mktemp /tmp/dbus_notify.XXXXXX)
+${CRASH_WORKER_SYSTEM_TESTS}/utils/diagnostics_bugreporttest --type=crash-info-json > "${TMP}" &
+watchpid=$!
+
+cleanup()
+{
+ kill "${watchpid}"
+ rm -f "${TMP}"
+}
+
+trap cleanup 0
+
+sleep 3
+wait_for_app crash-manager
+sleep 1
+
+if [ $(wc -l "${TMP}" | cut -f1 -d' ') -lt 10 ]; then
+ fail "Output file is too short"
+fi
+
+if ! egrep "callstack" "${TMP}"; then
+ fail "No callstack in output file"
+fi
+
+if ! egrep "native_hash" "${TMP}"; then
+ fail "No native_hash in output file"
+fi
+
+exit_ok
set_target_properties(kenny PROPERTIES COMPILE_FLAGS "-std=c++11 -ggdb -O0")
add_executable(libbugreport-servicetest libbugreport-servicetest.c)
+add_executable(diagnostics_bugreporttest diagnostics_bugreporttest.c)
INCLUDE(FindPkgConfig)
pkg_check_modules(helper_pkgs REQUIRED
gio-2.0
bugreport
+ diagnostics
dlog)
+FOREACH(flag ${helper_pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
TARGET_LINK_LIBRARIES(libbugreport-servicetest bugreport ${helper_pkgs_LDFLAGS})
+TARGET_LINK_LIBRARIES(diagnostics_bugreporttest bugreport ${helper_pkgs_LDFLAGS})
install(TARGETS kenny DESTINATION ${CRASH_SYSTEM_TESTS_PATH}/utils)
install(TARGETS btee DESTINATION ${CRASH_SYSTEM_TESTS_PATH}/utils)
install(FILES minicore-utils.sh DESTINATION ${CRASH_SYSTEM_TESTS_PATH}/utils)
install(TARGETS libbugreport-servicetest DESTINATION ${CRASH_SYSTEM_TESTS_PATH}/utils)
+install(TARGETS diagnostics_bugreporttest DESTINATION ${CRASH_SYSTEM_TESTS_PATH}/utils)
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <diagnostics.h>
+#include <glib.h>
+#include <getopt.h>
+#include "shared/util.h"
+
+GMainLoop *mainloop;
+
+static void bugreport_created_cb(diagnostics_ctx_h ctx, void *user_data)
+{
+ const char *params[] = {"--type", (char*)user_data};
+ diagnostics_data_h data;
+ int ret = diagnostics_get_data(ctx, params, ARRAY_SIZE(params), &data);
+ if (ret != DIAGNOSTICS_ERROR_NONE) {
+ printf("diagnostics_get_data error: %d\n", ret);
+ return;
+ }
+
+ size_t byte_read = 0;
+ char buff[1024];
+ printf("---- START ----\n");
+ do {
+ ret = diagnostics_data_read(data, buff, sizeof(buff)-1, 5000, &byte_read);
+ if (ret != DIAGNOSTICS_ERROR_NONE) {
+ printf("diagnostics_data_read error: %d\n", ret);
+ return;
+ }
+ buff[byte_read] = 0;
+ printf("%s", buff);
+ } while(byte_read > 0);
+
+ printf("\n----- END -----\n");
+ diagnostics_data_destroy(data);
+ diagnostics_destroy(ctx);
+ g_main_loop_quit(mainloop);
+}
+
+int main(int argc, char *argv[])
+{
+ struct option long_options[] = {
+ {"type", required_argument, NULL, 't'},
+ {}
+ };
+
+ int opt;
+ char *type = "crash-info";
+
+ while ((opt = getopt_long(argc, argv, "t:", long_options, NULL)) != -1) {
+ switch (opt) {
+ case 't':
+ type = optarg;
+ break;
+ default:
+ printf("%s [--type=<type>]\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+ }
+
+ int ret = diagnostics_set_notification_cb(bugreport_created_cb, type);
+ if (ret != DIAGNOSTICS_ERROR_NONE) {
+ printf("diagnostics_set_notification_cb error: %d\n", ret);
+ return EXIT_FAILURE;
+ }
+
+ diagnostics_subscribe_event("BugreportCreated", "org.tizen.bugreport-service");
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
+ return EXIT_SUCCESS;
+}