检测ELF可执行文件中未解析的符号

时间:2015-06-10 15:23:51

标签: c linux shared-libraries ld elf

假设我有两个文件:

// shared.c (will be compiled to 'shared.so')
#include <stdio.h>
int f() { printf("hello\n"); }

// exe.c (will be compiled to 'exe')
#include <stdio.h>
int f();
int main() { 
    int i;
    scanf("%d", &i);
    if (i == 5) f(); 
}

我按如下方式编译这两个文件:

gcc -shared shared.c -o libshared.so
gcc exe.c -o exe -lshared -L.

当我运行exe并输入5时,它将调用f然后退出。但是,如果我从f删除shared.c并重新编译它,那么只有在我输入5时我才会收到运行符号查找错误。有没有办法我可以检查exe是否包含它在这种情况下,独立于用户输入工作的符号?最好没有运行它。

2 个答案:

答案 0 :(得分:3)

您可以使用# app/assets/controllers/profiles_controller.rb class ProfilesController < ApplicationController before_action :authenticate_tutor!, except: [:show] # Everything handled by edit page def new @tutor = current_tutor if (@tutor.profile.nil?) @profile = @tutor.build_profile else @profile = @tutor.profile redirect_to edit_profile_path(@profile.id) end end def edit @tutor = current_tutor if (@tutor.profile.nil?) redirect_to new_profile_path else @profile = @tutor.profile end end def show if tutor_signed_in? @tutor = Tutor.find(current_tutor.id) @profile = Profile.find(@tutor.profile.id) else @profile = Profile.find(params[:id]) end end # POST /tutors # POST /tutors.json def create @profile = current_tutor.build_profile(profile_params) if @profile.save flash[:success] = "Profile created!" redirect_to tutors_dashboard_path else render 'new' end end # PATCH/PUT /tutors/1 # PATCH/PUT /tutors/1.json def update @profile = Profile.find(current_tutor.id) if @profile.update(profile_params) flash[:success] = "Profile updated!" redirect_to tutors_dashboard_path else render 'edit' end end private def profile_params params.require(:profile).permit(:first_name, :last_name, :postal_code, :gender, :dob, :rate, :alma_mater, :major, :degree, :address, :phone_num, :travel_radius, :bio) end end 命令列出共享库依赖项。 以下是没有Rails.application.routes.draw do root 'pages#home' get '/about' => 'pages#about' get '/contact' => 'pages#contact' get '/about-tutors' => 'pages#about_tutors' get '/about-students' => 'pages#about_students' devise_for :tutors, controllers: { confirmations: 'tutors/confirmations', passwords: 'tutors/passwords', registrations: 'tutors/registrations', sessions: 'tutors/sessions' } get '/tutors/dashboard' => 'tutors#dashboard' resources :profiles end 函数的示例的输出:

ldd -r exe

(不要介意f部分。它用于告诉在当前目录中查找共享库)

答案 1 :(得分:0)

@tohava 编译可执行文件并将其与共享对象链接时,ld(链接器)会检查可执行文件所依赖的共享对象列表中是否所有引用的符号都可用,如果任何符号未解析,则会抛出错误。

因此,当您从共享库中删除f()并重建可执行文件时,我不确定您是如何设法获得运行时错误的。 (我自己做了练习并得到了链接器错误)。