חיפוש פונקציות בספרייה משותפת

אם אתם כמוני – משתמשים בפונקציות של ספריות משותפות, אבל לא תמיד יודעים לאיזו ספרייה משותפת יש את הפונקציה שמשתמשים בה (בשביל לקשר אותה לתוכנית שלנו), אז אתם יכולים להירגע.

יצרתי סקריפט bash שמחפש את הפונקציה שאנחנו מעוניינים בספריות משותפות, ומחזירה את שם הקובץ (הראשון) אשר מכיל אותה.

כרגע ניתן למצוא את הסקריפט בחשבון svn של אחד הפרוייקטים שאני עושה, אך כנראה שבסופ"ש הקרוב (כלומר שבוע הבא) אצור לו גם דף באתר הבית שלי, ומשם יהיה אפשר להוריד את הגרסה היציבה של הסקריפט.

אין להתסמך על ה svn לאורך זמן בקשר לסקריפט.

אז במידה ואתם מעוניינים לעבוד עם הסקריפט, אתם מוזמנים להוריד אותו, רק חשוב לדעת שאני לא לוקח עליו שום אחריות, והוא משוחרר תחת רשיון BSD.

אם יש לכם הצעות ייעול/תיקונים/תוספות וכו', אשמח לקבל גם אותם.

