ì£¼ë³€ì— ìµœê·¼ì— ë‹¤ìŒ ì»¤ë®¤ë‹ˆì¼€ì´ì…˜ìœ¼ë¡œ 옮긴 ì‚¬ëžŒë“¤ì´ ê½¤ 있어 마ì´í”¼í”Œì— (어째서ì¸ì§€ 사내 ë©”ì‹ ì ¸) 대한 ì´ì•¼ê¸°ë¥¼ ë§Žì´ ë“£ê³ , ê¶ê¸ˆí•´ì„œ 설치를 해보았다.
ê·¸ëŸ°ë° ë§¥ì—ì„œ 기ë™ë§Œ 하면 죽는 ë¬¸ì œê°€ 있어서 ê²°êµ ì‚¬ìš©ì„ í•´ë³´ì§€ 못했는ë°, ê·¸ ì´ìœ 를 íŒŒê³ ë“¤ì–´ê°€ë³´ë‹ˆ 재미있는 ë¬¸ì œ.
ì‹¤ì œë¡œ 죽는 ê³³ì€ AIR안ì—ì„œ 죽게 ë˜ëŠ”ë°, 마ì´í”¼í”Œì—ì„œ ì‚¬ìš©ì¤‘ì¸ AIR 3.9 기준으로 아래와 같다. (주: 디버거 표시와 다르게 ì •ìˆœìœ¼ë¡œ 표기)
- ì•ž stack frameì€ ì˜ë¯¸ê°€ 없으므로 ìƒëžµ
Tamarin JIT Code (symbol-less executable page)
Tamarin JIT Code (symbol-less executable page)
Tamarin JIT Code (symbol-less executable page)
sub_52FF1C __text 000000000052FF1C
sub_345FFE __text 0000000000345FFE
sub_4BBBC6 __text 00000000004BBBC6
sub_4BB942 __text 00000000004BB942
sub_4BAC8A __text 00000000004BAC8A
0x004BAC8A + B0
ì‹¤ì œ í¬ëž˜ì‹œ 주소는 0x004BAD2D
ì¸ë° ê·¸ ì´ìœ 는 ì„¤ì •ì„ ê°€ì ¸ì˜¤ëŠ” 부분ì—ì„œ, CFArrayGetValueAtIndex
ì—ì„œ ê°€ì ¸ì˜¨ê±´ NULL ì²´í¬ë¥¼ 하나, ê·¸ 다ìŒì— CFDictionaryGetValue
ì—ì„œ ê°€ì ¸ì˜¨ ê²ƒì„ ìœ íš¨ì„± ì²´í¬ë¥¼ ì•ˆí•˜ê³ í•´ë‹¹ í¬ì¸í„°ë¥¼ CFStringCompare
를 호출하기 ë•Œë¬¸ì— ê±°ê¸°ì„œ 죽는 Adobe AIR 버그ë¼ëŠ” ê²°ë¡ . (http://developer.apple.com ë¬¸ì„œì— ì˜í•˜ë©´ NULLì´ ëŒì•„올 수 있는 ìƒí™©ì€ 분명히 있ìŒì—ë„ ë¶ˆêµ¬í•˜ê³ ì´ë ‡ê²Œ ëœë°ì—는 ì•„ë§ˆë„ ì‹œì¤‘ì— ë„는 ê´€ë ¨ 코드가 대부분 ì´ ì²´í¬ë¥¼ ìƒëžµí•˜ê¸° ë•Œë¬¸ì´ ì•„ë‹ê¹Œ ìƒê°ëœë‹¤.)
ì•žì— 2번 í”„ë ˆìž„ë¶€í„° 4번 í”„ë ˆìž„ê¹Œì§€ì˜ ë‚´ìš©ì€ ì¶”ì •ìœ¼ë¡œëŠ” ActionScript 코드 ìƒìœ¼ë¡œëŠ”, MyB.openMainWindow()
, Preferences.getItem()
, net.daum.myb.services.NativeExtension.startAtLogin()
순으로 ì¶”ì •ë˜ëŠ”ë°, ì‹¤ì œë¡œ 메모리 ë¤í”„를 확ì¸í•´ë³´ì§€ëŠ” ì•Šì•˜ê³ , AIRì—ì„œ 사용하는 Tamarinì—”ì§„ì˜ ì½”ë“œ ì œë„ˆë ˆì´í„° íŒ¨í„´ì„ ë³¸ì ì´ ì—†ì–´ì„œ 어디까지나 ì¶”ì •ì´ë‹¤. Inliningì´ ë°œìƒí•˜ì˜€ë‹¤ë©´ ë¬¼ë¡ ì´ ê°€ì„¤ì€ ë¬´íš¨ì´ì§€ë§Œ 언듯 본 ê²°ê³¼ inliningì´ ë°œìƒí• 것 같지는 않다는 소견ì´ë‹¤.
OS X ë‚´ë¶€ì— ëŒ€í•´ì„œëŠ” 잘 ëª¨ë¥´ëŠ”ì§€ë¼ ìµœì´ˆì— ì„¤ì •ì´ NULLë¡œ ëŒì•„오는게 OS ë²„ê·¸ì— ì˜í•œê±´ì§€ëŠ” ëª¨ë¥´ê² ìœ¼ë‚˜, ì¼ë‹¨ ëŒì•„온다는건 확실하기 ë•Œë¬¸ì— ì²´í¬ë¥¼ 해줘야한다는 ì‚¬ì‹¤ì„ ì´ë²ˆì— 알게 ë˜ì—ˆë‹¤. 아울러 ì´ ë²„ê·¸ê°€ Adobe AIRì˜ ê³µì‹ ìµœì‹ ë²„ì „ì¸ 4.0ì—ë„ ìžˆë‹¤ëŠ”ê²Œ ë¬¸ì œ. 꽤나 간단한 버그ì¸ë°, ì´ ë¬¸ì œë¥¼ 겪ì€ê²Œ 처ìŒì´ 아니다.
ìºë…¼ Selphy 시리즈 프린터 ë“œë¼ì´ë²„ì—ë„ ì´ ë¬¸ì œê°€ 있다. 해당 ë¬¸ì œë¥¼ ìœ ë°œí•˜ëŠ” ColorPDE.plugin
ë°”ì´ë„ˆë¦¬ë¥¼ 그대로 재현한 코드는 아래ì—. 코드 ìžì²´ê°€ 무ì˜ë¯¸í•œ 코드가 있는건 ì»´íŒŒì¼ ë˜ê¸° ì „ 코드가 어째서ì¸ì§€ ë”± ê·¸ë ‡ê²Œ í•´ì„ì´ ë˜ì–´ì„œì´ì§€ 실수가 아님. ê¶ê·¹ì 으로 파보면 ê°™ì€ ë¬¸ì œ.
실실ì ì¸ ì›ì¸ NativeApplication.supportsStartAtLogin
ë˜ëŠ” NativeApplication.nativeApplication.startAtLogin._setter
둘 중 하나ì—ì„œ ë°œìƒì„ 하게 ë˜ëŠ”ë°, 마ì´í”¼í”Œ 입장ì—ì„œ 단기 우회책으로는 ì´ê±¸ ì‚¬ìš©í•˜ê³ ìžˆëŠ” net.daum.myb.services.NativeExtension.startAtLogin()
ì—ì„œ flash.system.Capabilities.os
를 ì²´í¬í•´ì„œ Macì´ í¬í•¨ë˜ì–´ ìžˆì„ ê²½ìš° 그냥 return
ì„ í•˜ëŠ” 방법 ì •ë„ì˜ ë°©ë²• ë°–ì— ì—†ë‹¤ëŠ”ê²Œ ë¬¸ì œì¼ ë“¯. ê²°êµì€ ê¸°ëŠ¥ì„ ì¼ì‹œì 으로 죽여야하는 우회책. 런타임 ë¬¸ì œë¼ try / catch
ê°™ì€ ê²ƒìœ¼ë¡œë„ í•´ê²°ì´ ì•ˆë 것 같지가 않다.
ì´ê±¸ ì œëŒ€ë¡œ 해결해야하는 어플리케ì´ì…˜ì€ 꽤나 골치아픈 ìš°íšŒì±…ì„ ì¨ì•¼ 하는ë°, FREë¡œ ì§ì ‘ ë¬¸ì œê°€ 있는 ê¸°ëŠ¥ì„ êµ¬í˜„ì„ í•´ì•¼í•˜ëŠ”ë° ì´ê±¸ 구현해서 소스를 í’€ ì‚¬ëžŒì´ ìžˆì„지는 ëª¨ë¥´ê² ë‹¤. 어차피 AIR ê°œë°œì„ ì•ˆí•˜ë‹ˆ ë‚´ê°€ ê³ ë¯¼í• ë¬¸ì œëŠ” 아니지만.
ë‹¤í–‰ížˆë„ ì–´ë„비ì—ì„œ 해당 ë¬¸ì œë¥¼ 해결했으니 다행ì¸ë°, ì–´ë„비 ë‹´ë‹¹ìž ë§ë¡œëŠ” 출시까지 꽤나 ì‹œê°„ì´ ê±¸ë¦´ê²ƒ 같다는 ì´ì•¼ê¸°.
// Minimized version of the ColorPDE.plugin crasher
// Sangwhan Moon <[email protected]>
//
// Based on ColorPDE.plugin - Copyright (c) Canon Electronics
// Compile with:
// gcc -g -F /Library/Printers/Canon/SELPHYCP/Frameworks \
// -framework SELPHYCPUIKit -framework CoreFoundation colorpdecrasher.c
#include <Carbon/Carbon.h>
#define u kCFPreferencesCurrentUser
int main()
{
int i, j, k;
char *p, *q;
i = GetCountOfLoginItems(u);
for (j = i; j > 0 ; j--)
{
p = ReturnLoginItemPropertyAtIndex(u, 1, j-1);
q = p;
k = strcmp("foobar", q);
}
return 0;
}