Yuhang Zheng

关于动态库的链接调用问题的排查

N 人看过

日前在移植LSDK2108的时候,发现在启动weston服务的时候会报以下的错误

root@forlinx:~# weston --tty=1
Date: 2022-04-09 CST
[16:30:47.231] weston 9.0.0
               https://wayland.freedesktop.org
               Bug reports to: https://gitlab.freedesktop.org/wayland/weston/issues/
               Build: lf-5.10.35-2.0.0-rc2-1-gbf611255
[16:30:47.232] Command line: weston --tty=1
[16:30:47.232] OS: Linux, 5.10.35-g46e1a09b0512, #1 SMP PREEMPT Sat Apr 9 13:20:41 CST 2022, aarch64
[16:30:47.233] Using config file '/etc/xdg/weston/weston.ini'
[16:30:47.234] Output repaint window is 7 ms maximum.
[16:30:47.235] Loading module '/usr/lib/libweston-9/drm-backend.so'
[16:30:47.239] initializing drm backend
[16:30:47.244] using /dev/dri/card0
[16:30:47.245] DRM: supports atomic modesetting
[16:30:47.245] DRM: supports GBM modifiers
[16:30:47.245] DRM: supports picture aspect ratio
[16:30:47.245] Loading module '/usr/lib/libweston-9/gl-renderer.so'
[16:30:47.268] Failed to load module: /lib/libEGL.so.1: undefined symbol: gbm_surface_set_in_fence_fd
[16:30:47.268] failed to initialize egl
[16:30:47.269] fatal: failed to create compositor backend
Internal warning: debug scope 'drm-backend' has not been destroyed.

从错误上来看,就是加载/lib/libEGL.so.1模块的时候找不到gbm_surface_set_in_fence_fd符号

我们可以使用ldd -r /lib/libEGL.so.1命令来验证这一问题

root@forlinx:~# ldd -r /lib/libEGL.so.1
        linux-vdso.so.1 (0x0000ffff9ae6f000)
        libGAL.so => /lib/libGAL.so (0x0000ffff9ac04000)
        libwayland-server.so.0 => /lib/aarch64-linux-gnu/libwayland-server.so.0 (0x0000ffff9abe0000)
        libwayland-client.so.0 => /lib/aarch64-linux-gnu/libwayland-client.so.0 (0x0000ffff9abc1000)
        libdrm.so.2 => /lib/aarch64-linux-gnu/libdrm.so.2 (0x0000ffff9ab9f000)
        libgbm.so.1 => /lib/aarch64-linux-gnu/libgbm.so.1 (0x0000ffff9ab81000)
        libgbm_viv.so => /lib/libgbm_viv.so (0x0000ffff9ab6c000)
        libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000ffff9ab3c000)
        libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffff9a9c9000)
        /lib/ld-linux-aarch64.so.1 (0x0000ffff9ae3f000)
        libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000ffff9a91c000)
        libdl.so.2 => /lib/aarch64-linux-gnu/libdl.so.2 (0x0000ffff9a908000)
        libffi.so.7 => /lib/aarch64-linux-gnu/libffi.so.7 (0x0000ffff9a8ef000)
        libexpat.so.1 => /lib/aarch64-linux-gnu/libexpat.so.1 (0x0000ffff9a8b8000)
undefined symbol: gbm_surface_set_in_fence_fd   (/lib/libEGL.so.1)

在上面的打印信息中,我们也看到了/lib/libEGL.so.1所链接的其他动态库

这个时候,我们去源码中找一个看看gbm_surface_set_in_fence_fd函数到底是在哪里定义的

zyh@1ffe9f7b637e:~/workspace/LSDK2108_ME/flexbuild_lsdk2108/components/apps/graphics$ grep -nr "gbm_surface_set_in_fence_fd" ./
匹配到二进制文件 ./gpulib/gpu-core/usr/lib/wayland/libEGL.so.1.5.0
匹配到二进制文件 ./gpulib/gpu-core/usr/lib/libgbm.so.1.0.0
./gpulib/gpu-core/usr/include/gbm.h:399:gbm_surface_set_in_fence_fd(struct gbm_surface *surface, int fd);

结果我们发现,只有在./gpulib/gpu-core/usr/include/gbm.h文件中找到了这个函数的声明,但是却找不到这个函数的定义的源码,同时我们也发现了,在

./gpulib/gpu-core/usr/lib/wayland/libEGL.so.1.5.0
./gpulib/gpu-core/usr/lib/libgbm.so.1.0.0

这两个动态库里面有关于gbm_surface_set_in_fence_fd的内容。

