From: Good Guy Date: Wed, 30 Mar 2016 22:01:40 +0000 (-0600) Subject: merge: leaks, nested seq segv, ffmpeg avi frames X-Git-Url: https://git.cinelerra-gg.org/git/?a=commitdiff_plain;h=50a589b1decdd353a984d8a710e064ebaf8b4f7b;p=goodguy%2Fhistory.git merge: leaks, nested seq segv, ffmpeg avi frames --- diff --git a/cinelerra-5.1/bld_scripts/bld_package.sh b/cinelerra-5.1/bld_scripts/bld_package.sh index ff715bf4..9a88437a 100755 --- a/cinelerra-5.1/bld_scripts/bld_package.sh +++ b/cinelerra-5.1/bld_scripts/bld_package.sh @@ -14,7 +14,12 @@ proj="cinelerra5" base="cinelerra-5.1" centos="centos-7.0-1406" +fedora="fedora-23" +leap="leap-42.1" +mint="mint-14.04.1" suse="opensuse-13.2" +ub14="ubuntu-14.04.1" +ub15="ubuntu-15.10" ubuntu="ubuntu-14.04.1" eval os="\${$dir}" diff --git a/cinelerra-5.1/cinelerra/asset.C b/cinelerra-5.1/cinelerra/asset.C index 598068eb..5350004c 100644 --- a/cinelerra-5.1/cinelerra/asset.C +++ b/cinelerra-5.1/cinelerra/asset.C @@ -1014,17 +1014,17 @@ int Asset::dump(FILE *fp) fprintf(fp," ff_video_bitrate=%d\n", ff_video_bitrate); fprintf(fp," ff_video_quality=%d\n", ff_video_quality); fprintf(fp," audio_data %d channels %d samplerate %d bits %d" - " byte_order %d signed %d header %d dither %d acodec %c%c%c%c\n", + " byte_order %d signed %d header %d dither %d acodec %4.4s\n", audio_data, channels, sample_rate, bits, byte_order, signed_, - header, dither, acodec[0], acodec[1], acodec[2], acodec[3]); + header, dither, acodec); fprintf(fp," audio_length %jd\n", audio_length); char string[BCTEXTLEN]; ilacemode_to_xmltext(string, interlace_mode); fprintf(fp," video_data %d program %d layers %d framerate %f width %d" - " height %d vcodec %c%c%c%c aspect_ratio %f ilace_mode %s\n", + " height %d vcodec %4.4s aspect_ratio %f ilace_mode %s\n", video_data, layers, program, frame_rate, width, height, - vcodec[0], vcodec[1], vcodec[2], vcodec[3], aspect_ratio,string); - printf(" reel_name %s reel_number %i tcstart %jd tcend %jd tcf %d\n", + vcodec, aspect_ratio,string); + fprintf(fp," reel_name %s reel_number %i tcstart %jd tcend %jd tcf %d\n", reel_name, reel_number, tcstart, tcend, tcformat); fprintf(fp," video_length %jd \n", video_length); diff --git a/cinelerra-5.1/cinelerra/asset.inc b/cinelerra-5.1/cinelerra/asset.inc index 291709df..2b73d0b0 100644 --- a/cinelerra-5.1/cinelerra/asset.inc +++ b/cinelerra-5.1/cinelerra/asset.inc @@ -22,11 +22,7 @@ #ifndef ASSET_INC #define ASSET_INC - class Asset; -class InterlaceautofixoptionItem; class InterlacefixmethodItem; - - #endif diff --git a/cinelerra-5.1/cinelerra/assetedit.C b/cinelerra-5.1/cinelerra/assetedit.C index cb633437..92e70a2a 100644 --- a/cinelerra-5.1/cinelerra/assetedit.C +++ b/cinelerra-5.1/cinelerra/assetedit.C @@ -517,7 +517,7 @@ void AssetEditWindow::create_objects() add_subwindow(new BC_Title(x, y, _("Frame rate:"))); x = x2; - sprintf(string, "%.2f", asset_edit->changed_params->frame_rate); + sprintf(string, "%.4f", asset_edit->changed_params->frame_rate); //printf("AssetEditWindow::create_objects %d %f\n", __LINE__, asset_edit->changed_params->frame_rate); if(asset) diff --git a/cinelerra-5.1/cinelerra/audiodevice.C b/cinelerra-5.1/cinelerra/audiodevice.C index 82a9b8cf..a6aebcb4 100644 --- a/cinelerra-5.1/cinelerra/audiodevice.C +++ b/cinelerra-5.1/cinelerra/audiodevice.C @@ -151,6 +151,7 @@ AudioThread(AudioDevice *device, AudioThread::~AudioThread() { + stop(0); delete startup_lock; } diff --git a/cinelerra-5.1/cinelerra/automation.C b/cinelerra-5.1/cinelerra/automation.C index 298618af..1ce714fb 100644 --- a/cinelerra-5.1/cinelerra/automation.C +++ b/cinelerra-5.1/cinelerra/automation.C @@ -100,9 +100,6 @@ void Automation::create_objects() autos[AUTOMATION_MUTE]->create_objects(); autos[AUTOMATION_MUTE]->autoidx = AUTOMATION_MUTE; autos[AUTOMATION_MUTE]->autogrouptype = AUTOGROUPTYPE_INT255; - autos[AUTOMATION_SPEED] = new FloatAutos(edl, track, 1.0); - autos[AUTOMATION_SPEED]->create_objects(); - autos[AUTOMATION_SPEED]->autogrouptype = AUTOGROUPTYPE_SPEED; } Automation& Automation::operator=(Automation& automation) diff --git a/cinelerra-5.1/cinelerra/ffmpeg.C b/cinelerra-5.1/cinelerra/ffmpeg.C index e4949327..68a13158 100644 --- a/cinelerra-5.1/cinelerra/ffmpeg.C +++ b/cinelerra-5.1/cinelerra/ffmpeg.C @@ -362,6 +362,7 @@ int FFStream::decode(AVFrame *frame) if( ipkt->stream_index == st->index ) { while( (ipkt->size > 0 || !ipkt->data) && !got_frame ) { ret = decode_frame(ipkt, frame, got_frame); + if( ret < 0 ) need_packet = 1; if( ret <= 0 || !ipkt->data ) break; ipkt->data += ret; ipkt->size -= ret; @@ -732,6 +733,9 @@ int FFVideoStream::decode_frame(AVPacket *pkt, AVFrame *frame, int &got_frame) ff_err(ret, "FFVideoStream::decode_frame: Could not read video frame\n"); return -1; } + else // this is right out of ffplay, looks questionable ??? + ret = pkt->size; + if( got_frame ) { int64_t pkt_ts = av_frame_get_best_effort_timestamp(frame); if( pkt_ts != AV_NOPTS_VALUE ) @@ -1191,6 +1195,38 @@ int FFMPEG::scan_option_line(char *cp, char *tag, char *val) return 0; } +int FFMPEG::load_defaults(const char *path, const char *type, + char *codec, char *codec_options, int len) +{ + char default_file[BCTEXTLEN]; + FFMPEG::set_option_path(default_file, "%s/%s.dfl", path, type); + FILE *fp = fopen(default_file,"r"); + if( !fp ) return 1; + fgets(codec, BCSTRLEN, fp); + char *cp = codec; + while( *cp && *cp!='\n' ) ++cp; + *cp = 0; + while( len > 0 && fgets(codec_options, len, fp) ) { + int n = strlen(codec_options); + codec_options += n; len -= n; + } + fclose(fp); + FFMPEG::set_option_path(default_file, "%s/%s", path, codec); + return FFMPEG::load_options(default_file, codec_options, len); +} + +void FFMPEG::set_asset_format(Asset *asset, const char *text) +{ + if( asset->format != FILE_FFMPEG ) return; + strcpy(asset->fformat, text); + strcpy(asset->ff_audio_options, ""); + strcpy(asset->ff_video_options, ""); + asset->audio_data = !load_defaults("audio", text, asset->acodec, + asset->ff_audio_options, sizeof(asset->ff_audio_options)); + asset->video_data = !load_defaults("video", text, asset->vcodec, + asset->ff_video_options, sizeof(asset->ff_video_options)); +} + int FFMPEG::get_encoder(const char *options, char *format, char *codec, char *bsfilter, char *bsargs) { diff --git a/cinelerra-5.1/cinelerra/ffmpeg.h b/cinelerra-5.1/cinelerra/ffmpeg.h index d9ca7836..4860c002 100644 --- a/cinelerra-5.1/cinelerra/ffmpeg.h +++ b/cinelerra-5.1/cinelerra/ffmpeg.h @@ -263,6 +263,9 @@ public: static void get_option_path(char *path, const char *type, const char *spec); static int get_format(char *format, const char *path, char *spec); static int scan_option_line(char *cp,char *tag,char *val); + static int load_defaults(const char *path, const char *type, + char *codec, char *codec_options, int len); + static void set_asset_format(Asset *asset, const char *text); int get_file_format(); int get_encoder(const char *options, char *format, char *codec, char *bsfilter, char *bsargs); diff --git a/cinelerra-5.1/cinelerra/formattools.C b/cinelerra-5.1/cinelerra/formattools.C index a86fbfa2..37810a8e 100644 --- a/cinelerra-5.1/cinelerra/formattools.C +++ b/cinelerra-5.1/cinelerra/formattools.C @@ -213,10 +213,10 @@ void FormatTools::create_objects(int &init_x, format_button->create_objects(); x += format_button->get_w() + 5; window->add_subwindow(ffmpeg_type = new FFMpegType(x, y, 50, 1, asset->fformat)); + FFMPEG::set_asset_format(asset, asset->fformat); x += ffmpeg_type->get_w(); window->add_subwindow(format_ffmpeg = new FormatFFMPEG(x, y, this)); format_ffmpeg->create_objects(); - x = init_x; y += format_button->get_h() + 10; if(do_audio) @@ -845,40 +845,13 @@ FormatFFMPEG::~FormatFFMPEG() { } -int FormatFFMPEG::load_defaults(const char *path, const char *type, - char *codec, char *codec_options, int len) -{ - char default_file[BCTEXTLEN]; - FFMPEG::set_option_path(default_file, "%s/%s.dfl", path, type); - FILE *fp = fopen(default_file,"r"); - if( !fp ) return 1; - fgets(codec, BCSTRLEN, fp); - char *cp = codec; - while( *cp && *cp!='\n' ) ++cp; - *cp = 0; - while( len > 0 && fgets(codec_options, len, fp) ) { - int n = strlen(codec_options); - codec_options += n; len -= n; - } - fclose(fp); - FFMPEG::set_option_path(default_file, "%s/%s", path, codec); - return FFMPEG::load_options(default_file, codec_options, len); -} - int FormatFFMPEG::handle_event() { BC_ListBoxItem *selection = get_selection(0, 0); if( selection ) { char *text = get_selection(0, 0)->get_text(); format->ffmpeg_type->update(text); - Asset *asset = format->asset; - strcpy(asset->fformat, text); - strcpy(asset->ff_audio_options, ""); - strcpy(asset->ff_video_options, ""); - asset->audio_data = !load_defaults("audio", text, asset->acodec, - asset->ff_audio_options, sizeof(asset->ff_audio_options)); - asset->video_data = !load_defaults("video", text, asset->vcodec, - asset->ff_video_options, sizeof(asset->ff_video_options)); + FFMPEG::set_asset_format(format->asset, text); format->update_extension(); format->close_format_windows(); format->update_format(); diff --git a/cinelerra-5.1/cinelerra/formattools.h b/cinelerra-5.1/cinelerra/formattools.h index b5b56768..3929bbff 100644 --- a/cinelerra-5.1/cinelerra/formattools.h +++ b/cinelerra-5.1/cinelerra/formattools.h @@ -167,8 +167,6 @@ public: int handle_event(); FormatTools *format; - static int load_defaults(const char *path, const char *type, - char *codec, char *codec_options, int len); // squash show/hide window int show_window(int flush=1) { return 0; } diff --git a/cinelerra-5.1/cinelerra/mwindow.C b/cinelerra-5.1/cinelerra/mwindow.C index 18b9a239..adb7a87a 100644 --- a/cinelerra-5.1/cinelerra/mwindow.C +++ b/cinelerra-5.1/cinelerra/mwindow.C @@ -214,6 +214,8 @@ MWindow::MWindow() MWindow::~MWindow() { in_destructor = 1; + stop_playback(1); + stop_brender(); //printf("MWindow::~MWindow %d\n", __LINE__); gui->stop_drawing(); gui->remote_control->deactivate(); @@ -230,9 +232,9 @@ MWindow::~MWindow() // Save defaults for open plugins plugin_gui_lock->lock("MWindow::~MWindow"); - for(int i = 0; i < plugin_guis->size(); i++) - { + for(int i = 0; i < plugin_guis->size(); i++) { plugin_guis->get(i)->hide_gui(); + delete_plugin(plugin_guis->get(i)); } plugin_gui_lock->unlock(); hide_keyframe_guis(); @@ -277,10 +279,10 @@ MWindow::~MWindow() join(); #endif reset_caches(); - dead_plugins->remove_all(); + dead_plugins->remove_all_objects(); + delete_plugins(); finit_error(); keyframe_threads->remove_all_objects(); - if( !edl->Garbage::remove_user() ) edl = 0; colormodels.remove_all_objects(); delete gui; gui = 0; delete render; render = 0; @@ -303,12 +305,13 @@ MWindow::~MWindow() delete keyframe_threads; keyframe_threads = 0; delete undo; undo = 0; delete preferences; preferences = 0; + delete exportedl; exportedl = 0; delete session; session = 0; delete defaults; defaults = 0; delete assets; assets = 0; delete splash_window; splash_window = 0; - delete theme; theme = 0; - delete_plugins(); +// delete theme; theme = 0; // deleted by delete_plugins + if( !edl->Garbage::remove_user() ) edl = 0; delete channeldb_buz; delete channeldb_v4l2jpeg; // This must be last thread to exit @@ -318,6 +321,10 @@ MWindow::~MWindow() delete vwindows_lock; delete brender_lock; delete keyframe_gui_lock; + colormodels.remove_all_objects(); + interlace_project_modes.remove_all_objects(); + interlace_asset_modes.remove_all_objects(); + interlace_asset_fixmethods.remove_all_objects(); sighandler->terminate(); delete sighandler; } @@ -2361,12 +2368,8 @@ void MWindow::show_plugin(Plugin *plugin) SET_TRACE // Remove previously deleted plugin GUIs - dead_plugin_lock->lock("MWindow::delete_plugin"); - for(int i = 0; i < dead_plugins->size(); i++) - { - delete dead_plugins->get(i); - } - dead_plugins->remove_all(); + dead_plugin_lock->lock("MWindow::show_plugin"); + dead_plugins->remove_all_objects(); dead_plugin_lock->unlock(); //printf("MWindow::show_plugin %d\n", __LINE__); @@ -2399,7 +2402,8 @@ SET_TRACE //printf("MWindow::show_plugin %p %d\n", server, server->uses_gui); if(server && server->uses_gui) { - PluginServer *gui = plugin_guis->append(new PluginServer(*server)); + PluginServer *gui = new PluginServer(*server); + plugin_guis->append(gui); // Needs mwindow to do GUI gui->set_mwindow(this); gui->open_plugin(0, preferences, edl, plugin); diff --git a/cinelerra-5.1/cinelerra/mwindow.h b/cinelerra-5.1/cinelerra/mwindow.h index 0ac72d2a..00e9dea8 100644 --- a/cinelerra-5.1/cinelerra/mwindow.h +++ b/cinelerra-5.1/cinelerra/mwindow.h @@ -526,7 +526,6 @@ public: // Menu items ArrayList colormodels; - ArrayList interlace_asset_autofixoptions; ArrayList interlace_project_modes; ArrayList interlace_asset_modes; ArrayList interlace_asset_fixmethods; diff --git a/cinelerra-5.1/cinelerra/pluginclient.C b/cinelerra-5.1/cinelerra/pluginclient.C index 64c7d53f..c401ef22 100644 --- a/cinelerra-5.1/cinelerra/pluginclient.C +++ b/cinelerra-5.1/cinelerra/pluginclient.C @@ -56,9 +56,8 @@ PluginClientThread::PluginClientThread(PluginClient *client) PluginClientThread::~PluginClientThread() { //printf("PluginClientThread::~PluginClientThread %p %d\n", this, __LINE__); - delete window; + join(); //printf("PluginClientThread::~PluginClientThread %p %d\n", this, __LINE__); - window = 0; delete init_complete; } @@ -85,8 +84,7 @@ void PluginClientThread::run() //printf("PluginClientThread::run %p %d\n", this, __LINE__); window->hide_window(1); window->unlock_window(); - - + delete window; window = 0; // Can't save defaults in the destructor because it's not called immediately // after closing. /* if(client->defaults) */ client->save_defaults_xml(); @@ -144,35 +142,14 @@ PluginClientWindow::PluginClientWindow(PluginClient *client, : BC_Window(client->gui_string, client->window_x /* - w / 2 */, client->window_y /* - h / 2 */, - w, - h, - min_w, - min_h, - allow_resize, - 0, - 1) + w, h, min_w, min_h, allow_resize, 0, 1) { this->client = client; } PluginClientWindow::PluginClientWindow(const char *title, - int x, - int y, - int w, - int h, - int min_w, - int min_h, - int allow_resize) - : BC_Window(title, - x, - y, - w, - h, - min_w, - min_h, - allow_resize, - 0, - 1) + int x, int y, int w, int h, int min_w, int min_h, int allow_resize) + : BC_Window(title, x, y, w, h, min_w, min_h, allow_resize, 0, 1) { this->client = 0; } @@ -217,11 +194,7 @@ PluginClient::PluginClient(PluginServer *server) PluginClient::~PluginClient() { // Delete the GUI thread. The GUI must be hidden with hide_gui first. - if(thread) - { - thread->join(); - delete thread; - } + delete thread; // Virtual functions don't work here. if(defaults) delete defaults; @@ -384,7 +357,7 @@ int PluginClient::set_string() if(thread) { thread->window->lock_window("PluginClient::set_string"); - thread->window->set_title(gui_string); + thread->window->put_title(gui_string); thread->window->unlock_window(); } return 0; diff --git a/cinelerra-5.1/cinelerra/tracking.C b/cinelerra-5.1/cinelerra/tracking.C index 5a4ef42e..1ca59993 100644 --- a/cinelerra-5.1/cinelerra/tracking.C +++ b/cinelerra-5.1/cinelerra/tracking.C @@ -106,7 +106,6 @@ int Tracking::stop_playback() update_tracker(position); stop_meters(); - state = DONE; } return 0; } diff --git a/cinelerra-5.1/cinelerra/vmodule.C b/cinelerra-5.1/cinelerra/vmodule.C index fd9d557e..48f2643d 100644 --- a/cinelerra-5.1/cinelerra/vmodule.C +++ b/cinelerra-5.1/cinelerra/vmodule.C @@ -452,7 +452,8 @@ int VModule::import_frame(VFrame *output, // current_edit->asset->interlace_fixmethod); // Determine the interlacing method to use. - int interlace_fixmethod = ilaceautofixmethod2(get_edl()->session->interlace_mode, + int interlace_fixmethod = !current_edit->asset ? BC_ILACE_FIXMETHOD_NONE : + ilaceautofixmethod2(get_edl()->session->interlace_mode, current_edit->asset->interlace_autofixoption, current_edit->asset->interlace_mode, current_edit->asset->interlace_fixmethod); diff --git a/cinelerra-5.1/guicast/bcsignals.C b/cinelerra-5.1/guicast/bcsignals.C index e2a8b149..609ea1e2 100644 --- a/cinelerra-5.1/guicast/bcsignals.C +++ b/cinelerra-5.1/guicast/bcsignals.C @@ -22,6 +22,7 @@ #include "bcsignals.h" #include "bcwindowbase.h" #include "bckeyboard.h" +#include "bcresources.h" #include #include @@ -126,14 +127,14 @@ static bc_buffertrace_t* new_bc_buffertrace(int size, void *ptr, const char *loc return result; } -static void bc_copy_textfile(FILE *ofp, const char *fmt,...) +static void bc_copy_textfile(int lines, FILE *ofp, const char *fmt,...) { va_list ap; va_start(ap, fmt); char bfr[BCTEXTLEN]; vsnprintf(bfr, sizeof(bfr), fmt, ap); va_end(ap); FILE *ifp = fopen(bfr,"r"); if( !ifp ) return; - while( fgets(bfr,sizeof(bfr),ifp) ) fputs(bfr,ofp); + while( --lines >= 0 && fgets(bfr,sizeof(bfr),ifp) ) fputs(bfr,ofp); fclose(ifp); } @@ -855,6 +856,8 @@ static void handle_dump(int n, siginfo_t * info, void *sc) fprintf(fp," by %d:%d %s(%s)\n", pw->pw_uid, pw->pw_gid, pw->pw_name, pw->pw_gecos); } + fprintf(fp,"\nCPUS: %d\n", BC_Resources::get_machine_cpus()); + fprintf(fp,"\nCPUINFO:\n"); bc_copy_textfile(32, fp,"/proc/cpuinfo"); fprintf(fp,"\nTHREADS:\n"); Thread::dump_threads(fp); fprintf(fp,"\nTRACES:\n"); BC_Signals::dump_traces(fp); fprintf(fp,"\nLOCKS:\n"); BC_Signals::dump_locks(fp); @@ -863,9 +866,9 @@ static void handle_dump(int n, siginfo_t * info, void *sc) fprintf(fp,"\nMAIN HOOK:\n"); BC_Signals::trap_hook(fp, BC_Signals::trap_data); } - fprintf(fp,"\nVERSION:\n"); bc_copy_textfile(fp,"/proc/version"); - fprintf(fp,"\nMEMINFO:\n"); bc_copy_textfile(fp,"/proc/meminfo"); - fprintf(fp,"\nMAPS:\n"); bc_copy_textfile(fp,"/proc/%d/maps",pid); + fprintf(fp,"\nVERSION:\n"); bc_copy_textfile(INT_MAX, fp,"/proc/version"); + fprintf(fp,"\nMEMINFO:\n"); bc_copy_textfile(INT_MAX, fp,"/proc/meminfo"); + fprintf(fp,"\nMAPS:\n"); bc_copy_textfile(INT_MAX, fp,"/proc/%d/maps",pid); fprintf(fp,"\n\n"); if( fp != stdout ) fclose(fp); char cmd[1024], *cp = cmd; diff --git a/cinelerra-5.1/guicast/bcsynchronous.C b/cinelerra-5.1/guicast/bcsynchronous.C index 4459fa36..a8eccf23 100644 --- a/cinelerra-5.1/guicast/bcsynchronous.C +++ b/cinelerra-5.1/guicast/bcsynchronous.C @@ -460,6 +460,7 @@ void BC_Synchronous::delete_display_sync(BC_SynchronousCommand *command) Display *display = command->display; XLockDisplay(display); XUnlockDisplay(display); + glXMakeContextCurrent(display, None, None, 0); XCloseDisplay(display); #endif } diff --git a/cinelerra-5.1/guicast/bcwindowbase.C b/cinelerra-5.1/guicast/bcwindowbase.C index c61691f2..389670c3 100644 --- a/cinelerra-5.1/guicast/bcwindowbase.C +++ b/cinelerra-5.1/guicast/bcwindowbase.C @@ -186,7 +186,6 @@ BC_WindowBase::~BC_WindowBase() } #endif finit_im(); - flush(); sync_display(); diff --git a/cinelerra-5.1/guicast/condition.h b/cinelerra-5.1/guicast/condition.h index 8ab4fd87..1fd455e2 100644 --- a/cinelerra-5.1/guicast/condition.h +++ b/cinelerra-5.1/guicast/condition.h @@ -30,7 +30,6 @@ public: Condition(int init_value = 0, const char *title = 0, int is_binary = 0); ~Condition(); - // Reset to init_value whether locked or not. void reset(); // Block if value <= 0, then decrease value @@ -43,9 +42,9 @@ public: int timed_lock(int microseconds, const char *location = 0); int get_value(); - pthread_cond_t cond; - pthread_mutex_t mutex; - int value; + pthread_cond_t cond; + pthread_mutex_t mutex; + int value; int init_value; int is_binary; const char *title; diff --git a/cinelerra-5.1/guicast/thread.C b/cinelerra-5.1/guicast/thread.C index c3d068e0..3d817272 100644 --- a/cinelerra-5.1/guicast/thread.C +++ b/cinelerra-5.1/guicast/thread.C @@ -46,8 +46,8 @@ Mutex MLocker::the_lock; class the_dbg { public: - pthread_t tid; const char *name; - the_dbg(pthread_t t, const char *nm) { tid = t; name = nm; } + pthread_t tid, owner; const char *name; + the_dbg(pthread_t t, pthread_t o, const char *nm) { tid = t; owner = o; name = nm; } ~the_dbg() {} }; @@ -62,7 +62,7 @@ public: } } thread_list; -static void dbg_add(pthread_t tid, const char *nm) +static void dbg_add(pthread_t tid, pthread_t owner, const char *nm) { MLocker mlkr; int i = thread_list.size(); @@ -72,7 +72,7 @@ static void dbg_add(pthread_t tid, const char *nm) (unsigned long)tid, nm, thread_list[i]->name); return; } - thread_list.append(new the_dbg(tid, nm)); + thread_list.append(new the_dbg(tid, owner, nm)); } static void dbg_del(pthread_t tid) @@ -93,9 +93,10 @@ public: ~the_chkr() { int i = thread_list.size(); if( !i ) return; - printf("unjoined tids %d\n", i); - while( --i >= 0 ) printf(" %016lx %s\n", + printf("unjoined tids / owner %d\n", i); + while( --i >= 0 ) printf(" %016lx / %016lx %s\n", (unsigned long)thread_list[i]->tid, + (unsigned long)thread_list[i]->owner, thread_list[i]->name); } } the_chk; @@ -182,7 +183,7 @@ void Thread::start() pthread_create(&tid, &attr, Thread::entrypoint, this); - dbg_add(tid, typeid(*this).name()); + dbg_add(tid, owner, typeid(*this).name()); } int Thread::cancel() @@ -315,8 +316,8 @@ void Thread::dump_threads(FILE *fp) { int i = thread_list.size(); while( --i >= 0 ) { - fprintf(fp, "thread %016lx, %s\n", - (unsigned long)thread_list[i]->tid, + fprintf(fp, "thread %016lx, owner %016lx, %s\n", + (unsigned long)thread_list[i]->tid, (unsigned long)thread_list[i]->owner, thread_list[i]->name); } }