wlroots/backend/drm/backend.c

296 lines
8.6 KiB
C
Raw Normal View History

2017-06-01 20:29:10 -04:00
#include <assert.h>
#include <drm_fourcc.h>
2018-02-12 21:29:23 +01:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wayland-server-core.h>
2017-06-04 19:30:37 -04:00
#include <wlr/backend/interface.h>
2018-02-12 21:29:23 +01:00
#include <wlr/backend/session.h>
2017-06-21 10:27:45 -04:00
#include <wlr/interfaces/wlr_output.h>
2017-06-21 12:10:07 -04:00
#include <wlr/util/log.h>
2018-02-12 21:29:23 +01:00
#include <xf86drm.h>
#include "backend/drm/drm.h"
#include "backend/drm/fb.h"
#include "render/drm_format_set.h"
2017-05-01 17:49:18 +12:00
2018-09-17 22:25:20 +02:00
struct wlr_drm_backend *get_drm_backend_from_backend(
struct wlr_backend *wlr_backend) {
assert(wlr_backend_is_drm(wlr_backend));
struct wlr_drm_backend *backend = wl_container_of(wlr_backend, backend, backend);
return backend;
2018-09-17 22:25:20 +02:00
}
static bool backend_start(struct wlr_backend *backend) {
2018-09-17 22:25:20 +02:00
struct wlr_drm_backend *drm = get_drm_backend_from_backend(backend);
scan_drm_connectors(drm, NULL);
2017-05-07 10:00:23 -04:00
return true;
}
2017-05-03 21:28:44 +12:00
static void backend_destroy(struct wlr_backend *backend) {
2017-09-30 22:22:26 +13:00
if (!backend) {
2017-05-07 10:00:23 -04:00
return;
}
2018-09-17 22:25:20 +02:00
struct wlr_drm_backend *drm = get_drm_backend_from_backend(backend);
struct wlr_drm_connector *conn, *next;
wl_list_for_each_safe(conn, next, &drm->connectors, link) {
conn->crtc = NULL; // leave CRTCs on when shutting down
destroy_drm_connector(conn);
2017-05-31 16:17:04 -04:00
}
2017-08-05 18:15:39 +12:00
struct wlr_drm_page_flip *page_flip, *page_flip_tmp;
wl_list_for_each_safe(page_flip, page_flip_tmp, &drm->page_flips, link) {
drm_page_flip_destroy(page_flip);
}
wlr_backend_finish(backend);
backend/drm, backend/libinput: listen to session destroy This fixes a heap-use-after-free when the session is destroyed before the backend during wl_display_destroy: ==1085==ERROR: AddressSanitizer: heap-use-after-free on address 0x614000000180 at pc 0x7f88e3590c2d bp 0x7ffdc4e33f90 sp 0x7ffdc4e33f80 READ of size 8 at 0x614000000180 thread T0 #0 0x7f88e3590c2c in find_device ../subprojects/wlroots/backend/session/session.c:192 #1 0x7f88e3590e85 in wlr_session_close_file ../subprojects/wlroots/backend/session/session.c:204 #2 0x7f88e357b80c in libinput_close_restricted ../subprojects/wlroots/backend/libinput/backend.c:24 #3 0x7f88e21af274 (/lib64/libinput.so.10+0x28274) #4 0x7f88e21aff1d (/lib64/libinput.so.10+0x28f1d) #5 0x7f88e219ddac (/lib64/libinput.so.10+0x16dac) #6 0x7f88e21b415d in libinput_unref (/lib64/libinput.so.10+0x2d15d) #7 0x7f88e357c9d6 in backend_destroy ../subprojects/wlroots/backend/libinput/backend.c:130 #8 0x7f88e3545a09 in wlr_backend_destroy ../subprojects/wlroots/backend/backend.c:50 #9 0x7f88e358981a in multi_backend_destroy ../subprojects/wlroots/backend/multi/backend.c:54 #10 0x7f88e358a059 in handle_display_destroy ../subprojects/wlroots/backend/multi/backend.c:107 #11 0x7f88e314acde (/lib64/libwayland-server.so.0+0x8cde) #12 0x7f88e314b466 in wl_display_destroy (/lib64/libwayland-server.so.0+0x9466) #13 0x559fefb52385 in main ../main.c:67 #14 0x7f88e2639152 in __libc_start_main (/lib64/libc.so.6+0x27152) #15 0x559fefb4297d in _start (/home/simon/src/glider/build/glider+0x2297d) 0x614000000180 is located 320 bytes inside of 416-byte region [0x614000000040,0x6140000001e0) freed by thread T0 here: #0 0x7f88e3d0a6b0 in __interceptor_free /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:122 #1 0x7f88e35b51fb in logind_session_destroy ../subprojects/wlroots/backend/session/logind.c:270 #2 0x7f88e35905a4 in wlr_session_destroy ../subprojects/wlroots/backend/session/session.c:156 #3 0x7f88e358f440 in handle_display_destroy ../subprojects/wlroots/backend/session/session.c:65 #4 0x7f88e314acde (/lib64/libwayland-server.so.0+0x8cde) previously allocated by thread T0 here: #0 0x7f88e3d0acd8 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:153 #1 0x7f88e35b911c in logind_session_create ../subprojects/wlroots/backend/session/logind.c:746 #2 0x7f88e358f6b4 in wlr_session_create ../subprojects/wlroots/backend/session/session.c:91 #3 0x559fefb51ea6 in main ../main.c:20 #4 0x7f88e2639152 in __libc_start_main (/lib64/libc.so.6+0x27152)
2019-11-30 11:57:37 +01:00
wl_list_remove(&drm->session_destroy.link);
wl_list_remove(&drm->session_active.link);
wl_list_remove(&drm->parent_destroy.link);
wl_list_remove(&drm->dev_change.link);
wl_list_remove(&drm->dev_remove.link);
2017-12-07 23:44:59 +01:00
if (drm->mgpu_renderer.wlr_rend) {
2025-01-16 19:10:11 +05:30
wlr_drm_format_set_finish(&drm->mgpu_formats);
finish_drm_renderer(&drm->mgpu_renderer);
}
finish_drm_resources(drm);
struct wlr_drm_fb *fb, *fb_tmp;
wl_list_for_each_safe(fb, fb_tmp, &drm->fbs, link) {
drm_fb_destroy(fb);
}
free(drm->name);
wlr_session_close_file(drm->session, drm->dev);
2017-09-30 22:22:26 +13:00
wl_event_source_remove(drm->drm_event);
free(drm);
2017-05-07 10:00:23 -04:00
}
2020-12-04 16:47:42 +01:00
static int backend_get_drm_fd(struct wlr_backend *backend) {
struct wlr_drm_backend *drm = get_drm_backend_from_backend(backend);
return drm->fd;
2020-12-04 16:47:42 +01:00
}
static bool backend_test(struct wlr_backend *backend,
const struct wlr_backend_output_state *states, size_t states_len) {
struct wlr_drm_backend *drm = get_drm_backend_from_backend(backend);
return commit_drm_device(drm, states, states_len, true);
}
static bool backend_commit(struct wlr_backend *backend,
const struct wlr_backend_output_state *states, size_t states_len) {
struct wlr_drm_backend *drm = get_drm_backend_from_backend(backend);
return commit_drm_device(drm, states, states_len, false);
}
static const struct wlr_backend_impl backend_impl = {
.start = backend_start,
.destroy = backend_destroy,
2020-12-04 16:47:42 +01:00
.get_drm_fd = backend_get_drm_fd,
.test = backend_test,
.commit = backend_commit,
2017-05-07 10:00:23 -04:00
};
bool wlr_backend_is_drm(struct wlr_backend *b) {
return b->impl == &backend_impl;
}
struct wlr_backend *wlr_drm_backend_get_parent(struct wlr_backend *backend) {
struct wlr_drm_backend *drm = get_drm_backend_from_backend(backend);
return drm->parent ? &drm->parent->backend : NULL;
}
static void handle_session_active(struct wl_listener *listener, void *data) {
2017-12-07 23:44:59 +01:00
struct wlr_drm_backend *drm =
wl_container_of(listener, drm, session_active);
struct wlr_session *session = drm->session;
2017-05-14 01:12:47 +12:00
wlr_log(WLR_INFO, "DRM FD %s", session->active ? "resumed" : "paused");
2017-05-14 01:12:47 +12:00
if (!session->active) {
return;
}
backend/drm: disable all CRTCs after VT switch When the user switches away from the VT where wlroots is running, the new DRM master may mutate the KMS state in an arbitrary manner. For instance, let's say wlroots uses the following connector/CRTC mapping: - CRTC 42 drives connector DP-1 - CRTC 43 drives connector DP-2 Then the new DRM master may swap the mapping like so: - CRTC 42 drives connector DP-2 - CRTC 43 drives connector DP-1 wlroots needs to restore its own state when the user switches back. Some state is attached to wlr_drm_crtc (e.g. current FB), so reading back and adopting the CRTC/connector mapping left by the previous DRM master would be complicated (this was the source of other bugs in the past, see [1]). With the previous logic, wlroots merely tries to restore the state of each connector one after the other. This fails in the scenario described above: the kernel refuses to use CRTC 42 for DP-1, because that CRTC is already in-use for DP-2. Unfortunately with the legacy uAPI it's not possible to restore the state in one go. We need to support both legacy and atomic uAPIs, so let's fix the bug for the legacy uAPI first, and then improve the situation for the atomic uAPI as a second step [2]. We need to disable the CRTCs we're going to switch the connectors for. This sounds complicated, so let's just disable all CRTCs to simplify. This causes a black screen because of the on/off modesets, but makes VT switch much more reliable, so I'll take it. [1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/commit/c6d8a11d2c438d514473b1cbe20e5550e7227472 [2]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3794 Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3342
2023-01-15 16:21:21 +01:00
scan_drm_connectors(drm, NULL);
Revert removal of automatic drm reset on VT switch ...on the basis that it reduces user-space breakage with respect to layer-shell clients disappearing on suspend/resume and on VT change. Revert the following two commits: - 1edd5e2 "backend/drm: Remove reset from interface" - 0f255b4 "backend/drm: Remove automatic reset on VT switch" This it not intended to be reverted on the `master` branch. Instead, the next wlroots release is anticipated to handle the situation differently, possibly by splitting some objects and leaving output-related wl_globals which have been announced to clients. See discussions on [issue-3944]. [issue-3944]: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3944#note_3030632 Background: With [MR-4878] on wlroots-0.19.0, the DRM backend destroys/recreates outputs on VT switch and in some cases on suspend/resume too. The reason for this change was that (i) the KMS state is undefined when a VT is switched away; and (ii) the previous outputs had issues with restoration, particularly when the output configuration had changed whilst switched away. This change causes two issues for users: - Some layer-shell clients do not re-appear on output re-connection, or may appear on a different output. Whilst this has always been the case, it will now also happen in said situations. It is technically possible for layer-shell clients to deal with this more thoughtfully by handling the new-output and surface-destroy signals to achieve desired behaviours, but such changes take time and meanwhile Desktop Environment teams and other users consider this a serious regression. - Some Gtk clients issue critical warnings on some compositors as they assume that at least one output is always available. This will be fixed in `Gtk-3.24.50` and is believed to be a harmless warning, [MR-4878]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4878 Testing: 1. This reversion has been tested with [conky] and [GlassyClock]. With the reversion applied, the clients remain visible after VT switching. 2. It was also tested with labwc on tty1; and sway on tty2. No adverse affects were observed when changing output scales on either compositor. [conky]: https://github.com/brndnmtthws/conky [GlassyClock]: https://github.com/tsujan/GlassyClock
2025-08-03 13:00:55 +01:00
restore_drm_device(drm);
2017-05-14 01:12:47 +12:00
}
static void handle_dev_change(struct wl_listener *listener, void *data) {
struct wlr_drm_backend *drm = wl_container_of(listener, drm, dev_change);
struct wlr_device_change_event *change = data;
2017-06-03 15:47:33 +12:00
if (!drm->session->active) {
return;
}
2017-06-04 17:43:34 +12:00
switch (change->type) {
case WLR_DEVICE_HOTPLUG:
wlr_log(WLR_DEBUG, "Received hotplug event for %s", drm->name);
scan_drm_connectors(drm, &change->hotplug);
break;
case WLR_DEVICE_LEASE:
wlr_log(WLR_DEBUG, "Received lease event for %s", drm->name);
scan_drm_leases(drm);
break;
default:
wlr_log(WLR_DEBUG, "Received unknown change event for %s", drm->name);
}
2017-06-01 20:29:10 -04:00
}
static void handle_dev_remove(struct wl_listener *listener, void *data) {
struct wlr_drm_backend *drm = wl_container_of(listener, drm, dev_remove);
wlr_log(WLR_INFO, "Destroying DRM backend for %s", drm->name);
backend_destroy(&drm->backend);
}
backend/drm, backend/libinput: listen to session destroy This fixes a heap-use-after-free when the session is destroyed before the backend during wl_display_destroy: ==1085==ERROR: AddressSanitizer: heap-use-after-free on address 0x614000000180 at pc 0x7f88e3590c2d bp 0x7ffdc4e33f90 sp 0x7ffdc4e33f80 READ of size 8 at 0x614000000180 thread T0 #0 0x7f88e3590c2c in find_device ../subprojects/wlroots/backend/session/session.c:192 #1 0x7f88e3590e85 in wlr_session_close_file ../subprojects/wlroots/backend/session/session.c:204 #2 0x7f88e357b80c in libinput_close_restricted ../subprojects/wlroots/backend/libinput/backend.c:24 #3 0x7f88e21af274 (/lib64/libinput.so.10+0x28274) #4 0x7f88e21aff1d (/lib64/libinput.so.10+0x28f1d) #5 0x7f88e219ddac (/lib64/libinput.so.10+0x16dac) #6 0x7f88e21b415d in libinput_unref (/lib64/libinput.so.10+0x2d15d) #7 0x7f88e357c9d6 in backend_destroy ../subprojects/wlroots/backend/libinput/backend.c:130 #8 0x7f88e3545a09 in wlr_backend_destroy ../subprojects/wlroots/backend/backend.c:50 #9 0x7f88e358981a in multi_backend_destroy ../subprojects/wlroots/backend/multi/backend.c:54 #10 0x7f88e358a059 in handle_display_destroy ../subprojects/wlroots/backend/multi/backend.c:107 #11 0x7f88e314acde (/lib64/libwayland-server.so.0+0x8cde) #12 0x7f88e314b466 in wl_display_destroy (/lib64/libwayland-server.so.0+0x9466) #13 0x559fefb52385 in main ../main.c:67 #14 0x7f88e2639152 in __libc_start_main (/lib64/libc.so.6+0x27152) #15 0x559fefb4297d in _start (/home/simon/src/glider/build/glider+0x2297d) 0x614000000180 is located 320 bytes inside of 416-byte region [0x614000000040,0x6140000001e0) freed by thread T0 here: #0 0x7f88e3d0a6b0 in __interceptor_free /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:122 #1 0x7f88e35b51fb in logind_session_destroy ../subprojects/wlroots/backend/session/logind.c:270 #2 0x7f88e35905a4 in wlr_session_destroy ../subprojects/wlroots/backend/session/session.c:156 #3 0x7f88e358f440 in handle_display_destroy ../subprojects/wlroots/backend/session/session.c:65 #4 0x7f88e314acde (/lib64/libwayland-server.so.0+0x8cde) previously allocated by thread T0 here: #0 0x7f88e3d0acd8 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:153 #1 0x7f88e35b911c in logind_session_create ../subprojects/wlroots/backend/session/logind.c:746 #2 0x7f88e358f6b4 in wlr_session_create ../subprojects/wlroots/backend/session/session.c:91 #3 0x559fefb51ea6 in main ../main.c:20 #4 0x7f88e2639152 in __libc_start_main (/lib64/libc.so.6+0x27152)
2019-11-30 11:57:37 +01:00
static void handle_session_destroy(struct wl_listener *listener, void *data) {
struct wlr_drm_backend *drm =
wl_container_of(listener, drm, session_destroy);
backend_destroy(&drm->backend);
}
static void handle_parent_destroy(struct wl_listener *listener, void *data) {
struct wlr_drm_backend *drm =
wl_container_of(listener, drm, parent_destroy);
backend_destroy(&drm->backend);
}
static void sanitize_mgpu_modifiers(struct wlr_drm_format_set *set) {
for (size_t idx = 0; idx < set->len; idx++) {
// Implicit modifiers are not well-defined across devices, so strip
// them from all formats in multi-gpu scenarios.
struct wlr_drm_format *fmt = &set->formats[idx];
wlr_drm_format_set_remove(set, fmt->format, DRM_FORMAT_MOD_INVALID);
}
}
static bool init_mgpu_renderer(struct wlr_drm_backend *drm) {
if (!init_drm_renderer(drm, &drm->mgpu_renderer)) {
wlr_log(WLR_INFO, "Failed to initialize mgpu blit renderer"
", falling back to scanning out from primary GPU");
for (uint32_t plane_idx = 0; plane_idx < drm->num_planes; plane_idx++) {
struct wlr_drm_plane *plane = &drm->planes[plane_idx];
sanitize_mgpu_modifiers(&plane->formats);
}
return true;
}
// We'll perform a multi-GPU copy for all submitted buffers, we need
// to be able to texture from them
struct wlr_renderer *renderer = drm->mgpu_renderer.wlr_rend;
const struct wlr_drm_format_set *texture_formats =
wlr_renderer_get_texture_formats(renderer, WLR_BUFFER_CAP_DMABUF);
if (texture_formats == NULL) {
wlr_log(WLR_ERROR, "Failed to query renderer texture formats");
return false;
}
wlr_drm_format_set_copy(&drm->mgpu_formats, texture_formats);
sanitize_mgpu_modifiers(&drm->mgpu_formats);
drm->backend.features.timeline = drm->backend.features.timeline &&
drm->mgpu_renderer.wlr_rend->features.timeline;
return true;
}
struct wlr_backend *wlr_drm_backend_create(struct wlr_session *session,
struct wlr_device *dev, struct wlr_backend *parent) {
assert(session && dev);
2017-10-01 19:22:47 +13:00
assert(!parent || wlr_backend_is_drm(parent));
2017-06-03 15:47:33 +12:00
char *name = drmGetDeviceNameFromFd2(dev->fd);
if (name == NULL) {
wlr_log_errno(WLR_ERROR, "drmGetDeviceNameFromFd2() failed");
return NULL;
}
drmVersion *version = drmGetVersion(dev->fd);
if (version == NULL) {
wlr_log_errno(WLR_ERROR, "drmGetVersion() failed");
free(name);
return NULL;
}
2018-07-09 22:49:54 +01:00
wlr_log(WLR_INFO, "Initializing DRM backend for %s (%s)", name, version->name);
2017-06-03 15:47:33 +12:00
drmFreeVersion(version);
struct wlr_drm_backend *drm = calloc(1, sizeof(*drm));
2017-09-30 22:22:26 +13:00
if (!drm) {
2018-07-09 22:49:54 +01:00
wlr_log_errno(WLR_ERROR, "Allocation failed");
2017-05-01 17:49:18 +12:00
return NULL;
2017-05-02 13:00:25 +12:00
}
2017-09-30 22:22:26 +13:00
wlr_backend_init(&drm->backend, &backend_impl);
2017-05-01 17:49:18 +12:00
drm->backend.buffer_caps = WLR_BUFFER_CAP_DMABUF;
2017-09-30 22:22:26 +13:00
drm->session = session;
wl_list_init(&drm->fbs);
wl_list_init(&drm->connectors);
2023-11-17 13:49:18 -05:00
wl_list_init(&drm->page_flips);
2017-05-02 14:34:33 +12:00
drm->dev = dev;
drm->fd = dev->fd;
drm->name = name;
2018-09-17 22:25:20 +02:00
if (parent != NULL) {
drm->parent = get_drm_backend_from_backend(parent);
drm->parent_destroy.notify = handle_parent_destroy;
wl_signal_add(&parent->events.destroy, &drm->parent_destroy);
} else {
wl_list_init(&drm->parent_destroy.link);
2018-09-17 22:25:20 +02:00
}
2017-05-01 17:49:18 +12:00
drm->dev_change.notify = handle_dev_change;
wl_signal_add(&dev->events.change, &drm->dev_change);
2017-06-04 17:43:34 +12:00
drm->dev_remove.notify = handle_dev_remove;
wl_signal_add(&dev->events.remove, &drm->dev_remove);
drm->drm_event = wl_event_loop_add_fd(session->event_loop, drm->fd,
WL_EVENT_READABLE, handle_drm_event, drm);
2017-09-30 22:22:26 +13:00
if (!drm->drm_event) {
2018-07-09 22:49:54 +01:00
wlr_log(WLR_ERROR, "Failed to create DRM event source");
2017-05-01 17:49:18 +12:00
goto error_fd;
}
drm->session_active.notify = handle_session_active;
wl_signal_add(&session->events.active, &drm->session_active);
2017-05-14 01:12:47 +12:00
if (!check_drm_features(drm)) {
2017-08-05 18:15:39 +12:00
goto error_event;
2017-07-20 20:51:59 +12:00
}
if (!init_drm_resources(drm)) {
2017-08-05 18:15:39 +12:00
goto error_event;
}
2017-07-20 20:51:59 +12:00
if (drm->parent && !init_mgpu_renderer(drm)) {
goto error_mgpu_renderer;
}
backend/drm, backend/libinput: listen to session destroy This fixes a heap-use-after-free when the session is destroyed before the backend during wl_display_destroy: ==1085==ERROR: AddressSanitizer: heap-use-after-free on address 0x614000000180 at pc 0x7f88e3590c2d bp 0x7ffdc4e33f90 sp 0x7ffdc4e33f80 READ of size 8 at 0x614000000180 thread T0 #0 0x7f88e3590c2c in find_device ../subprojects/wlroots/backend/session/session.c:192 #1 0x7f88e3590e85 in wlr_session_close_file ../subprojects/wlroots/backend/session/session.c:204 #2 0x7f88e357b80c in libinput_close_restricted ../subprojects/wlroots/backend/libinput/backend.c:24 #3 0x7f88e21af274 (/lib64/libinput.so.10+0x28274) #4 0x7f88e21aff1d (/lib64/libinput.so.10+0x28f1d) #5 0x7f88e219ddac (/lib64/libinput.so.10+0x16dac) #6 0x7f88e21b415d in libinput_unref (/lib64/libinput.so.10+0x2d15d) #7 0x7f88e357c9d6 in backend_destroy ../subprojects/wlroots/backend/libinput/backend.c:130 #8 0x7f88e3545a09 in wlr_backend_destroy ../subprojects/wlroots/backend/backend.c:50 #9 0x7f88e358981a in multi_backend_destroy ../subprojects/wlroots/backend/multi/backend.c:54 #10 0x7f88e358a059 in handle_display_destroy ../subprojects/wlroots/backend/multi/backend.c:107 #11 0x7f88e314acde (/lib64/libwayland-server.so.0+0x8cde) #12 0x7f88e314b466 in wl_display_destroy (/lib64/libwayland-server.so.0+0x9466) #13 0x559fefb52385 in main ../main.c:67 #14 0x7f88e2639152 in __libc_start_main (/lib64/libc.so.6+0x27152) #15 0x559fefb4297d in _start (/home/simon/src/glider/build/glider+0x2297d) 0x614000000180 is located 320 bytes inside of 416-byte region [0x614000000040,0x6140000001e0) freed by thread T0 here: #0 0x7f88e3d0a6b0 in __interceptor_free /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:122 #1 0x7f88e35b51fb in logind_session_destroy ../subprojects/wlroots/backend/session/logind.c:270 #2 0x7f88e35905a4 in wlr_session_destroy ../subprojects/wlroots/backend/session/session.c:156 #3 0x7f88e358f440 in handle_display_destroy ../subprojects/wlroots/backend/session/session.c:65 #4 0x7f88e314acde (/lib64/libwayland-server.so.0+0x8cde) previously allocated by thread T0 here: #0 0x7f88e3d0acd8 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:153 #1 0x7f88e35b911c in logind_session_create ../subprojects/wlroots/backend/session/logind.c:746 #2 0x7f88e358f6b4 in wlr_session_create ../subprojects/wlroots/backend/session/session.c:91 #3 0x559fefb51ea6 in main ../main.c:20 #4 0x7f88e2639152 in __libc_start_main (/lib64/libc.so.6+0x27152)
2019-11-30 11:57:37 +01:00
drm->session_destroy.notify = handle_session_destroy;
wl_signal_add(&session->events.destroy, &drm->session_destroy);
2017-09-30 22:22:26 +13:00
return &drm->backend;
2017-05-01 17:49:18 +12:00
error_mgpu_renderer:
finish_drm_renderer(&drm->mgpu_renderer);
finish_drm_resources(drm);
2017-05-03 21:28:44 +12:00
error_event:
wl_list_remove(&drm->session_active.link);
2017-09-30 22:22:26 +13:00
wl_event_source_remove(drm->drm_event);
2017-05-01 17:49:18 +12:00
error_fd:
wl_list_remove(&drm->dev_remove.link);
wl_list_remove(&drm->dev_change.link);
wl_list_remove(&drm->parent_destroy.link);
wlr_session_close_file(drm->session, dev);
free(drm->name);
2017-09-30 22:22:26 +13:00
free(drm);
2017-05-01 17:49:18 +12:00
return NULL;
}