不过我们通过上面的打印信息也知道了,libEGL.so.1库会去它所链接的库里面去寻找gbm_surface_set_in_fence_fd函数,那么综上所述,大概率就是libgbm.so.1.0.0库里面有gbm_surface_set_in_fence_fd函数的实现方法了。

我们可以通过命令来验证一下

root@forlinx:~# nm -D /lib/libEGL.so.1.5.0
0000000000064190 D _EGL_VERSION
...
                 U gbm_device_get_fd
                 U gbm_surface_set_in_fence_fd
                 U gbm_viv_surface_enqueue
                 U gbm_viv_surface_get_free_buffer
                 U gcfSTATISTICS_MarkFrameEnd
...
root@forlinx:~# nm -D /lib/libgbm.so.1.0.0
...
0000000000001820 T gbm_surface_destroy
0000000000001860 T gbm_surface_get_in_fence_fd
0000000000001850 T gbm_surface_has_free_buffers
0000000000001830 T gbm_surface_lock_front_buffer
0000000000001840 T gbm_surface_release_buffer
0000000000001870 T gbm_surface_set_in_fence_fd
0000000000001880 T gbm_surface_set_sync_post
                 U gbm_viv_backend
                 U getenv
                 U strcmp
...

nm -D *.so 有两个符号:U和T,U代表so中调用了这个接口,但没有具体实现。T代表so中有该函数的具体实现代码

从上面的信息中,我们看到了/lib/libgbm.so.1.0.0库里面是有gbm_surface_set_in_fence_fd函数的实现方法的呀,而且libEGL.so.1也去链接了libEGL.so.1库,那为什么还有加载/lib/libEGL.so.1模块的时候找不到gbm_surface_set_in_fence_fd符号呢?

这个时候细心的话就发现了,/lib/libEGL.so.1去链接的库是/lib/aarch64-linux-gnu/libgbm.so.1,位置是不太一样的,那我们同样用nm -D命令去查看一下/lib/aarch64-linux-gnu/libgbm.so.1库吧

root@forlinx:~# nm -D /lib/aarch64-linux-gnu/libgbm.so.1
                 U XML_ErrorString
                 U XML_GetBuffer
                 U XML_GetCurrentColumnNumber
                 U XML_GetCurrentLineNumber
                 U XML_GetErrorCode
                 U XML_ParseBuffer
                 U XML_ParserCreate
                 U XML_ParserFree
                 U XML_SetElementHandler
                 U XML_SetUserData
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 U __asprintf_chk
                 U __cxa_atexit
                 w __cxa_finalize
                 U __errno_location
                 U __fprintf_chk
                 U __fxstat64
                 w __gmon_start__
                 U __progname_full
                 U __snprintf_chk
                 U __stack_chk_fail
                 U __stack_chk_guard
                 U __vfprintf_chk
                 U abort
                 U alphasort64
                 U calloc
                 U close
                 U dlclose
                 U dlerror
                 U dlopen
                 U dlsym
                 U drmCommandWriteRead
                 U drmFreeDevice
                 U drmFreeVersion
                 U drmGetDevice2
                 U drmGetVersion
                 U drmIoctl
                 U free
0000000000003028 T gbm_bo_create
0000000000003068 T gbm_bo_create_with_modifiers
0000000000002fe8 T gbm_bo_destroy
0000000000002bb8 T gbm_bo_get_bpp
0000000000002f78 T gbm_bo_get_device
0000000000002f88 T gbm_bo_get_fd
0000000000002bb0 T gbm_bo_get_format
0000000000002f80 T gbm_bo_get_handle
0000000000002fa8 T gbm_bo_get_handle_for_plane
0000000000002b90 T gbm_bo_get_height
0000000000002fb8 T gbm_bo_get_modifier
0000000000002f68 T gbm_bo_get_offset
0000000000002f98 T gbm_bo_get_plane_count
0000000000002ba8 T gbm_bo_get_stride
0000000000002b98 T gbm_bo_get_stride_for_plane
0000000000002fe0 T gbm_bo_get_user_data
0000000000002b88 T gbm_bo_get_width
00000000000030c8 T gbm_bo_import
00000000000030d8 T gbm_bo_map
0000000000002fd8 T gbm_bo_set_user_data
0000000000003128 T gbm_bo_unmap
0000000000002fc8 T gbm_bo_write
0000000000002a28 T gbm_create_device
0000000000002b68 T gbm_device_destroy
0000000000002b40 T gbm_device_get_backend_name
0000000000002b38 T gbm_device_get_fd
0000000000002b58 T gbm_device_get_format_modifier_plane_count
0000000000002b48 T gbm_device_is_format_supported
0000000000003208 T gbm_format_get_name
0000000000003138 T gbm_surface_create
0000000000003150 T gbm_surface_create_with_modifiers
00000000000031a0 T gbm_surface_destroy
00000000000031d0 T gbm_surface_has_free_buffers
00000000000031b0 T gbm_surface_lock_front_buffer
00000000000031c0 T gbm_surface_release_buffer
                 U getenv
                 U geteuid
                 U getuid
                 U malloc
                 U memcpy
                 U mmap64
                 U munmap
                 U open64
                 U pow
                 U program_invocation_name
                 U pthread_mutex_init
                 U pthread_mutex_lock
                 U pthread_mutex_unlock
                 U read
                 U readlink
                 U realloc
                 U realpath
                 U regcomp
                 U regexec
                 U regfree
                 U scandir64
                 U stderr
                 U strcasecmp
                 U strchr
                 U strcmp
                 U strdup
                 U strerror
                 U strlen
                 U strncmp
                 U strndup
                 U strrchr
                 U strspn
                 U strstr
                 U wl_buffer_interface
                 U wl_resource_get_user_data
                 U wl_resource_instance_of