8 מחשבות על “חיפוש פונקציות בספרייה משותפת

  1. ארתיום

    עידו מספר נקודות:

    1. הסקריפט שלך ימצא לא רק את הפונקציה כמו hello_world אבל גם hello_world_1 או jsp_hello_world ועוד.
    2. בנוסף היא תמצא את המחרוזת לא רק בספריה ספציפית אלא בכל ספריה אחרת שמתמשת בפונקציה הזו.

    נגיד אני רוצה למצוא לאיזו ספריה אני צריך לעשות link כדי להשתמש ב־pthreads ואני מחפש:

    ‎./find.sh -p '/usr/lib/lib*.so' -s pthread_mutex_lock
    ומה אני מקבל?

    found the string "pthread_mutex_lock" in /usr/lib/libanl.so

    אז אם אני צריך לעשות link עם libanl? לא למה? כי
    ldd /usr/lib/libanl.so
    מראה:

    libc.so.6 => /lib/libc.so.6 (0x00002b0584704000)
    libpthread.so.0 => /lib/libpthread.so.0 (0x00002b0584942000)
    /lib64/ld-linux-x86-64.so.2 (0x0000555555554000)‎

    ברור שזה ל א מה שחיפשנו.

    הדרך הנכונה לעשות דברים כאלה זה לא להמציא גלגל מחדש אלא להשתמש למשל ב־autotools ולשים ב־autoconf הוראה כמו AC_SEARCH_LIBS: למשל:

    AC_SEARCH_LIBS(gethostbyname,nsl socket)‎

    לחפש gethostbyname ב־nsl ו־socket.

    אם אתה אמת רוצה לעשות חיפוש כזה מסובך (בכל הספריות) אז אתה צריך לכתוב תכנה קטנה שתנסה לפתוח soים אחד־אחד ויקרא ל־dlsym עם הסימבול המתאים.

    טוב…

  2. ארתיום

    הנה קוד לדוגמה:

    include
    #include

    int main(int argv,char **argc)
    {
    if(argv<2) {
    fprintf(stderr,"Usage symbol libs\n");
    return 1;
    }
    char *symbol=argc[1];
    argc+=2;
    while(*argc!=NULL) {
    void *handler=dlopen(*argc,RTLD_LAZY);
    if(handler) {
    if(dlsym(handler,symbol)) {
    printf("%s found\n",*argc);
    }
    dlclose(handler);
    }
    argc++;
    }
    return 0;
    }

  3. ik_5 מאת

    הבעיה עם autotools היא שהוא בנוי רק עבור gcc ולא מתאים לשום דבר שלא קשור ל gcc (או שנכתב להיות מותאם עבורו).

    למשל בפסקל, אני לא צריך כל פעם מחדש לחפש ספריות (אתה מוזמן לראות את הקבצים שיש לי שם ב svn בשביל דוגמא), אלא רק פעם אחת לשים את זה בקוד המקור (יש יותר מדרך אחת לעשות את זה, אני מעדיף בדרך הקשה יותר לכתיבה, אבל קלה יותר לדיבוג). אני לא צריך בשביל זה configure או makefile בשביל לקשר את הספרייה ובגלל זה autotools לא מתאימים לי בכלל למה שאני צריך.

    וגם נתקלתי במצב מאוד בעייתי עכשיו. למשל הפרוצדורה xcb_prefetch_extension_data לא נמצאת בשום ספרייה שחיפשתי.

    בקשר למחרוזת לחפש, אם תחפש אותה בכל הספריות יש לך בעיה, אבל אם תחפש אותה נגיד רק בספריות של הכלים שאתה מתכנת אליהם, אז סביר להניח שזה יהיה יותר פשוט.

  4. ארתיום

    הבעיה עם autotools היא שהוא בנוי רק עבור gcc ולא מתאים לשום דבר שלא קשור ל gcc (או שנכתב להיות מותאם עבורו).

    זה לא בדיוק… autotools תומכים ברוב הקומפיילרים הסבירים של רוב ה־UNIXים הסבירים.

    בנוסף, הבאתי autotools לדוגמה, אתה יכול לקחת גם CMake או SCons (אם כי autotools הם עדיין הכלי הטוב ביותר לטעמי).

    למשל הפרוצדורה xcb_prefetch_extension_data לא נמצאת בשום ספרייה שחיפשתי.

    האם ניסית?

    pkg-config –libs xcb

  5. ik_5 מאת

    ואיך זה יעזור ? הוא יביא לי רק את הספרייה של libxcb.so אבל לא את שאר הספריות של xcb.

    והשלאה שצריך לשאול בקשר לכל הכלים האלו, היא למה צריך כל פעם בכל מחשב מחדש לחפש את המידע הזה בשביל לבנות את הקוד ?

    עם פסקל בכלל וFPC בפרט, בשביל להדר אתה צריך את שם הספרייה והוא מחפש לך אותה, והנתונים האלו נמצאים לך בקוד, וזה הכי הגיוני שזה יהיה שם, כי בסופו של דבר אתה אומר למהדר מה לעשות עם מה שכתבת, זה התפקיד שלך בתור מתכנת, אז למה להשתמש בעוד כלים מסביב ולא להגיד בתוך הקוד ?

  6. ארתיום

    ואיך זה יעזור ? הוא יביא לי רק את הספרייה של libxcb.so אבל לא את שאר הספריות של xcb.

    אולי שאר הספריות כבר מקושרות אליה?

    והשלאה שצריך לשאול בקשר לכל הכלים האלו, היא למה צריך כל פעם בכל מחשב מחדש לחפש את המידע הזה בשביל לבנות את הקוד ?

    אני לא מבין את השאלה שלך? אתה יודע באיזו ספריה אתה משתמש — השם שלה, תעשה link איתה וגמרת… המקרה שלך טריוויאלי לחלוטין, אתה לא צריך לחפש pthread_sigmask או gethostbyname ב־10 ספריות שונות בפלטפורמות שונות: אתה בסה"כ צריך לעשות link עם ספריה אחת שאתה יודע מהי…

    למה הסתבכת?

    ואגב, אתה יודע למה "צריך לחפש בכל פעם מחדש" (שזה גם לא נכון)? התשובה פשוטה מאוד — תחשוב שאתה רוצה לעבוד עם גרסאות ספריה שונות, המותקנות במקומות שונים. למשל, לפעמים אם אני רוצה לבדוק קוד מול גרסאות שונות של אותה ספריה אני מתקין אותה באופן מקומי ומקשר אליה.

    אתה סתם מסתבך, הבעיה שלך לא קשורה לא ל־C ולא ל־FPC אלא לניהול ספריות נכון.

  7. ik_5 מאת

    ארתיום אני מדבר על משהו אחד, ואתה על משהו אחר.

    בפסקל (לא רק FPC) כאשר אני עושה קישור לספרייה (סטטית או דינמית, נמצאת בתור resource או כל דרך אחרת) אני חייב לציין בקוד מה ואיך לקחת את הנתונים.

    ב gcc אתה מציין את אותו המידע דרך ה command line של gcc ואין לך דרך בקוד לכתוב מאיפה לקחת את הנתונים.

    בגלל זה, אני לא יכול להשתמש בשום כלי חיצוני.

    עכשיו בקשר לפרוצדורה שאני מחפש, שום ספרייה בדביאן testing של xcb לא מכילה אותה בפועל. היא לא מופיע בתור סימול בכלל לא פרטי ולא ציבורי.

כתיבת תגובה

הזינו את פרטיכם בטופס, או לחצו על אחד מהאייקונים כדי להשתמש בחשבון קיים:

הלוגו של WordPress.com

אתה מגיב באמצעות חשבון WordPress.com שלך. לצאת מהמערכת / לשנות )

תמונת Twitter

אתה מגיב באמצעות חשבון Twitter שלך. לצאת מהמערכת / לשנות )

תמונת Facebook

אתה מגיב באמצעות חשבון Facebook שלך. לצאת מהמערכת / לשנות )

תמונת גוגל פלוס

אתה מגיב באמצעות חשבון Google+ שלך. לצאת מהמערכת / לשנות )

מתחבר ל-%s