מאמרים בנושא ‏C++‎‏‏.

כשעפים על מספר מעבדים

ב־יום רביעי, 8 באוגוסט 2012, מאת ארתיום; פורסם תחת: תכנה חופשית, תכנה ומחשבים, C++‎‏; ‏4 תגובות

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

אז הופנית לדיווח על באג ישן וסגור שנראה כשתי טיפות מים דומה לתעופה הזו. אז הבנתי שבכל זאת מדובר במשהו אמתי. פתחתי VirtualBox, הורדתי image של FreeBSD 9.0/64bit ותוך עשר דקות התחלתי לנסות שוב. ללא הועיל. ואז קיבלתי תוכנה שלדוגמה (טריביאלית לחלוטין) שבאמת עפה!

מעמיסים עליה כמה אלפי פניות ומידי פעם אני מקבל תעופה בפניה לאובייקט std::locale - האובייקט שמחזיק מידע על לוקל המערכת ובפרט הקידוד שלה (כדי להוסיף ל־content-type).

צללתי פנימה והתחלתי לחפור - זה היה נראה כמו באג שקשור ל־threading, ניסיתי גרסאות קומפיילר שונות ואופציות שונות - תעופה היה קבועה וברורה.

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

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

נכנסתי עוד יותר פנימה והתחלתי להדפיס את המונה (שהוצאתי בדרך לא דרך כי הוא private) ואכן - הוא ממש לא יציב, הולך וגדל עם הזמן - קרי, קיבלתי אמות - יש בעיה במונה!

המשכתי לחפור עוד יותר לעומק והגעתי לקוד שמבצע את עדכון המונה ב־‎libstdc++‎:

if (__gthread_active_p())
  __atomic_add(__mem, __val);
else
  __atomic_add_single(__mem, __val);

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

  • אם אני לא עושה קישור עם libpthread - הוא תמיד מריץ קוד עבור מערכת עם חוט יחיד.
  • אחרת תמיד מבצע פעולה אטומית.

מה הבעיה? הספרייה שלי קשורה ישירות ב־libpthread, אבל התכנה הראשית לא! בלינוקס זה לא מפריע אבל ב־FreeBSD זה לא עובד!

אז הוספתי דגלון ‎-lpthread‎ לתכנה הראשית והבעיה נפתרה ב־100% - המונה הפך ליציב ומתאפס מתי שצריך.

כנראה צריך ללכת לחברה ב־FreeBSD או ב־GCC ולפתוח באג: אם התכנה הראשית לא צריכה להפעיל חוטים באופן ישיר זה לא אומר שהספריות לא עובדות עם החוטים!

זה גם הסביר לי מדוע אותו באג שנסגר בגלל שלא היה ניתן לשחזר אותו, לא השתחזר - כי הבעיה נפתרה כנראה במקרה ע"י קישור ל־libpthread.

כך או אחרת, שמחתי שמצאתי את הבעיה, אפילו שהוא ממש לא הבעיה של ה־framework.

כיצד לא לעשות יוניקוד

ב־יום ראשון, 29 באפריל 2012, מאת ארתיום; פורסם תחת: תכנה חופשית, פיתוח, תכנה ומחשבים, C++‎‏, Unicode; ‏0 תגובות

הסיפורו של הניסיון להדפיס "שלום" במספר שפות במסוף של חלונות.

http://blog.cppcms.com/post/105

מפתח בארץ ה־IDE

ב־יום חמישי, 29 בדצמבר 2011, מאת ארתיום; פורסם תחת: תכנה חופשית, לינוקס, פיתוח, תכנה ומחשבים, C++‎‏; ‏8 תגובות

לאחרונה, הייתי צריך לבחון סביבת פיתוח משולבת (IDE) בלינוקס, ולעשות להן השוואה: איזו סביבה היא יותר מתקדמת ונוחה בהקשר של פיתוח ב־C++‎. למרות שאני כותב הרבה קוד, ויצא לי בעבר להשתמש בלא מעט IDE, ביניהם גם Visual Studio וגם KDevelop 3, אני מעדיף לעבוד עם vim, סביבת הפיתוח האולטימטיבית. אבל vim בתור "סביבת פיתוח משולבת" זה לא בדיוק מוכר. יש אנשים שאוהבים IDE... כך שפשטתי שרוולים והתחלתי לבדוק.

על הפרק עמדו מספר אופציות:

  • KDevelop שהיה לי ניסיון איתו בגסראות 3
  • Eclipse שרבים עובדים איתו
  • Netbeans שרבים ממליצים עליו

ומספר IDE נוספים: Anjuta, CodeBlocks ו־CodeLite.

התחלתי מ־KDevelop 4:

בעבר היה לי ניסיון לא רע עם KDevelop 3 והחלטתי לתת לסביבה הזו הזדמנות נוספת. לפני שאני מתחיל את הסיפור, אומר, אחרי כ־20 דקות עבודה התחלתי להרגיש שאני יותר פרודוקטיבי עם KDevelop מאשר עם vim!

הסביבה עשתה צעד עצום מאז גרסה 3. השלמה אוטומטית כמעט מושלמת ומהירה, highlighting מעולה וגם tooltips מאוד נוחים שמאפשרים לגשת לכל מקום. שילוב נוח עם CMake, הגדרות פשוטות, התנהגות ברורה, אינטגרציה עם קובצי man ועוד.