结果可以看到,/lib/aarch64-linux-gnu/libgbm.so.1动态库里面确实是没有gbm_surface_set_in_fence_fd符号的,那简单的解决方法就是

root@forlinx:~# cp /lib/libgbm.so.1.0.0 /lib/aarch64-linux-gnu/libgbm.so.1.0.0

之后我们再运行一下weston –tty=1看一下

root@forlinx:~# weston --tty=1
Date: 2022-04-11 CST
[13:08:19.718] weston 9.0.0
               https://wayland.freedesktop.org
               Bug reports to: https://gitlab.freedesktop.org/wayland/weston/issues/
               Build: lf-5.10.35-2.0.0-rc2
[13:08:19.719] Command line: weston --tty=1
[13:08:19.719] OS: Linux, 5.10.35-g46e1a09b0512, #1 SMP PREEMPT Sat Apr 9 16:53:59 CST 2022, aarch64
[13:08:19.719] Using config file '/etc/xdg/weston/weston.ini'
[13:08:19.720] Output repaint window is 7 ms maximum.
[13:08:19.720] Loading module '/usr/lib/libweston-9/drm-backend.so'
[13:08:19.724] Failed to load module: /usr/lib/libweston-9/drm-backend.so: undefined symbol: gbm_surface_get_in_fence_fd
[13:08:19.724] fatal: failed to create compositor backend
root@forlinx:~# cp /lib/libgbm.so.1.0.0 /lib/aarch64-linux-gnu/libgbm.so.1.0.0
root@forlinx:~# weston --tty=1
Date: 2022-04-11 CST
[13:12:19.236] weston 9.0.0
               https://wayland.freedesktop.org
               Bug reports to: https://gitlab.freedesktop.org/wayland/weston/issues/
               Build: lf-5.10.35-2.0.0-rc2
[13:12:19.236] Command line: weston --tty=1
[13:12:19.236] OS: Linux, 5.10.35-g46e1a09b0512, #1 SMP PREEMPT Sat Apr 9 16:53:59 CST 2022, aarch64
[13:12:19.236] Using config file '/etc/xdg/weston/weston.ini'
[13:12:19.236] Output repaint window is 7 ms maximum.
[13:12:19.237] Loading module '/usr/lib/libweston-9/drm-backend.so'
[13:12:19.244] initializing drm backend
[13:12:19.248] using /dev/dri/card0
[13:12:19.248] DRM: supports atomic modesetting
[13:12:19.248] DRM: supports GBM modifiers
[13:12:19.248] DRM: supports picture aspect ratio
[13:12:19.248] Loading module '/usr/lib/libweston-9/gl-renderer.so'
[13:12:19.305] EGL client extensions: EGL_EXT_client_extensions
               EGL_EXT_platform_base EGL_KHR_platform_wayland
               EGL_EXT_platform_wayland EGL_KHR_platform_gbm
