March 2009 - Posts
שריינו את יום שישי ה 3.4.09 (ואת הערב של יום חמישי שלפניו).
בשעה טובה כנס alt.net israel נוסף יוצא לדרך.
תודה למארגנים - רועי אושרוב, ליאור פרידמן וחן אגוזי:
בשנה שעברה היה כנס ממש טוב, למדתי המון והכרתי אחלה אנשים.
נתראה שם.
בעיית design/debugging מרגיזה, שנתקלתי בה בעבר:
נתון קוד קיים, שעובד ב production והיה צורך להוסיף פונקציונליות.
ע"מ לחקור את הפונקציונליות הקיימת הרצתי debugger , בשלב מסוים, לאחר כניסה אל פונקציה מסוימת, ה debugger השתגע - בחלון ה watch לא הראה יותר אובייקטים, אלא רק את ההודעה הבאה:
"Cannot evaluate expression because a thread is stopped at a point where
garbage collection is impossible, possibly because the code is optimized."
חיפושים בגוגל החזירו בעיקר מידע על
Funceval שלא ממש עוזר במקרה הזה.
הבעיה נבעה מ struct
ענק שהועבר כפרמטר לפונקציה,
כיוון ש struct הוא
ValueType - הוא גרם לניפוח של הגודל של הפרמטרים שעוברים לפונקציה - דבר שגרם להתרסקות של ה debugger.
את הסיבה לבעיה מצאתי (בקושי רב) בלינק הזה - בקצרה לפי מיקרוסופט:
"...generally speaking, when the total size of the arguments
passed to a callee function is larger than 256 bytes,
JIT will make the caller function partially interruptible.
In a partially interruptible code, not every location in the
code is a GC safe point. Therefore, it might be unsafe to
evaluate expression at certain locations.
When this happens you get [the error message]."
(כמובן שהבעיה יכולה גם לנבוע מפונקציה שמקבלת המווון פרמטרים).
struct אמור להיות קטן!! - לפי מיקרוסופט - "Unless you need reference type semantics, a class that is smaller than 16 bytes
may be more efficiently handled by the system as a struct."
במקרה הנדון ה struct נועד להעברת מספר די גדול של פרמטרים.
הפתרון במקרה שכזה אמור להיות שימוש ב class במקום struct להעברת כל הפרמטרים,ובדיקה האם אפשר לפצל את הלוגיקה כדי שלא ליצור פונקציה מפלצתית שתקבל המון פרמטרים.
מפאת חוסר זמן, ושימוש נרחב ב struct הנדון בפרוייקט (דבר שיצר בעיה בהפיכתו ל class), ה"פתרון" במקרה זה היה לשלוח את ה struct באמצעות ref כך מתבצע boxing שלו, והקריאה לפונקציה תופחת במשקל של פוינטר, ולא במשקל ה struct.
דרך אגב - במקרה של "פתרון" שכזה, צריך לוודא שלא משנים את ה struct בתוך הפונקציה - הוא הרי לא עובר יותר by value
שיהיה שבוע נפלא
מסביר בצורה הכי ברורה שראיתי איך התחיל המשבר הנוכחי, וכנראה איך הוא גם יסתיים :-(.
הסרטון אמנם משעשע, אבל הנושא מטריד ביותר.
ההבדל בין השוק בארץ לבין ארה"ב הוא שבארה"ב לווים בעייתיים פשוט נוטשים את הנכס וממשיכים הלאה.
בארץ לא כך הדבר - מי שלוקח משכנתא - מחזיר עד השקל האחרון - אפילו אם מכר את הנכס במחיר שלא מכסה את החוב.
אני חושב שהתנערות מחוב זה דבר בזוי (בקרב החברות הכשירו את השרץ - קוראים לזה פשיטת רגל).
אבל הבעיה לא נובעת מהלווים, אלא ממי שנתן להם את ההלואה - הבנקים, שעד להתפוצצות המשבר "העניקו" משכנתאות גם של 90% מערך הנכס.
משכנתא שכזו הינה קבר פוטנציאלי ללווה, שבמקרה של ירידה קלה בערך הנכס, כבר לא יוכל פשוט למכור ולהחזיר את החוב במקרה שייקלע לקשיים.
כיוון שאני משתמש בעיקר בשועל האש, החלטתי להכין חיקוי עלוב (לא התקנה או משהו מתוחכם) עבורו:
צרו רשומה חדשה ב Bookmarks toolbar
תנו לרשומה זו שם (לשלי קראתי Captcha Killer )
וב location תדביקו את הקוד הבא:
java[space]script: var elems = document.getElementsByTagName("*"); for (var i = 0; i < elems.length; ++i) { if (elems[i].clientvalidationfunction != null && elems[i].clientvalidationfunction == 'ValidateCaptcha') { elems[i].clientvalidationfunction = ''; alert('go go go'); } }
הקוד צריך להיות בשורה אחת, וצריך למחוק את ה [space] ב java[space]script: הכנסתי אותו בכוונה כדי שלא ייחסם ע"י העורך.
הקוד עושה בדיוק את מה ששלמה הסביר בפוסט שלו, רק בצורה שהשועל שלי יבין.
ה alert בסוף נועד למנוע מעבר לדף אחר, מסיבה לא ברורה return false ביטל את כל הפעולה, ואני חולה מידיי בשביל שיהיה איכפת לי לבדוק את זה עכשיו.