התחלתי לממש פיצ'ר מסוים עבור cppdb‏ ולראשונה הרגשתי שאני מצליח לכתוב קוד מהר יותר ומדויק יותר בהשוואה ל־vim.

הסביבה מאוד מהירה ומגיבה בצורה כמעט מידית.

מבחינת יכולת הדיבוג, הדבר היחיד שלא הצלחתי למצוא זה כיצד אני מגדיד למשל catch throw - לעצור על זריקת החריגה, בסוף, הפעלתי את זה ישירות דרך מסוף ה־gdb.

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

המשכתי ל־Eclipse

אחרי מעט הגדרות הצלחתי לגרום לו לעבוד עם קובץ Makefile הנוצר ע"י CMake, הגדרתי פרויקט והתחלתי לעבוד.

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

בנוסף, בניגוד ל־KDevelop הוא לא ידע להשלים ערכים תוך כדי הקלדה בצורה לגמרי אוטומטית, למשל אני מתחיל לכתוב my_variable הוא לא מציע לי השלמה אחרי שכתבתי my_va - צריך ללחוץ ctrl-space, אבל בסה"כ הסביבה בהחלט לא רעה ופרודוקטיבית.

התרשמתי לטובה מסימון השגיאות בקוד תוך כדי כתיבה, הוא הרגיש לי קצת יותר ברור בהשוואה ל־KDevelop, מבחינת הדיבוג המצב היה דומה לזה של KDevelop.

בכל אופן, הרגשתי שזאת סביבה ברמה מאוד גבוהה, אבל קצת אטית.

ניסיתי סביבות "קלות" יותר

אז פתחתי CodeBlocks שרבים ממליצים עליו. ויתרתי עליו די מהר - מבחינתי חוסר אינטגרציה עם כלי בניה חיצוניים הוא "deal-breaker" ובכלל לא התרשמתי ממנה יותר מידי. ניסיתי קצת codelite - גם הוא היה יותר מידי lite לטעמי.

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

גם היא ירדה מהפרק די מהר.

נותרה לי סביבת Netbeans

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

בניגוד לסביבות אחרות שזמינות ישירות ומהמאגרים של Ubuntu, ‏Netbeans לא מופיעה שם, צריך להתקין אותה בנפרד. הורדתי את הגרסה היציבה האחרונה המותאמת לפיתוח C++‎ והתקנתי.

פה הייתה לי הפתעה ממש טובה:

  • אפילו שהיא צרכת הרבה יותר זיכרון מ־eclipse ו־KDevelop הסביבה עבדה מאוד מהר, השלמה אוטומטית כמעט מושלמת ומהירה.
  • אינטגרציה מעולה עם subversion, למשל הצגת diff מאוד נוחה עם אפשרות עריכה ישירה.
  • הגדרות פשוטות
  • אינטגרציה עם CMake (שחסרה ל־eclipse)
  • תפריטים נוחים והגיוניים (ב־eclipse הן היו ממש קטסטרופה)

ועוד

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

סיכום

אחרי הרבה שנים של עבודה עם vim אני חושב שאתחיל לבחון את הגישה שלי ל־IDE מחדש. כרגע Netbeans היא הבחירה המובילה. הייתי מאוד רוצה לעבוד עם KDevelop אבל אני לא חושב שאוכל לעבוד אתו כל עוד הוא קורס.

מבחינתי יציבות ואמינות יותר חשובה מכל פיצ'ר אחר, וכרגע KDevelop לא עונה על הדרישה הבסיסית הזו וחבל.

שוחררה גרסת 1.48 של Boost שמכילה Boost.Locale

ב־יום רביעי, 16 בנובמבר 2011, מאת ארתיום; פורסם תחת: תכנה חופשית, פיתוח, תכנה ומחשבים, CppCMS, C++‎‏, Unicode, Boost‏; ‏2 תגובות

סוף סוף שוחררה גרסה 1.48 של Boost. אחד הדברים המשמעותיים בה היא שילוב של Boost.Locale - ספריית הלוקליזציה שאני פיתחתי.

קישורים:

להזכירכם, Boost.Locale פותחה כחלק מפרויקט CppCMS‏

כמה מטומטם ה־API יכול להיות

ב־יום שישי, 23 בספטמבר 2011, מאת ארתיום; פורסם תחת: תכנה חופשית, פיתוח, תכנה ומחשבים, C++‎‏; ‏3 תגובות

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

תוך כדי בירור נכנסתי למכונה וגיליתי חלונית עם הודעה בסגנון:

The library e:\mingw\lib\libsqlite3.dll is not valid windows library. Reinstalling
application may solve the problem

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

אני מצפה שפונקציה תחזיר שגיאה ולא תציג חלון! אחרי חיפוש קצר הגעתי לפונקציה SetErrorMode... שמאפשרת "לפתור" את הבעיה. אבל באמת... אם אין dll אז LoadLibrary יחזיר שגיאה אבל אם ה־dll לא ניתן לטעינה תקפיץ חלון?!?!

מי האידיוט שתכנן את ה־API הזה... בחלום הרע שלי לא הייתי מצפה להתנהגות כזו!

בקיצור: אם אתם לא חייבים אל תפתחו לחלונות!

העמוד הבא

העמוד הבא

דפים

נושאים