[13:12:19.310] EGL version: 1.5
[13:12:19.310] EGL vendor: Vivante Corporation
[13:12:19.310] EGL client APIs: OpenGL_ES OpenGL OpenVG
[13:12:19.310] EGL extensions: EGL_KHR_fence_sync EGL_KHR_reusable_sync
               EGL_KHR_wait_sync EGL_KHR_image EGL_KHR_image_base
               EGL_KHR_image_pixmap EGL_KHR_gl_texture_2D_image
               EGL_KHR_gl_texture_cubemap_image EGL_KHR_gl_renderbuffer_image
               EGL_EXT_image_dma_buf_import
               EGL_EXT_image_dma_buf_import_modifiers EGL_KHR_lock_surface
               EGL_KHR_create_context EGL_KHR_no_config_context
               EGL_KHR_surfaceless_context EGL_KHR_get_all_proc_addresses
               EGL_EXT_create_context_robustness EGL_EXT_protected_surface
               EGL_EXT_protected_content EGL_EXT_buffer_age
               EGL_ANDROID_native_fence_sync EGL_WL_bind_wayland_display
               EGL_WL_create_wayland_buffer_from_image EGL_KHR_partial_update
               EGL_EXT_swap_buffers_with_damage
               EGL_KHR_swap_buffers_with_damage EGL_EXT_pixel_format_float
[13:12:19.310] EGL_KHR_surfaceless_context available
[13:12:19.331] GL version: OpenGL ES 3.1 V6.4.3.p2.336687
[13:12:19.331] GLSL version: OpenGL ES GLSL ES 3.10
[13:12:19.331] GL vendor: Vivante Corporation
[13:12:19.331] GL renderer: Vivante GC7000UL
[13:12:19.331] GL extensions: GL_OES_vertex_type_10_10_10_2
               GL_OES_vertex_half_float GL_OES_element_index_uint
               GL_OES_mapbuffer GL_OES_vertex_array_object
               GL_OES_compressed_ETC1_RGB8_texture
               GL_OES_compressed_paletted_texture GL_OES_texture_npot
               GL_OES_rgb8_rgba8 GL_OES_depth_texture
               GL_OES_depth_texture_cube_map GL_OES_depth24 GL_OES_depth32
               GL_OES_packed_depth_stencil GL_OES_fbo_render_mipmap
               GL_OES_get_program_binary GL_OES_fragment_precision_high
               GL_OES_standard_derivatives GL_OES_EGL_image
               GL_OES_EGL_image_external GL_OES_EGL_image_external_essl3
               GL_OES_EGL_sync GL_OES_texture_stencil8
               GL_OES_shader_image_atomic
               GL_OES_texture_storage_multisample_2d_array
               GL_OES_required_internalformat GL_OES_surfaceless_context
               GL_OES_draw_buffers_indexed GL_OES_texture_border_clamp
               GL_OES_texture_buffer GL_OES_texture_cube_map_array
               GL_OES_draw_elements_base_vertex GL_OES_texture_half_float
               GL_OES_texture_float GL_KHR_blend_equation_advanced
               GL_KHR_debug GL_KHR_robustness
               GL_KHR_robust_buffer_access_behavior
               GL_EXT_texture_type_2_10_10_10_REV
               GL_EXT_texture_compression_dxt1 GL_EXT_texture_format_BGRA8888
               GL_EXT_texture_compression_s3tc GL_EXT_read_format_bgra
               GL_EXT_multi_draw_arrays GL_EXT_frag_depth
               GL_EXT_discard_framebuffer GL_EXT_blend_minmax
               GL_EXT_multisampled_render_to_texture
               GL_EXT_color_buffer_half_float GL_EXT_color_buffer_float
               GL_EXT_robustness GL_EXT_texture_sRGB_decode
               GL_EXT_draw_buffers_indexed GL_EXT_texture_border_clamp
               GL_EXT_texture_buffer GL_EXT_texture_cube_map_array
               GL_EXT_multi_draw_indirect GL_EXT_draw_elements_base_vertex
               GL_EXT_texture_rg GL_EXT_protected_textures GL_EXT_sRGB
               GL_VIV_direct_texture
[13:12:19.332] GL ES 2 renderer features:
               read-back format: BGRA
               wl_shm sub-image to texture: yes
               EGL Wayland extension: yes
[13:12:19.343] event0  - InputEmulator: is tagged by udev as: Keyboard
[13:12:19.343] event0  - InputEmulator: device is a keyboard
[13:12:19.361] libinput: configuring device "InputEmulator".
[13:12:19.362] DRM: head 'DP-1' found, connector 56 is connected, EDID make 'unknown', model 'unknown', serial 'unknown'
[13:12:19.362] Registered plugin API 'weston_drm_output_api_v1' of size 24
[13:12:19.362] no available modes for DP-1
[13:12:19.362] Cannot configure an output using weston_drm_output_api.
[13:12:19.363] event0  - InputEmulator: device removed

虽然显示仍有其他的问题,但是至少库找不到引用符号的问题解决了,接下来就是继续慢慢求索了。