シミュレーターが起動しない2
iPhoneシミュレーターを起動しようとしたら、下記のようなエラーが出現
com.apple.iPhoneSimulator:com.apple.adlibd: Already loaded
com.apple.iPhoneSimulator:com.apple.apsd: Already loaded
com.apple.iPhoneSimulator:com.apple.aps.tcpdump.en0: Already loaded
com.apple.iPhoneSimulator:com.apple.aps.tcpdump.pdp_ip0: Already loaded
com.apple.iPhoneSimulator:com.apple.assetsd: Already loaded
com.apple.iPhoneSimulator:com.apple.AXInspector: Already loaded
com.apple.iPhoneSimulator:com.apple.calaccessd: Already loaded
com.apple.iPhoneSimulator:com.apple.certui.relay: Already loaded
com.apple.iPhoneSimulator:com.apple.dataaccess.dataaccessd: Already loaded
com.apple.iPhoneSimulator:com.apple.gamed: Already loaded
com.apple.iPhoneSimulator:com.apple.gmmd: Already loaded
com.apple.iPhoneSimulator:com.apple.lsd: Already loaded
com.apple.iPhoneSimulator:com.apple.managedconfiguration.mdmd: Already loaded
com.apple.iPhoneSimulator:com.apple.managedconfiguration.profiled: Already loaded
com.apple.iPhoneSimulator:com.apple.marcod.tcpdump.en0: Already loaded
com.apple.iPhoneSimulator:com.apple.marcoagent: Already loaded
com.apple.iPhoneSimulator:com.apple.mdt: Already loaded
com.apple.iPhoneSimulator:com.apple.midiserver.sim: Already loaded
com.apple.iPhoneSimulator:com.apple.mobile.installd: Already loaded
com.apple.iPhoneSimulator:com.apple.mobile.profile_janitor: Already loaded
com.apple.iPhoneSimulator:com.apple.printd: Already loaded
com.apple.iPhoneSimulator:com.apple.search.appindexer: Already loaded
com.apple.iPhoneSimulator:com.apple.searchd: Already loaded
com.apple.iPhoneSimulator:com.apple.securityd: Already loaded
com.apple.iPhoneSimulator:com.apple.UIKit.pasteboardd: Already loaded
初見で焦ったけど、よく考えたらシミュレーターを起動したのがスーパーユーザーだったのが災い。
ちゃんと他ユーザで起動したら動いてくれた
デバッグを効率化するアイディア
デバッグを簡単にする一つのアイディア。
実行したメソッドの、クラス名、メソッド名、引数をすべてGDBに出力します。
これでエラーが起きた時にメソッドの逆追いが凄く楽になります。
void DEBUG_PRINT( id my , SEL sel , char *argv , ... ) { printf("%s",[[NSString stringWithFormat:@"[Class:]%@ [Method:]%s",[my class],sel ] UTF8String]); //引数 ... の部分を展開 va_start( list , argv ); for( cp=( char * )argv ; *cp != '\0' ; cp++ ) { //\0→バックスラッシュに変換してね switch ( *cp ){ case 's': printf( "%s" , va_arg( list , char * ) ); break; //Cのchar*(文字列) case 'f': printf( "%f" , va_arg( list , float ) ); break; //Cのfloat、CGFloatなど case 'c': printf( "%c" , va_arg( list , char ) ); break; //Cのcharなど case 'i': printf( "%d" , va_arg( list , int ) ); break; //Cのint、CGIntなど case 'S': printf( "%s" ,[va_arg( list , void* ) UTF8String]); break; //NSString* case 'C': printf( "%s" ,[[va_arg( list , void* ) class] UTF8String]; break; //インスタンス //引数に使いたいデータ型を追加してね } printf(","); //データの区切り } va_end( list ); printf ("\n"); //¥→バックスラッシュに変換してね }
このC関数をどこかに記述して、使いたい〜.mで#include(#import)してください。
通常、各メソッドで引数のデータ型も個数もバラバラだろうと思いますので、違いを吸収するためにC特有の可変長引数を使用しています(引数の...の部分)
使い方は各メソッドの一番最初に
-(void)Sample:(int)num :(NSString*)nsstr :(MyClass*)mycls{ DEBUG_PRINT( self , _cmd , "iSC" , num , nsstr , mycls ); //以下メソッドのプログラム〜 }
DEBUG_PRINTを挿入し、1つ目の引数はself、2つ目は_cmd
3つ目は、各引数のデータ型を指定してやります。上記の例ならば
"iSC" → 1つ目の引数i(int型) 2つ目の引数S(NSString*型) 3つ目の引数C(クラス)
各文字の意味はDEBUG_PRINT関数を見てください。
適宜プログラムに合わせて必要なデータ型を追加してください。
上記の出力イメージは
[Class:]SampleClass [Method:]Sample:int:NSString*:MyClass:10,引数文字列,MyClass
呼び出されたクラス、メソッド、引数の型、引数の内容がそれぞれ出力されます
ちなみにDEBUG_PRINTはC関数ではなくObjective-Cのメソッドに出来るのですが、たまたま今使っているのがCだったので、そのまま出しちゃいます。
バグがあったら教えて下さい
FireFoxでYoutubeが見られない
この手の記事は見つくしたよ〜という方、ここは一味ちがいますぜ。
通常のYoutube見られない記事は「再生ボタン」は表示されているのが前提で、私の子狐さんが罹った病は、画面真っ黒、再生ボタンなし、右クリックしても通常のHTML上のメニューしかでない!(FlashPlayerのメニューすら出ない)
なんということ。瀕死だ。余命いくばく、今夜が山です状態。
この重篤な病状に私がとった手段はひとつ、FireFoxをアップデートしよう!
アドオンの未対応が嫌で、Firefoxを古い8.0のままにしていたのです。
これはイカン。
ヘルプ→FireFoxについて→ソフトウェアの更新を確認
ボタンを押して無事アップデートしたら解決です。
キャッチできない例外をキャッチする
@try @catchなどを使ってもEXE_BAD_ACCESSなどのアクセス共有違反をキャッチ出来ないケースがある(シミュレータではできず、実機ではできることも多い。デバッグができない)
アプリが唐突に落ちてしまい、次回起動したとき最初から操作してもらうのは、いかがなものかと考えておられる人も多いのでは?
そこで、シグナルをキャッチする処理をかましてやることにした。
〜AppDelegate.mにて
#include <signal.h> void Clientsigcatch(int sig) { /* ここで終了に必要な処理 (次回起動時に現状を復元するため、変数をファイルに書き込む等) */ signal(sig,SIG_DFL); } //シグナルをキャッチする設定 bool signalSetting(){ struct sigaction myAction; memset( &myAction, 0, sizeof(struct sigaction) ); myAction.sa_handler = Clientsigcatch; if (sigfillset(&myAction.sa_mask) < 0){ printf("sigfillsetエラー"); return false; } myAction.sa_flags = SA_RESTART; signal(SIGILL ,Clientsigcatch); signal(SIGSEGV,Clientsigcatch); signal(SIGABRT,Clientsigcatch); signal(SIGALRM,Clientsigcatch); signal(SIGBUS ,Clientsigcatch); signal(SIGCHLD,Clientsigcatch); signal(SIGCONT,Clientsigcatch); signal(SIGFPE ,Clientsigcatch); signal(SIGHUP ,Clientsigcatch); signal(SIGINT ,Clientsigcatch); signal(SIGPIPE,Clientsigcatch); signal(SIGQUIT,Clientsigcatch); signal(SIGTERM,Clientsigcatch); signal(SIGTSTP,Clientsigcatch); signal(SIGTTIN,Clientsigcatch); signal(SIGTTOU,Clientsigcatch); signal(SIGPROF,Clientsigcatch); signal(SIGSYS ,Clientsigcatch); signal(SIGTRAP,Clientsigcatch); signal(SIGXCPU,Clientsigcatch); signal(SIGXFSZ,Clientsigcatch); return true; } //アプリケーション起動直後 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { signalSetting(); //必要 ・・・
シグナルは全部キャッチしてやることにしたけれども、もっといい方法あるかもしれない。
どうしてアプリが落ちてしまったのか?を判断するのはClientsigcatch関数の引数sigで分かる。
たとえば、sig==11はよく出る。
何が原因かは/usr/include/sys/signal.hを参照すると、
#define SIGHUP 1 /* hangup */ #define SIGINT 2 /* interrupt */ #define SIGQUIT 3 /* quit */ #define SIGILL 4 /* illegal instruction (not reset when caught) */ #define SIGTRAP 5 /* trace trap (not reset when caught) */ #define SIGABRT 6 /* abort() */ #if (defined(_POSIX_C_SOURCE) && !defined(_DARWIN_C_SOURCE)) #define SIGPOLL 7 /* pollable event ([XSR] generated, not supported) */ #else /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ #define SIGIOT SIGABRT /* compatibility */ #define SIGEMT 7 /* EMT instruction */ #endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ #define SIGFPE 8 /* floating point exception */ #define SIGKILL 9 /* kill (cannot be caught or ignored) */ #define SIGBUS 10 /* bus error */ #define SIGSEGV 11 /* segmentation violation */ //キミキミ!ここだここだ! #define SIGSYS 12 /* bad argument to system call */ #define SIGPIPE 13 /* write on a pipe with no one to read it */ #define SIGALRM 14 /* alarm clock */ #define SIGTERM 15 /* software termination signal from kill */ #define SIGURG 16 /* urgent condition on IO channel */ #define SIGSTOP 17 /* sendable stop signal not from tty */ #define SIGTSTP 18 /* stop signal from tty */ #define SIGCONT 19 /* continue a stopped process */ #define SIGCHLD 20 /* to parent on child stop or exit */ #define SIGTTIN 21 /* to readers pgrp upon background tty read */ #define SIGTTOU 22 /* like TTIN for output if (tp->t_local<OSTOP) */ #if (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) #define SIGIO 23 /* input/output possible signal */ #endif #define SIGXCPU 24 /* exceeded CPU time limit */ #define SIGXFSZ 25 /* exceeded file size limit */ #define SIGVTALRM 26 /* virtual time alarm */ #define SIGPROF 27 /* profiling time alarm */ #if (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) #define SIGWINCH 28 /* window size changes */ #define SIGINFO 29 /* information request */ #endif #define SIGUSR1 30 /* user defined signal 1 */ #define SIGUSR2 31 /* user defined signal 2 */
#define SIGSEGV 11 /* segmentation violation */
セグメンテーション違反、つまりアクセスできない領域を参照している。
これEXE_BAD_ACCESSということ。
ちなみに、デバッグ時にタスクの赤丸を押してアプリを終了しても、上記関数は呼び出されない(SIGKILLを受信するがLinuxの仕様上キャッチできない)
iPhoneシミュレータが起動しない
アプリケーションiOSシミュレータ.appは、ほかの人が使用しているため開くことができません。
そのユーザーにアプリケーションを終了するように依頼してから、もう一度試してください。
というメッセージとか、
[Session started at 2012-12-20 00:56:55 +0900.]
Failed to launch simulator: Operation failed with underlying error 4294956467.
とか、
[Session started at 2012-12-20 00:34:29 +0900.]
Cannot launch in simulator while it is already in use.
GDBにこんなメッセージが表示。
シミュレータが起動しない。
原因は、シミュレータのプロセスが残存しているのに、もう一つ起動しようとしてエラーとなっている。
なのでプロセスを一度消す。アプリケーションからターミナルを開き、
$ ps aux | grep 'iphonesimulator'
で見ると
/プロジェクトディレクトリ/build/Debug-iphonesimulator/実行ファイル名.app/実行ファイル名 -RegisterForSystemEvents
/Developer/Platforms/iPhoneSimulator.platform/Developer/Applications/iPhone Simulator.app/Contents/MacOS/iPhone Simulator -SimulateApplication /プロジェクトディレクトリ/Debug-iphonesimulator/実行ファイル名.app/実行ファイル名
といったプロセルが2つ見つかるので、
kill -9 プロセスID
で消してやる。
そのあとXCodeを再起動が必要だけど
「内部エラー、キャッチできなかった例外」てウィンドウが出てXCodeが固まることがある。
ターミナルでXCodeをKillするかアクティビティモニタでXCodeを強制終了させてやる。
再度XCodeを起動すると、シミュレータが起動するようになる
ファイル終端まで読み込めない
Macの改行コード(CR)のままファイルを読み込むと、1行読み込んだらすぐにEOFがかえってきた。
→改行コードをLFに変えると、EOFが返ってくることはない
たとえば
while ( fgets(buffer,256,filePointer) != NULL ){ printf("%s",buffer); }
ってファイル全部を読み込んで標準出力しようとしても、1行分しか表示されない
while ((buffer=fgetc(filePointer)) != EOF){ printf("%c",buffer); }
これも1行分しか表示されない(テキスト/バイナリ両者で)
Mac妙なことになっとる