lldb::ValueObjectSP lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex (size_t idx) { lldb::addr_t m_keys_ptr = (m_data_32 ? m_data_32->_keys_addr : m_data_64->_keys_addr); lldb::addr_t m_values_ptr = (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr); uint32_t num_children = CalculateNumChildren(); if (idx >= num_children) return lldb::ValueObjectSP(); if (m_children.empty()) { // do the scan phase lldb::addr_t key_at_idx = 0, val_at_idx = 0; uint32_t tries = 0; uint32_t test_idx = 0; while(tries < num_children) { key_at_idx = m_keys_ptr + (test_idx * m_ptr_size); val_at_idx = m_values_ptr + (test_idx * m_ptr_size);; ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP(); if (!process_sp) return lldb::ValueObjectSP(); Error error; key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error); if (error.Fail()) return lldb::ValueObjectSP(); val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error); if (error.Fail()) return lldb::ValueObjectSP(); test_idx++; if (!key_at_idx || !val_at_idx) continue; tries++; DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()}; m_children.push_back(descriptor); } } if (idx >= m_children.size()) // should never happen return lldb::ValueObjectSP(); DictionaryItemDescriptor &dict_item = m_children[idx]; if (!dict_item.valobj_sp) { if (!m_pair_type.IsValid()) { TargetSP target_sp(m_backend.GetTargetSP()); if (!target_sp) return ValueObjectSP(); m_pair_type = GetLLDBNSPairType(target_sp); } if (!m_pair_type.IsValid()) return ValueObjectSP(); DataBufferSP buffer_sp(new DataBufferHeap(2*m_ptr_size,0)); if (m_ptr_size == 8) { uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes(); *data_ptr = dict_item.key_ptr; *(data_ptr+1) = dict_item.val_ptr; } else { uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes(); *data_ptr = dict_item.key_ptr; *(data_ptr+1) = dict_item.val_ptr; } StreamString idx_name; idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); DataExtractor data(buffer_sp, m_order, m_ptr_size); dict_item.valobj_sp = ValueObject::CreateValueObjectFromData(idx_name.GetData(), data, m_exe_ctx_ref, m_pair_type); } return dict_item.valobj_sp; }
Error::Error( const Error &src ) : runtime_error( src.what() ) { ++src.data->usageCount; data = src.data; }
void CFlyCap2MFCDoc::OnFileSaveAs() { Error error; CString csMessage; JPEGOption JPEG_Save_Option; PNGOption PNG_Save_Option; m_beingSaved = true; // Define the list of filters to include in the SaveAs dialog. const unsigned int uiNumFilters = 8; const CString arcsFilter[uiNumFilters] = { "Windows Bitmap (*.bmp)|*.bmp" , "Portable Pixelmap (*.ppm)|*.ppm" , "Portable Greymap (raw image) (*.pgm)|*.pgm" , "Independent JPEG Group (*.jpg, *.jpeg)|*.jpg; *.jpeg" , "Tagged Image File Format (*.tiff)|*.tiff" , "Portable Network Graphics (*.png)|*.png" , "Raw data (*.raw)|*.raw" , "All Files (*.*)|*.*" }; CString csFilters; // Keep track of which filter should be selected as default. // m_uiFilterIndex is set to what was previously used (0 if this is first time). for ( int i = 0; i < (uiNumFilters - 1); i++ ) { csFilters += arcsFilter[(m_uiFilterIndex + i) % (uiNumFilters - 1)]; csFilters += "|"; } // Always finish with All Files and a ||. csFilters += arcsFilter[uiNumFilters - 1]; csFilters += "||"; time_t rawtime; struct tm * timeinfo; time( &rawtime ); timeinfo = localtime( &rawtime ); char timestamp[64]; strftime( timestamp, 64, "%Y-%m-%d-%H%M%S", timeinfo ); char tempFilename[128]; sprintf( tempFilename, "%u-%s", m_cameraInfo.serialNumber, timestamp ); CFileDialog fileDialog( FALSE, "bmp", tempFilename, OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT, csFilters, AfxGetMainWnd() ); if( fileDialog.DoModal() == IDOK ) { CString csExt = fileDialog.GetFileExt(); // Save the filter index for the next time if( csExt.CompareNoCase("bmp") == 0 ) { m_uiFilterIndex = 0; } else if( csExt.CompareNoCase("ppm") == 0 ) { m_uiFilterIndex = 1; } else if( csExt.CompareNoCase("pgm") == 0 ) { m_uiFilterIndex = 2; } else if( csExt.CompareNoCase("jpeg") == 0 || csExt.CompareNoCase("jpg") == 0 ) { m_uiFilterIndex = 3; JPEG_Save_Option.progressive = false; JPEG_Save_Option.quality = 100; //Superb quality. } else if( csExt.CompareNoCase("tiff") == 0 ) { m_uiFilterIndex = 4; } else if( csExt.CompareNoCase("png") == 0 ) { m_uiFilterIndex = 5; PNG_Save_Option.interlaced = false; PNG_Save_Option.compressionLevel = 9; //Best compression } else if( csExt.CompareNoCase("raw") == 0 ) { m_uiFilterIndex = 6; } else { AfxMessageBox( "Invalid file type" ); } switch ( m_uiFilterIndex ) { case 0: case 1: case 2: case 4: case 6: error = m_saveImage.Save( fileDialog.GetPathName(), FROM_FILE_EXT); break; case 3: // Save image with options error = m_saveImage.Save( fileDialog.GetPathName(), &JPEG_Save_Option); break; case 5: // Save image with options error = m_saveImage.Save( fileDialog.GetPathName(), &PNG_Save_Option); break; } if( error != PGRERROR_OK ) { CString csMessage; csMessage.Format( "Save image failure: %s", error.GetDescription() ); AfxMessageBox( csMessage, MB_ICONSTOP ); } } m_beingSaved = false; }
void LogError(const char *msg, const Error &error) { LogFormat("%s: %s", msg, error.GetMessage()); }
size_t MemoryCache::Read (addr_t addr, void *dst, size_t dst_len, Error &error) { size_t bytes_left = dst_len; // If this memory read request is larger than the cache line size, then // we (1) try to read as much of it at once as possible, and (2) don't // add the data to the memory cache. We don't want to split a big read // up into more separate reads than necessary, and with a large memory read // request, it is unlikely that the caller function will ask for the next // 4 bytes after the large memory read - so there's little benefit to saving // it in the cache. if (dst && dst_len > m_cache_line_byte_size) { return m_process.ReadMemoryFromInferior (addr, dst, dst_len, error); } if (dst && bytes_left > 0) { const uint32_t cache_line_byte_size = m_cache_line_byte_size; uint8_t *dst_buf = (uint8_t *)dst; addr_t curr_addr = addr - (addr % cache_line_byte_size); addr_t cache_offset = addr - curr_addr; Mutex::Locker locker (m_mutex); while (bytes_left > 0) { if (m_invalid_ranges.FindEntryThatContains(curr_addr)) { error.SetErrorStringWithFormat("memory read failed for 0x%" PRIx64, curr_addr); return dst_len - bytes_left; } BlockMap::const_iterator pos = m_cache.find (curr_addr); BlockMap::const_iterator end = m_cache.end (); if (pos != end) { size_t curr_read_size = cache_line_byte_size - cache_offset; if (curr_read_size > bytes_left) curr_read_size = bytes_left; memcpy (dst_buf + dst_len - bytes_left, pos->second->GetBytes() + cache_offset, curr_read_size); bytes_left -= curr_read_size; curr_addr += curr_read_size + cache_offset; cache_offset = 0; if (bytes_left > 0) { // Get sequential cache page hits for (++pos; (pos != end) && (bytes_left > 0); ++pos) { assert ((curr_addr % cache_line_byte_size) == 0); if (pos->first != curr_addr) break; curr_read_size = pos->second->GetByteSize(); if (curr_read_size > bytes_left) curr_read_size = bytes_left; memcpy (dst_buf + dst_len - bytes_left, pos->second->GetBytes(), curr_read_size); bytes_left -= curr_read_size; curr_addr += curr_read_size; // We have a cache page that succeeded to read some bytes // but not an entire page. If this happens, we must cap // off how much data we are able to read... if (pos->second->GetByteSize() != cache_line_byte_size) return dst_len - bytes_left; } } } // We need to read from the process if (bytes_left > 0) { assert ((curr_addr % cache_line_byte_size) == 0); std::unique_ptr<DataBufferHeap> data_buffer_heap_ap(new DataBufferHeap (cache_line_byte_size, 0)); size_t process_bytes_read = m_process.ReadMemoryFromInferior (curr_addr, data_buffer_heap_ap->GetBytes(), data_buffer_heap_ap->GetByteSize(), error); if (process_bytes_read == 0) return dst_len - bytes_left; if (process_bytes_read != cache_line_byte_size) data_buffer_heap_ap->SetByteSize (process_bytes_read); m_cache[curr_addr] = DataBufferSP (data_buffer_heap_ap.release()); // We have read data and put it into the cache, continue through the // loop again to get the data out of the cache... } } } return dst_len - bytes_left; }
Error Host::RunShellCommand(const Args &args, const FileSpec &working_dir, int *status_ptr, int *signo_ptr, std::string *command_output_ptr, uint32_t timeout_sec, bool run_in_default_shell) { Error error; ProcessLaunchInfo launch_info; launch_info.SetArchitecture(HostInfo::GetArchitecture()); if (run_in_default_shell) { // Run the command in a shell launch_info.SetShell(HostInfo::GetDefaultShell()); launch_info.GetArguments().AppendArguments(args); const bool localhost = true; const bool will_debug = false; const bool first_arg_is_full_shell_command = false; launch_info.ConvertArgumentsForLaunchingInShell( error, localhost, will_debug, first_arg_is_full_shell_command, 0); } else { // No shell, just run it const bool first_arg_is_executable = true; launch_info.SetArguments(args, first_arg_is_executable); } if (working_dir) launch_info.SetWorkingDirectory(working_dir); llvm::SmallString<PATH_MAX> output_file_path; if (command_output_ptr) { // Create a temporary file to get the stdout/stderr and redirect the // output of the command into this file. We will later read this file // if all goes well and fill the data into "command_output_ptr" FileSpec tmpdir_file_spec; if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) { tmpdir_file_spec.AppendPathComponent("lldb-shell-output.%%%%%%"); llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath().c_str(), output_file_path); } else { llvm::sys::fs::createTemporaryFile("lldb-shell-output.%%%%%%", "", output_file_path); } } FileSpec output_file_spec{output_file_path.c_str(), false}; launch_info.AppendSuppressFileAction(STDIN_FILENO, true, false); if (output_file_spec) { launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_spec, false, true); launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO); } else { launch_info.AppendSuppressFileAction(STDOUT_FILENO, false, true); launch_info.AppendSuppressFileAction(STDERR_FILENO, false, true); } std::shared_ptr<ShellInfo> shell_info_sp(new ShellInfo()); const bool monitor_signals = false; launch_info.SetMonitorProcessCallback( std::bind(MonitorShellCommand, shell_info_sp, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4), monitor_signals); error = LaunchProcess(launch_info); const lldb::pid_t pid = launch_info.GetProcessID(); if (error.Success() && pid == LLDB_INVALID_PROCESS_ID) error.SetErrorString("failed to get process ID"); if (error.Success()) { bool timed_out = false; shell_info_sp->process_reaped.WaitForValueEqualTo( true, std::chrono::seconds(timeout_sec), &timed_out); if (timed_out) { error.SetErrorString("timed out waiting for shell command to complete"); // Kill the process since it didn't complete within the timeout specified Kill(pid, SIGKILL); // Wait for the monitor callback to get the message timed_out = false; shell_info_sp->process_reaped.WaitForValueEqualTo( true, std::chrono::seconds(1), &timed_out); } else { if (status_ptr) *status_ptr = shell_info_sp->status; if (signo_ptr) *signo_ptr = shell_info_sp->signo; if (command_output_ptr) { command_output_ptr->clear(); uint64_t file_size = output_file_spec.GetByteSize(); if (file_size > 0) { if (file_size > command_output_ptr->max_size()) { error.SetErrorStringWithFormat( "shell command output is too large to fit into a std::string"); } else { std::vector<char> command_output(file_size); output_file_spec.ReadFileContents(0, command_output.data(), file_size, &error); if (error.Success()) command_output_ptr->assign(command_output.data(), file_size); } } } } } if (FileSystem::GetFileExists(output_file_spec)) FileSystem::Unlink(output_file_spec); return error; }
bool Host::AddPosixSpawnFileAction(void *_file_actions, const FileAction *info, Log *log, Error &error) { if (info == NULL) return false; posix_spawn_file_actions_t *file_actions = reinterpret_cast<posix_spawn_file_actions_t *>(_file_actions); switch (info->GetAction()) { case FileAction::eFileActionNone: error.Clear(); break; case FileAction::eFileActionClose: if (info->GetFD() == -1) error.SetErrorString( "invalid fd for posix_spawn_file_actions_addclose(...)"); else { error.SetError( ::posix_spawn_file_actions_addclose(file_actions, info->GetFD()), eErrorTypePOSIX); if (log && (error.Fail() || log)) error.PutToLog(log, "posix_spawn_file_actions_addclose (action=%p, fd=%i)", static_cast<void *>(file_actions), info->GetFD()); } break; case FileAction::eFileActionDuplicate: if (info->GetFD() == -1) error.SetErrorString( "invalid fd for posix_spawn_file_actions_adddup2(...)"); else if (info->GetActionArgument() == -1) error.SetErrorString( "invalid duplicate fd for posix_spawn_file_actions_adddup2(...)"); else { error.SetError( ::posix_spawn_file_actions_adddup2(file_actions, info->GetFD(), info->GetActionArgument()), eErrorTypePOSIX); if (log && (error.Fail() || log)) error.PutToLog( log, "posix_spawn_file_actions_adddup2 (action=%p, fd=%i, dup_fd=%i)", static_cast<void *>(file_actions), info->GetFD(), info->GetActionArgument()); } break; case FileAction::eFileActionOpen: if (info->GetFD() == -1) error.SetErrorString( "invalid fd in posix_spawn_file_actions_addopen(...)"); else { int oflag = info->GetActionArgument(); mode_t mode = 0; if (oflag & O_CREAT) mode = 0640; error.SetError(::posix_spawn_file_actions_addopen( file_actions, info->GetFD(), info->GetPath().str().c_str(), oflag, mode), eErrorTypePOSIX); if (error.Fail() || log) error.PutToLog(log, "posix_spawn_file_actions_addopen (action=%p, " "fd=%i, path='%s', oflag=%i, mode=%i)", static_cast<void *>(file_actions), info->GetFD(), info->GetPath().str().c_str(), oflag, mode); } break; } return error.Success(); }
bool lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { static ConstString g_TypeHint("CFBag"); ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); if (!runtime) return false; ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj)); if (!descriptor.get() || !descriptor->IsValid()) return false; uint32_t ptr_size = process_sp->GetAddressByteSize(); lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); if (!valobj_addr) return false; uint32_t count = 0; bool is_type_ok = false; // check to see if this is a CFBag we know about if (descriptor->IsCFType()) { ConstString type_name(valobj.GetTypeName()); if (type_name == ConstString("__CFBag") || type_name == ConstString("const struct __CFBag")) { if (valobj.IsPointerType()) is_type_ok = true; } } if (is_type_ok == false) { StackFrameSP frame_sp(valobj.GetFrameSP()); if (!frame_sp) return false; ValueObjectSP count_sp; StreamString expr; expr.Printf("(int)CFBagGetCount((void*)0x%" PRIx64 ")",valobj.GetPointerValue()); EvaluateExpressionOptions options; options.SetResultIsInternal(true); if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), count_sp, options) != eExpressionCompleted) return false; if (!count_sp) return false; count = count_sp->GetValueAsUnsigned(0); } else { uint32_t offset = 2*ptr_size+4 + valobj_addr; Error error; count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error); if (error.Fail()) return false; } std::string prefix,suffix; if (Language* language = Language::FindPlugin(options.GetLanguage())) { if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix)) { prefix.clear(); suffix.clear(); } } stream.Printf("%s\"%u value%s\"%s", prefix.c_str(), count,(count == 1 ? "" : "s"), suffix.c_str()); return true; }
Error NativeRegisterContextLinux_s390x::WriteRegister(const RegisterInfo *reg_info, const RegisterValue ®_value) { if (!reg_info) return Error("reg_info NULL"); const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; if (reg == LLDB_INVALID_REGNUM) return Error("register \"%s\" is an internal-only lldb register, cannot write directly", reg_info->name); if (IsGPR(reg)) { s390_regs regs; Error error = DoReadGPR(®s, sizeof(regs)); if (error.Fail()) return error; uint8_t *dst = (uint8_t *)®s + reg_info->byte_offset; assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(regs)); switch (reg_info->byte_size) { case 4: *(uint32_t *)dst = reg_value.GetAsUInt32(); break; case 8: *(uint64_t *)dst = reg_value.GetAsUInt64(); break; default: assert(false && "Unhandled data size."); return Error("unhandled byte size: %" PRIu32, reg_info->byte_size); } return DoWriteGPR(®s, sizeof(regs)); } if (IsFPR(reg)) { s390_fp_regs fp_regs; Error error = DoReadFPR(&fp_regs, sizeof(fp_regs)); if (error.Fail()) return error; // byte_offset is just the offset within fp_regs, not the whole user area. uint8_t *dst = (uint8_t *)&fp_regs + reg_info->byte_offset; assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(fp_regs)); switch (reg_info->byte_size) { case 4: *(uint32_t *)dst = reg_value.GetAsUInt32(); break; case 8: *(uint64_t *)dst = reg_value.GetAsUInt64(); break; default: assert(false && "Unhandled data size."); return Error("unhandled byte size: %" PRIu32, reg_info->byte_size); } return DoWriteFPR(&fp_regs, sizeof(fp_regs)); } if (reg == lldb_last_break_s390x) { return Error("The last break address is read-only"); } if (reg == lldb_system_call_s390x) { uint32_t system_call = reg_value.GetAsUInt32(); return DoWriteRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4); } return Error("failed - register wasn't recognized"); }
bool Silf::readGraphite(const byte * const silf_start, size_t lSilf, Face& face, uint32 version) { const byte * p = silf_start, * const silf_end = p + lSilf; Error e; if (e.test(version >= 0x00060000, E_BADSILFVERSION)) { releaseBuffers(); return face.error(e); } if (version >= 0x00030000) { if (e.test(lSilf < 28, E_BADSIZE)) { releaseBuffers(); return face.error(e); } be::skip<int32>(p); // ruleVersion be::skip<uint16>(p,2); // passOffset & pseudosOffset } else if (e.test(lSilf < 20, E_BADSIZE)) { releaseBuffers(); return face.error(e); } const uint16 maxGlyph = be::read<uint16>(p); m_silfinfo.extra_ascent = be::read<uint16>(p); m_silfinfo.extra_descent = be::read<uint16>(p); m_numPasses = be::read<uint8>(p); m_sPass = be::read<uint8>(p); m_pPass = be::read<uint8>(p); m_jPass = be::read<uint8>(p); m_bPass = be::read<uint8>(p); m_flags = be::read<uint8>(p); be::skip<uint8>(p,2); // max{Pre,Post}Context. m_aPseudo = be::read<uint8>(p); m_aBreak = be::read<uint8>(p); m_aBidi = be::read<uint8>(p); m_aMirror = be::read<uint8>(p); m_aPassBits = be::read<uint8>(p); // Read Justification levels. m_numJusts = be::read<uint8>(p); if (e.test(maxGlyph >= face.glyphs().numGlyphs(), E_BADMAXGLYPH) || e.test(p + m_numJusts * 8 >= silf_end, E_BADNUMJUSTS)) { releaseBuffers(); return face.error(e); } if (m_numJusts) { m_justs = gralloc<Justinfo>(m_numJusts); if (e.test(!m_justs, E_OUTOFMEM)) return face.error(e); for (uint8 i = 0; i < m_numJusts; i++) { ::new(m_justs + i) Justinfo(p[0], p[1], p[2], p[3]); be::skip<byte>(p,8); } } if (e.test(p + sizeof(uint16) + sizeof(uint8)*8 >= silf_end, E_BADENDJUSTS)) { releaseBuffers(); return face.error(e); } m_aLig = be::read<uint16>(p); m_aUser = be::read<uint8>(p); m_iMaxComp = be::read<uint8>(p); m_dir = be::read<uint8>(p) - 1; m_aCollision = be::read<uint8>(p); be::skip<byte>(p,3); be::skip<uint16>(p, be::read<uint8>(p)); // don't need critical features yet be::skip<byte>(p); // reserved if (e.test(p >= silf_end, E_BADCRITFEATURES)) { releaseBuffers(); return face.error(e); } be::skip<uint32>(p, be::read<uint8>(p)); // don't use scriptTag array. if (e.test(p + sizeof(uint16) + sizeof(uint32) >= silf_end, E_BADSCRIPTTAGS)) { releaseBuffers(); return face.error(e); } m_gEndLine = be::read<uint16>(p); // lbGID const byte * o_passes = p, * const passes_start = silf_start + be::read<uint32>(p); const size_t num_attrs = face.glyphs().numAttrs(); if (e.test(m_aPseudo >= num_attrs, E_BADAPSEUDO) || e.test(m_aBreak >= num_attrs, E_BADABREAK) || e.test(m_aBidi >= num_attrs, E_BADABIDI) || e.test(m_aMirror>= num_attrs, E_BADAMIRROR) || e.test(m_aCollision && m_aCollision >= num_attrs - 5, E_BADACOLLISION) || e.test(m_numPasses > 128, E_BADNUMPASSES) || e.test(passes_start >= silf_end, E_BADPASSESSTART) || e.test(m_pPass < m_sPass, E_BADPASSBOUND) || e.test(m_pPass > m_numPasses, E_BADPPASS) || e.test(m_sPass > m_numPasses, E_BADSPASS) || e.test(m_jPass < m_pPass, E_BADJPASSBOUND) || e.test(m_jPass > m_numPasses, E_BADJPASS) || e.test((m_bPass != 0xFF && (m_bPass < m_jPass || m_bPass > m_numPasses)), E_BADBPASS) || e.test(m_aLig > 127, E_BADALIG)) { releaseBuffers(); return face.error(e); } be::skip<uint32>(p, m_numPasses); if (e.test(p + sizeof(uint16) >= passes_start, E_BADPASSESSTART)) { releaseBuffers(); return face.error(e); } m_numPseudo = be::read<uint16>(p); be::skip<uint16>(p, 3); // searchPseudo, pseudoSelector, pseudoShift m_pseudos = new Pseudo[m_numPseudo]; if (e.test(p + m_numPseudo*(sizeof(uint32) + sizeof(uint16)) >= passes_start, E_BADNUMPSEUDO) || e.test(!m_pseudos, E_OUTOFMEM)) { releaseBuffers(); return face.error(e); } for (int i = 0; i < m_numPseudo; i++) { m_pseudos[i].uid = be::read<uint32>(p); m_pseudos[i].gid = be::read<uint16>(p); } const size_t clen = readClassMap(p, passes_start - p, version, e); m_passes = new Pass[m_numPasses]; if (e || e.test(p + clen > passes_start, E_BADPASSESSTART) || e.test(!m_passes, E_OUTOFMEM)) { releaseBuffers(); return face.error(e); } for (size_t i = 0; i < m_numPasses; ++i) { const byte * const pass_start = silf_start + be::read<uint32>(o_passes), * const pass_end = silf_start + be::peek<uint32>(o_passes); face.error_context((face.error_context() & 0xFF00) + EC_ASILF + (i << 16)); if (e.test(pass_start > pass_end, E_BADPASSSTART) || e.test(pass_start < passes_start, E_BADPASSSTART) || e.test(pass_end > silf_end, E_BADPASSEND)) { releaseBuffers(); return face.error(e); } enum passtype pt = PASS_TYPE_UNKNOWN; if (i >= m_jPass) pt = PASS_TYPE_JUSTIFICATION; else if (i >= m_pPass) pt = PASS_TYPE_POSITIONING; else if (i >= m_sPass) pt = PASS_TYPE_SUBSTITUTE; else pt = PASS_TYPE_LINEBREAK; m_passes[i].init(this); if (!m_passes[i].readPass(pass_start, pass_end - pass_start, pass_start - silf_start, face, pt, version, e)) { releaseBuffers(); return false; } } // fill in gr_faceinfo m_silfinfo.upem = face.glyphs().unitsPerEm(); m_silfinfo.has_bidi_pass = (m_bPass != 0xFF); m_silfinfo.justifies = (m_numJusts != 0) || (m_jPass < m_pPass); m_silfinfo.line_ends = (m_flags & 1); m_silfinfo.space_contextuals = gr_faceinfo::gr_space_contextuals((m_flags >> 2) & 0x7); return true; }
bool lldb_private::formatters::CFBitVectorSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); if (!runtime) return false; ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj)); if (!descriptor.get() || !descriptor->IsValid()) return false; uint32_t ptr_size = process_sp->GetAddressByteSize(); lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); if (!valobj_addr) return false; uint32_t count = 0; bool is_type_ok = false; // check to see if this is a CFBag we know about if (descriptor->IsCFType()) { ConstString type_name(valobj.GetTypeName()); if (type_name == ConstString("__CFMutableBitVector") || type_name == ConstString("__CFBitVector") || type_name == ConstString("CFMutableBitVectorRef") || type_name == ConstString("CFBitVectorRef")) { if (valobj.IsPointerType()) is_type_ok = true; } } if (is_type_ok == false) return false; Error error; count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, ptr_size, 0, error); if (error.Fail()) return false; uint64_t num_bytes = count / 8 + ((count & 7) ? 1 : 0); addr_t data_ptr = process_sp->ReadPointerFromMemory(valobj_addr+2*ptr_size+2*ptr_size, error); if (error.Fail()) return false; // make sure we do not try to read huge amounts of data if (num_bytes > 1024) num_bytes = 1024; DataBufferSP buffer_sp(new DataBufferHeap(num_bytes,0)); num_bytes = process_sp->ReadMemory(data_ptr, buffer_sp->GetBytes(), num_bytes, error); if (error.Fail() || num_bytes == 0) return false; uint8_t *bytes = buffer_sp->GetBytes(); for (uint64_t byte_idx = 0; byte_idx < num_bytes-1; byte_idx++) { uint8_t byte = bytes[byte_idx]; bool bit0 = (byte & 1) == 1; bool bit1 = (byte & 2) == 2; bool bit2 = (byte & 4) == 4; bool bit3 = (byte & 8) == 8; bool bit4 = (byte & 16) == 16; bool bit5 = (byte & 32) == 32; bool bit6 = (byte & 64) == 64; bool bit7 = (byte & 128) == 128; stream.Printf("%c%c%c%c %c%c%c%c ", (bit7 ? '1' : '0'), (bit6 ? '1' : '0'), (bit5 ? '1' : '0'), (bit4 ? '1' : '0'), (bit3 ? '1' : '0'), (bit2 ? '1' : '0'), (bit1 ? '1' : '0'), (bit0 ? '1' : '0')); count -= 8; } { // print the last byte ensuring we do not print spurious bits uint8_t byte = bytes[num_bytes-1]; bool bit0 = (byte & 1) == 1; bool bit1 = (byte & 2) == 2; bool bit2 = (byte & 4) == 4; bool bit3 = (byte & 8) == 8; bool bit4 = (byte & 16) == 16; bool bit5 = (byte & 32) == 32; bool bit6 = (byte & 64) == 64; bool bit7 = (byte & 128) == 128; if (count) { stream.Printf("%c",bit7 ? '1' : '0'); count -= 1; } if (count) { stream.Printf("%c",bit6 ? '1' : '0'); count -= 1; } if (count) { stream.Printf("%c",bit5 ? '1' : '0'); count -= 1; } if (count) { stream.Printf("%c",bit4 ? '1' : '0'); count -= 1; } if (count) { stream.Printf("%c",bit3 ? '1' : '0'); count -= 1; } if (count) { stream.Printf("%c",bit2 ? '1' : '0'); count -= 1; } if (count) { stream.Printf("%c",bit1 ? '1' : '0'); count -= 1; } if (count) stream.Printf("%c",bit0 ? '1' : '0'); } return true; }
// For local debugging, Linux will override the debug logic to use llgs-launch rather than // lldb-launch, llgs-attach. This differs from current lldb-launch, debugserver-attach // approach on MacOSX. lldb::ProcessSP PlatformLinux::DebugProcess (ProcessLaunchInfo &launch_info, Debugger &debugger, Target *target, // Can be NULL, if NULL create a new target, else use existing one Error &error) { Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); if (log) log->Printf ("PlatformLinux::%s entered (target %p)", __FUNCTION__, static_cast<void*>(target)); // If we're a remote host, use standard behavior from parent class. if (!IsHost ()) return PlatformPOSIX::DebugProcess (launch_info, debugger, target, error); // // For local debugging, we'll insist on having ProcessGDBRemote create the process. // ProcessSP process_sp; // Make sure we stop at the entry point launch_info.GetFlags ().Set (eLaunchFlagDebug); // We always launch the process we are going to debug in a separate process // group, since then we can handle ^C interrupts ourselves w/o having to worry // about the target getting them as well. launch_info.SetLaunchInSeparateProcessGroup(true); // Ensure we have a target. if (target == nullptr) { if (log) log->Printf ("PlatformLinux::%s creating new target", __FUNCTION__); TargetSP new_target_sp; error = debugger.GetTargetList().CreateTarget (debugger, nullptr, nullptr, false, nullptr, new_target_sp); if (error.Fail ()) { if (log) log->Printf ("PlatformLinux::%s failed to create new target: %s", __FUNCTION__, error.AsCString ()); return process_sp; } target = new_target_sp.get(); if (!target) { error.SetErrorString ("CreateTarget() returned nullptr"); if (log) log->Printf ("PlatformLinux::%s failed: %s", __FUNCTION__, error.AsCString ()); return process_sp; } } else { if (log) log->Printf ("PlatformLinux::%s using provided target", __FUNCTION__); } // Mark target as currently selected target. debugger.GetTargetList().SetSelectedTarget(target); // Now create the gdb-remote process. if (log) log->Printf ("PlatformLinux::%s having target create process with gdb-remote plugin", __FUNCTION__); process_sp = target->CreateProcess (launch_info.GetListenerForProcess(debugger), "gdb-remote", nullptr); if (!process_sp) { error.SetErrorString ("CreateProcess() failed for gdb-remote process"); if (log) log->Printf ("PlatformLinux::%s failed: %s", __FUNCTION__, error.AsCString ()); return process_sp; } else { if (log) log->Printf ("PlatformLinux::%s successfully created process", __FUNCTION__); } // Adjust launch for a hijacker. ListenerSP listener_sp; if (!launch_info.GetHijackListener ()) { if (log) log->Printf ("PlatformLinux::%s setting up hijacker", __FUNCTION__); listener_sp = Listener::MakeListener("lldb.PlatformLinux.DebugProcess.hijack"); launch_info.SetHijackListener (listener_sp); process_sp->HijackProcessEvents (listener_sp); } // Log file actions. if (log) { log->Printf ("PlatformLinux::%s launching process with the following file actions:", __FUNCTION__); StreamString stream; size_t i = 0; const FileAction *file_action; while ((file_action = launch_info.GetFileActionAtIndex (i++)) != nullptr) { file_action->Dump (stream); log->PutCString (stream.GetString().c_str ()); stream.Clear(); } } // Do the launch. error = process_sp->Launch(launch_info); if (error.Success ()) { // Handle the hijacking of process events. if (listener_sp) { const StateType state = process_sp->WaitForProcessToStop (NULL, NULL, false, listener_sp); if (state == eStateStopped) { if (log) log->Printf ("PlatformLinux::%s pid %" PRIu64 " state %s\n", __FUNCTION__, process_sp->GetID (), StateAsCString (state)); } else { if (log) log->Printf ("PlatformLinux::%s pid %" PRIu64 " state is not stopped - %s\n", __FUNCTION__, process_sp->GetID (), StateAsCString (state)); } } // Hook up process PTY if we have one (which we should for local debugging with llgs). int pty_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor(); if (pty_fd != lldb_utility::PseudoTerminal::invalid_fd) { process_sp->SetSTDIOFileDescriptor(pty_fd); if (log) log->Printf ("PlatformLinux::%s pid %" PRIu64 " hooked up STDIO pty to process", __FUNCTION__, process_sp->GetID ()); } else { if (log) log->Printf ("PlatformLinux::%s pid %" PRIu64 " not using process STDIO pty", __FUNCTION__, process_sp->GetID ()); } } else { if (log) log->Printf ("PlatformLinux::%s process launch failed: %s", __FUNCTION__, error.AsCString ()); // FIXME figure out appropriate cleanup here. Do we delete the target? Do we delete the process? Does our caller do that? } return process_sp; }
Error PlatformLinux::ResolveExecutable (const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp, const FileSpecList *module_search_paths_ptr) { Error error; // Nothing special to do here, just use the actual file and architecture char exe_path[PATH_MAX]; ModuleSpec resolved_module_spec (ms); if (IsHost()) { // If we have "ls" as the exe_file, resolve the executable location based on // the current path variables if (!resolved_module_spec.GetFileSpec().Exists()) { resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path)); resolved_module_spec.GetFileSpec().SetFile(exe_path, true); } if (!resolved_module_spec.GetFileSpec().Exists()) resolved_module_spec.GetFileSpec().ResolveExecutableLocation (); if (resolved_module_spec.GetFileSpec().Exists()) error.Clear(); else { error.SetErrorStringWithFormat("unable to find executable for '%s'", resolved_module_spec.GetFileSpec().GetPath().c_str()); } } else { if (m_remote_platform_sp) { error = GetCachedExecutable (resolved_module_spec, exe_module_sp, module_search_paths_ptr, *m_remote_platform_sp); } else { // We may connect to a process and use the provided executable (Don't use local $PATH). if (resolved_module_spec.GetFileSpec().Exists()) error.Clear(); else error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", exe_path); } } if (error.Success()) { if (resolved_module_spec.GetArchitecture().IsValid()) { error = ModuleList::GetSharedModule (resolved_module_spec, exe_module_sp, NULL, NULL, NULL); if (error.Fail()) { // If we failed, it may be because the vendor and os aren't known. If that is the // case, try setting them to the host architecture and give it another try. llvm::Triple &module_triple = resolved_module_spec.GetArchitecture().GetTriple(); bool is_vendor_specified = (module_triple.getVendor() != llvm::Triple::UnknownVendor); bool is_os_specified = (module_triple.getOS() != llvm::Triple::UnknownOS); if (!is_vendor_specified || !is_os_specified) { const llvm::Triple &host_triple = HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple(); if (!is_vendor_specified) module_triple.setVendorName (host_triple.getVendorName()); if (!is_os_specified) module_triple.setOSName (host_triple.getOSName()); error = ModuleList::GetSharedModule (resolved_module_spec, exe_module_sp, NULL, NULL, NULL); } } // TODO find out why exe_module_sp might be NULL if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL) { exe_module_sp.reset(); error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s", resolved_module_spec.GetFileSpec().GetPath().c_str(), resolved_module_spec.GetArchitecture().GetArchitectureName()); } } else { // No valid architecture was specified, ask the platform for // the architectures that we should be using (in the correct order) // and see if we can find a match that way StreamString arch_names; for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx) { error = ModuleList::GetSharedModule (resolved_module_spec, exe_module_sp, NULL, NULL, NULL); // Did we find an executable using one of the if (error.Success()) { if (exe_module_sp && exe_module_sp->GetObjectFile()) break; else error.SetErrorToGenericError(); } if (idx > 0) arch_names.PutCString (", "); arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName()); } if (error.Fail() || !exe_module_sp) { if (resolved_module_spec.GetFileSpec().Readable()) { error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", resolved_module_spec.GetFileSpec().GetPath().c_str(), GetPluginName().GetCString(), arch_names.GetString().c_str()); } else { error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str()); } } } } return error; }
void TurkAnalyzer::onFrame() { // Called once every game frame // Display the game frame rate as text in the upper left area of the screen Broodwar->drawTextScreen(200, 0, "FPS: %d", Broodwar->getFPS()); // Broodwar->drawTextScreen(200, 20, "Average FPS: %f", Broodwar->getAverageFPS() ); //Broodwar->drawTextScreen(200, 20, "Number of Units: %d", BWAPI::Broodwar->self()->supplyUsed() / 2 ); //Broodwar->drawTextScreen(200, 40, "Number of Units: %d", BWAPI::Broodwar->self()->supplyTotal() / 2 ); // Return if the game is a replay or is paused if (Broodwar->isReplay() || Broodwar->isPaused() || !Broodwar->self()) return; //BWTA draw if (analyzed){ drawTerrainData(); } if (analysis_just_finished) { Broodwar << "Finished analyzing map." << std::endl;; analysis_just_finished = false; } // Prevent spamming by only running our onFrame once every number of latency frames. // Latency frames are the number of frames before commands are processed. if (Broodwar->getFrameCount() % Broodwar->getLatencyFrames() != 0) return; // Iterate through all the units that we own // Count the number of probes ProbeCount = 0; ZealotCount = 0; DragoonCount = 0; GateWayCount = 0; for (auto & unit2 : Broodwar->self()->getUnits()) { if (!unit2->exists()) continue; // Ignore the unit if it is incomplete or busy constructing if (!unit2->isCompleted() || unit2->isConstructing()) continue; // If the unit is a worker unit if (unit2->getType().isWorker()) { ProbeCount = ProbeCount + 1; } else if (unit2->getType() == BWAPI::UnitTypes::Protoss_Zealot) { ZealotCount = ZealotCount + 1; } else if (unit2->getType() == BWAPI::UnitTypes::Protoss_Dragoon) { DragoonCount = DragoonCount + 1; } else if (unit2->getType() == GateWay) { GateWayCount = GateWayCount + 1; } } Broodwar->drawTextScreen(100, 10, "Number of Zealot: %d", ZealotCount); Broodwar->drawTextScreen(100, 30, "Number of Dragoon: %d", DragoonCount); // Iterate through all the units that we own for (auto &u : Broodwar->self()->getUnits()) { // Ignore the unit if it no longer exists // Make sure to include this block when handling any Unit pointer! if (!u->exists()) continue; // Ignore the unit if it has one of the following status ailments if (u->isLockedDown() || u->isMaelstrommed() || u->isStasised()) continue; // Ignore the unit if it is in one of the following states if (u->isLoaded() || !u->isPowered() || u->isStuck()) continue; // Ignore the unit if it is incomplete or busy constructing if (!u->isCompleted() || u->isConstructing()) continue; // Finally make the unit do some stuff! // Build a gateway or generate a zealot if (u->getType().isBuilding()) { // We found a gateway, and it is not generating a unit if (u->isIdle() && u->getType() == GateWay) { u->rightClick(Enterance); //BWAPI::Position Hill = BWTA::getNearestChokepoint(BWAPI::Position(Broodwar->self()->getStartLocation()))->getCenter(); //u->rightClick(Hill); if (FirstCybernetics && ZealotCount >= DragoonCount){ u->train(BWAPI::UnitTypes::Protoss_Dragoon); } else{ u->train(BWAPI::UnitTypes::Protoss_Zealot); } } // We found a gateway, and it is generating a unit. else if (!u->isIdle() && u->getType() == GateWay && GateWayCount < MaxGateWayCount && FirstCybernetics) { static int lastChecked = 0; // If we are supply blocked and haven't tried constructing more recently if (lastChecked + 400 < Broodwar->getFrameCount() && Broodwar->self()->incompleteUnitCount(GateWay) == 0) { // Frame Count lastChecked = Broodwar->getFrameCount(); // Retrieve a unit that is capable of constructing the supply needed Unit GateBuilder = u->getClosestUnit(GetType == GateWay.whatBuilds().first && (IsIdle || IsGatheringMinerals) && IsOwned); // If a unit was found if (GateBuilder) { TilePosition targetBuildLocation = Broodwar->getBuildLocation(GateWay, GateBuilder->getTilePosition()); if (targetBuildLocation) { // Order the builder to construct the supply structure GateBuilder->build(GateWay, targetBuildLocation); } } } } } /* if (Broodwar->self()) { Unitset myUnits = Broodwar->self()->getUnits(); for (auto u : myUnits) { if (u->isIdle() && u->getType().isResourceDepot()) u->train(u->getType().getRace().getWorker()); } } */ // If the unit is a worker unit if (u->getType().isWorker()) { // if our worker is idle if (u->isIdle()) { // Order workers carrying a resource to return them to the center, // otherwise find a mineral patch to harvest. if (u->isCarryingGas() || u->isCarryingMinerals()) { u->returnCargo(); } else if (!u->getPowerUp()) // The worker cannot harvest anything if it { // is carrying a powerup such as a flag // Harvest from the nearest mineral patch or gas refinery if (!u->gather(u->getClosestUnit(IsMineralField))) // IsRefinery { // If the call fails, then print the last error message Broodwar << Broodwar->getLastError() << std::endl; } } // closure: has no powerup } // closure: if idle } else if (u->getType().isResourceDepot()) // A resource depot is a Command Center, Nexus, or Hatchery { // Order the depot to construct more workers! But only when it is idle. if (u->isIdle() && ProbeCount < 40) // && !u->train(u->getType().getRace().getWorker()) { u->train(u->getType().getRace().getWorker()); // If that fails, draw the error at the location so that you can visibly see what went wrong! // However, drawing the error once will only appear for a single frame // so create an event that keeps it on the screen for some frames // Position homePosition = Position(Broodwar->self()->getStartLocation()); } Position pos = u->getPosition(); Error lastErr = Broodwar->getLastError(); Broodwar->registerEvent([pos, lastErr](Game*){ Broodwar->drawTextMap(pos, "%c%s", Text::White, lastErr.c_str()); }, // action nullptr, // condition Broodwar->getLatencyFrames()); // frames to run // Retrieve the supply provider type in the case that we have run out of supplies UnitType supplyProviderType = u->getType().getRace().getSupplyProvider(); static int lastChecked = 0; // If we are supply blocked and haven't tried constructing more recently if (lastErr == Errors::Insufficient_Supply && lastChecked + 300 < Broodwar->getFrameCount() && Broodwar->self()->incompleteUnitCount(supplyProviderType) <= PylonLimiter) { lastChecked = Broodwar->getFrameCount(); // Retrieve a unit that is capable of constructing the supply needed Unit supplyBuilder = u->getClosestUnit(GetType == supplyProviderType.whatBuilds().first && (IsIdle || IsGatheringMinerals) && IsOwned); // If a unit was found if (supplyBuilder) { if (supplyProviderType.isBuilding()) { TilePosition targetBuildLocation = Broodwar->getBuildLocation(supplyProviderType, supplyBuilder->getTilePosition()); if (targetBuildLocation) { // Register an event that draws the target build location Broodwar->registerEvent([targetBuildLocation, supplyProviderType](Game*) { Broodwar->drawBoxMap(Position(targetBuildLocation), Position(targetBuildLocation + supplyProviderType.tileSize()), Colors::Blue); }, nullptr, // condition supplyProviderType.buildTime() + 100); // frames to run // Order the builder to construct the supply structure supplyBuilder->build(supplyProviderType, targetBuildLocation); } } else { // Train the supply provider (Overlord) if the provider is not a structure supplyBuilder->train(supplyProviderType); } } // closure: supplyBuilder is valid } // closure: insufficient supply // If there is the first pylon,but it there is no gateway, please build a gateway.s else if (FirstPylonExist && !FirstGateExist) { static int lastChecked = 0; // If we are supply blocked and haven't tried constructing more recently if (lastChecked + 400 < Broodwar->getFrameCount() && Broodwar->self()->incompleteUnitCount(GateWay) == 0) { // Frame Count lastChecked = Broodwar->getFrameCount(); // Retrieve a unit that is capable of constructing the supply needed Unit GateBuilder = u->getClosestUnit(GetType == GateWay.whatBuilds().first && (IsIdle || IsGatheringMinerals) && IsOwned); if (GateBuilder) { TilePosition targetBuildLocation = Broodwar->getBuildLocation(GateWay, GateBuilder->getTilePosition()); if (targetBuildLocation) { // Order the builder to construct the supply structure GateBuilder->build(GateWay, targetBuildLocation); } } } } else if (FirstGateExist && !FirstGasExist) { BWAPI::TilePosition closestGeyser = BWAPI::TilePositions::None; double minGeyserDistanceFromHome = (std::numeric_limits<double>::max)(); BWAPI::Position homePosition = BWAPI::Position(Broodwar->self()->getStartLocation()); // for each geyser for (auto & geyser : Broodwar->getStaticGeysers()) { if (geyser->getType() != BWAPI::UnitTypes::Resource_Vespene_Geyser) { continue; } BWAPI::Position geyserPos = geyser->getInitialPosition(); BWAPI::TilePosition geyserTilePos = geyser->getInitialTilePosition(); // check to see if it's next to one of our depots bool nearDepot = false; for (auto & unit : BWAPI::Broodwar->self()->getUnits()) { if (unit->getType().isResourceDepot() && unit->getDistance(geyserPos) < 300) { nearDepot = true; } } if (nearDepot) { double homeDistance = geyser->getDistance(homePosition); if (homeDistance < minGeyserDistanceFromHome) { minGeyserDistanceFromHome = homeDistance; closestGeyser = geyser->getInitialTilePosition(); } } static int lastChecked = 0; // If we are supply blocked and haven't tried constructing more recently if (lastChecked + 400 < Broodwar->getFrameCount() && Broodwar->self()->incompleteUnitCount(Assimilator) == 0) { // Frame Count lastChecked = Broodwar->getFrameCount(); // Retrieve a unit that is capable of constructing the supply needed Unit GasBuilder = u->getClosestUnit(GetType == GateWay.whatBuilds().first && (IsIdle || IsGatheringMinerals) && IsOwned); if (GasBuilder) { // Order the builder to construct the supply structure GasBuilder->build(Assimilator, closestGeyser); } } } } } } // closure: unit iterator // Build the supply unit if (BWAPI::Broodwar->self()->supplyUsed() / 2 + 6 > BWAPI::Broodwar->self()->supplyTotal() / 2){ for (auto & unit2 : Broodwar->self()->getUnits()){ if (!unit2->exists()) continue; // Ignore the unit if it is incomplete or busy constructing if (!unit2->isCompleted() || unit2->isConstructing()) continue; // If the unit is a worker unit if (unit2->getType().isResourceDepot()){ UnitType supplyProviderType = unit2->getType().getRace().getSupplyProvider(); static int lastChecked = 0; // If we are supply blocked and haven't tried constructing more recently if (lastChecked + 300 < Broodwar->getFrameCount() && Broodwar->self()->incompleteUnitCount(supplyProviderType) == 0){ lastChecked = Broodwar->getFrameCount(); // Retrieve a unit that is capable of constructing the supply needed Unit supplyBuilder = unit2->getClosestUnit(GetType == supplyProviderType.whatBuilds().first && (IsIdle || IsGatheringMinerals) && IsOwned); // If a unit was found if (supplyBuilder){ TilePosition targetBuildLocation = Broodwar->getBuildLocation(supplyProviderType, supplyBuilder->getTilePosition()); if (targetBuildLocation){ // Order the builder to construct the supply structure supplyBuilder->build(supplyProviderType, targetBuildLocation); } } } } } } // Build the Cybernetics Core if (FirstGasExist && !FirstCybernetics) { for (auto & unit2 : Broodwar->self()->getUnits()) { // If the unit is a worker unit if (unit2->getType().isWorker()) { static int lastChecked = 0; // If we are supply blocked and haven't tried constructing more recently if (lastChecked + 400 < Broodwar->getFrameCount() && Broodwar->self()->incompleteUnitCount(Cybernetics) == 0) { // Frame Count lastChecked = Broodwar->getFrameCount(); // Retrieve a unit that is capable of constructing the supply needed Unit GateBuilder = unit2->getClosestUnit(GetType == Cybernetics.whatBuilds().first && (IsIdle || IsGatheringMinerals) && IsOwned); if (GateBuilder) { TilePosition targetBuildLocation = Broodwar->getBuildLocation(Cybernetics, GateBuilder->getTilePosition()); if (targetBuildLocation) { // Order the builder to construct the supply structure GateBuilder->build(Cybernetics, targetBuildLocation); } } } } } } if (FirstCybernetics && !Singularity){ for (auto & unit : BWAPI::Broodwar->self()->getUnits()) { if (unit->getType() == Cybernetics && !unit->isUpgrading()) { unit->upgrade(BWAPI::UpgradeTypes::Singularity_Charge); } } } // Send workers to the gas refinary if (FirstGasExist && GasWorkerCount == 0) { // for each unit we have for (auto & unit : BWAPI::Broodwar->self()->getUnits()) { // if that unit is a refinery if (unit->getType().isRefinery() && unit->isCompleted()) { for (auto & unit2 : Broodwar->self()->getUnits()) { if (GasWorkerCount == 3) { break; } // If the unit is a worker unit if (unit2->getType().isWorker()) { GasWorkerCount = GasWorkerCount + 1; unit2->rightClick(unit); } } } } } // Build the Adun if (FirstCybernetics && !FirstAdun && GateWayCount >= 4) { for (auto & unit2 : Broodwar->self()->getUnits()) { // If the unit is a worker unit if (unit2->getType().isWorker()) { static int lastChecked = 0; // If we are supply blocked and haven't tried constructing more recently if (lastChecked + 400 < Broodwar->getFrameCount() && Broodwar->self()->incompleteUnitCount(CitadelOfAdun) == 0) { // Frame Count lastChecked = Broodwar->getFrameCount(); // Retrieve a unit that is capable of constructing the supply needed Unit GateBuilder = unit2->getClosestUnit(GetType == CitadelOfAdun.whatBuilds().first && (IsIdle || IsGatheringMinerals) && IsOwned); if (GateBuilder) { TilePosition targetBuildLocation = Broodwar->getBuildLocation(CitadelOfAdun, GateBuilder->getTilePosition()); if (targetBuildLocation) { // Order the builder to construct the supply structure GateBuilder->build(CitadelOfAdun, targetBuildLocation); } } } } } } // Leg Enhancements if (FirstAdun && !Leg_Enhancements){ for (auto & unit : BWAPI::Broodwar->self()->getUnits()) { if (unit->getType() == CitadelOfAdun && !unit->isUpgrading()) { unit->upgrade(BWAPI::UpgradeTypes::Leg_Enhancements); } } } BWAPI::Position homePosition = BWAPI::Position(Broodwar->self()->getStartLocation()); // Build the expansion nexus if (GateWayCount >= MaxGateWayCount) { for (auto & unit2 : Broodwar->self()->getUnits()) { // If the unit is a worker unit if (unit2->getType().isWorker()) { static int lastChecked = 0; // If we are supply blocked and haven't tried constructing more recently if (lastChecked + 400 < Broodwar->getFrameCount() && Broodwar->self()->incompleteUnitCount(Nexus) == 0) { // Frame Count lastChecked = Broodwar->getFrameCount(); // Retrieve a unit that is capable of constructing the supply needed Unit GateBuilder = unit2->getClosestUnit(GetType == Nexus.whatBuilds().first && (IsIdle || IsGatheringMinerals) && IsOwned); if (GateBuilder) { double minDistance = 100000; BWAPI::TilePosition homeTile = Broodwar->self()->getStartLocation(); if (NexusLocation){ // Order the builder to construct the supply structure GateBuilder->build(Nexus, NexusLocation); } } } } } } // If the number of Nexus is greater or equal to 2, increase the number of gates. int NofNexus = 0; for (auto & unit2 : Broodwar->self()->getUnits()) { if (unit2->getType().isBuilding() && unit2->getType() == Nexus) { NofNexus = NofNexus + 1; } if (NofNexus >= 2){ MaxGateWayCount = 8; break; } } }
core::ProgramStatus Options::read(int argc, char * const argv[]) { using namespace boost::program_options ; // get the shared secret monitorSharedSecret_ = core::system::getenv(kMonitorSharedSecretEnvVar); core::system::unsetenv(kMonitorSharedSecretEnvVar); // compute the resource path FilePath resourcePath; Error error = core::system::installPath("..", argv[0], &resourcePath); if (error) { LOG_ERROR_MESSAGE("Unable to determine install path: "+error.summary()); return ProgramStatus::exitFailure(); } // detect running in OSX bundle and tweak resource path #ifdef __APPLE__ if (resourcePath.complete("Info.plist").exists()) resourcePath = resourcePath.complete("Resources"); #endif // detect running in x64 directory and tweak resource path #ifdef _WIN32 if (resourcePath.complete("x64").exists()) resourcePath = resourcePath.parent(); #endif // verify installation flag options_description verify("verify"); verify.add_options() (kVerifyInstallationSessionOption, value<bool>(&verifyInstallation_)->default_value(false), "verify the current installation"); // program - name and execution options_description program("program"); program.add_options() (kProgramModeSessionOption, value<std::string>(&programMode_)->default_value("server"), "program mode (desktop or server"); // agreement options_description agreement("agreement"); agreement.add_options() ("agreement-file", value<std::string>(&agreementFilePath_)->default_value(""), "agreement file"); // docs url options_description docs("docs"); docs.add_options() ("docs-url", value<std::string>(&docsURL_)->default_value(""), "custom docs url"); // www options options_description www("www") ; www.add_options() ("www-local-path", value<std::string>(&wwwLocalPath_)->default_value("www"), "www local path") ("www-symbol-maps-path", value<std::string>(&wwwSymbolMapsPath_)->default_value( "www-symbolmaps"), "www symbol maps path") ("www-port", value<std::string>(&wwwPort_)->default_value("8787"), "port to listen on"); // session options std::string saveActionDefault; options_description session("session") ; session.add_options() (kTimeoutSessionOption, value<int>(&timeoutMinutes_)->default_value(120), "session timeout (minutes)" ) (kDisconnectedTimeoutSessionOption, value<int>(&disconnectedTimeoutMinutes_)->default_value(0), "session disconnected timeout (minutes)" ) ("session-preflight-script", value<std::string>(&preflightScript_)->default_value(""), "session preflight script") ("session-create-public-folder", value<bool>(&createPublicFolder_)->default_value(false), "automatically create public folder") ("session-rprofile-on-resume-default", value<bool>(&rProfileOnResumeDefault_)->default_value(false), "default user setting for running Rprofile on resume") ("session-save-action-default", value<std::string>(&saveActionDefault)->default_value(""), "default save action (yes, no, or ask)"); // allow options options_description allow("allow"); allow.add_options() ("allow-vcs-executable-edit", value<bool>(&allowVcsExecutableEdit_)->default_value(true), "allow editing of vcs executables") ("allow-r-cran-repos-edit", value<bool>(&allowCRANReposEdit_)->default_value(true), "Allow editing of CRAN repository") ("allow-vcs", value<bool>(&allowVcs_)->default_value(true), "allow use of version control features") ("allow-package-installation", value<bool>(&allowPackageInstallation_)->default_value(true), "allow installation of packages from the packages pane") ("allow-shell", value<bool>(&allowShell_)->default_value(true), "allow access to shell dialog") ("allow-file-downloads", value<bool>(&allowFileDownloads_)->default_value(true), "allow file downloads from the files pane") ("allow-remove-public-folder", value<bool>(&allowRemovePublicFolder_)->default_value(true), "allow removal of the user public folder") ("allow-rpubs-publish", value<bool>(&allowRpubsPublish_)->default_value(true), "allow publishing to rpubs"); // r options bool rShellEscape; // no longer works but don't want to break any // config files which formerly used it // TODO: eliminate this option entirely options_description r("r") ; r.add_options() ("r-core-source", value<std::string>(&coreRSourcePath_)->default_value("R"), "Core R source path") ("r-modules-source", value<std::string>(&modulesRSourcePath_)->default_value("R/modules"), "Modules R source path") ("r-session-library", value<std::string>(&sessionLibraryPath_)->default_value("R/library"), "R library path") ("r-session-packages", value<std::string>(&sessionPackagesPath_)->default_value("R/packages"), "R packages path") ("r-session-package-archives", value<std::string>(&sessionPackageArchivesPath_)->default_value("R/packages"), "R package archives path") ("r-libs-user", value<std::string>(&rLibsUser_)->default_value(""), "R user library path") ("r-cran-repos", value<std::string>(&rCRANRepos_)->default_value(""), "Default CRAN repository") ("r-auto-reload-source", value<bool>(&autoReloadSource_)->default_value(false), "Reload R source if it changes during the session") ("r-compatible-graphics-engine-version", value<int>(&rCompatibleGraphicsEngineVersion_)->default_value(10), "Maximum graphics engine version we are compatible with") ("r-resources-path", value<std::string>(&rResourcesPath_)->default_value("resources"), "Directory containing external resources") ("r-shell-escape", value<bool>(&rShellEscape)->default_value(false), "Support shell escape (deprecated, no longer works)") ("r-home-dir-override", value<std::string>(&rHomeDirOverride_)->default_value(""), "Override for R_HOME (used for debug configurations)") ("r-doc-dir-override", value<std::string>(&rDocDirOverride_)->default_value(""), "Override for R_DOC_DIR (used for debug configurations)"); // limits options options_description limits("limits"); limits.add_options() ("limit-file-upload-size-mb", value<int>(&limitFileUploadSizeMb_)->default_value(0), "limit of file upload size") ("limit-cpu-time-minutes", value<int>(&limitCpuTimeMinutes_)->default_value(0), "limit on time of top level computations") ("limit-xfs-disk-quota", value<bool>(&limitXfsDiskQuota_)->default_value(false), "limit xfs disk quota"); // external options options_description external("external"); external.add_options() ("external-rpostback-path", value<std::string>(&rpostbackPath_)->default_value(kDefaultPostbackPath), "Path to rpostback executable") ("external-consoleio-path", value<std::string>(&consoleIoPath_)->default_value("bin/consoleio.exe"), "Path to consoleio executable") ("external-gnudiff-path", value<std::string>(&gnudiffPath_)->default_value("bin/gnudiff"), "Path to gnudiff utilities (windows-only)") ("external-gnugrep-path", value<std::string>(&gnugrepPath_)->default_value("bin/gnugrep"), "Path to gnugrep utilities (windows-only)") ("external-msysssh-path", value<std::string>(&msysSshPath_)->default_value("bin/msys_ssh"), "Path to msys_ssh utilities (windows-only)") ("external-sumatra-path", value<std::string>(&sumatraPath_)->default_value("bin/sumatra"), "Path to SumatraPDF (windows-only)") ("external-hunspell-dictionaries-path", value<std::string>(&hunspellDictionariesPath_)->default_value("resources/dictionaries"), "Path to hunspell dictionaries") ("external-mathjax-path", value<std::string>(&mathjaxPath_)->default_value("resources/mathjax"), "Path to mathjax library") ("external-pandoc-path", value<std::string>(&pandocPath_)->default_value(kDefaultPandocPath), "Path to pandoc binaries"); // user options (default user identity to current username) std::string currentUsername = core::system::username(); options_description user("user") ; user.add_options() (kUserIdentitySessionOption "," kUserIdentitySessionOptionShort, value<std::string>(&userIdentity_)->default_value(currentUsername), "user identity" ) (kShowUserIdentitySessionOption, value<bool>(&showUserIdentity_)->default_value(true), "show the user identity"); // overlay options options_description overlay("overlay"); addOverlayOptions(&overlay); // define program options FilePath defaultConfigPath("/etc/rstudio/rsession.conf"); std::string configFile = defaultConfigPath.exists() ? defaultConfigPath.absolutePath() : ""; core::program_options::OptionsDescription optionsDesc("rsession", configFile); optionsDesc.commandLine.add(verify); optionsDesc.commandLine.add(program); optionsDesc.commandLine.add(agreement); optionsDesc.commandLine.add(docs); optionsDesc.commandLine.add(www); optionsDesc.commandLine.add(session); optionsDesc.commandLine.add(allow); optionsDesc.commandLine.add(r); optionsDesc.commandLine.add(limits); optionsDesc.commandLine.add(external); optionsDesc.commandLine.add(user); // define groups included in config-file processing optionsDesc.configFile.add(program); optionsDesc.configFile.add(agreement); optionsDesc.configFile.add(docs); optionsDesc.configFile.add(www); optionsDesc.configFile.add(session); optionsDesc.configFile.add(allow); optionsDesc.configFile.add(r); optionsDesc.configFile.add(limits); optionsDesc.configFile.add(external); optionsDesc.configFile.add(user); optionsDesc.configFile.add(overlay); // read configuration ProgramStatus status = core::program_options::read(optionsDesc, argc,argv); if (status.exit()) return status; // make sure the program mode is valid if (programMode_ != kSessionProgramModeDesktop && programMode_ != kSessionProgramModeServer) { LOG_ERROR_MESSAGE("invalid program mode: " + programMode_); return ProgramStatus::exitFailure(); } // call overlay hooks resolveOverlayOptions(); std::string errMsg; if (!validateOverlayOptions(&errMsg)) { program_options::reportError(errMsg, ERROR_LOCATION); return ProgramStatus::exitFailure(); } // compute program identity programIdentity_ = "rsession-" + userIdentity_; // provide special home path in temp directory if we are verifying if (verifyInstallation_) { // we create a special home directory in server mode (since the // user we are running under might not have a home directory) if (programMode_ == kSessionProgramModeServer) { verifyInstallationHomeDir_ = "/tmp/rstudio-verify-installation"; Error error = FilePath(verifyInstallationHomeDir_).ensureDirectory(); if (error) { LOG_ERROR(error); return ProgramStatus::exitFailure(); } core::system::setenv("R_USER", verifyInstallationHomeDir_); } } // compute user paths r_util::SessionType sessionType = (programMode_ == kSessionProgramModeDesktop) ? r_util::SessionTypeDesktop : r_util::SessionTypeServer; r_util::UserDirectories userDirs = r_util::userDirectories(sessionType); userHomePath_ = userDirs.homePath; userScratchPath_ = userDirs.scratchPath; // session timeout seconds is always -1 in desktop mode if (programMode_ == kSessionProgramModeDesktop) timeoutMinutes_ = 0; // convert string save action default to intenger if (saveActionDefault == "yes") saveActionDefault_ = r::session::kSaveActionSave; else if (saveActionDefault == "no") saveActionDefault_ = r::session::kSaveActionNoSave; else if (saveActionDefault == "ask" || saveActionDefault.empty()) saveActionDefault_ = r::session::kSaveActionAsk; else { program_options::reportWarnings( "Invalid value '" + saveActionDefault + "' for " "session-save-action-default. Valid values are yes, no, and ask.", ERROR_LOCATION); saveActionDefault_ = r::session::kSaveActionAsk; } // convert relative paths by completing from the app resource path resolvePath(resourcePath, &rResourcesPath_); resolvePath(resourcePath, &agreementFilePath_); resolvePath(resourcePath, &wwwLocalPath_); resolvePath(resourcePath, &wwwSymbolMapsPath_); resolvePath(resourcePath, &coreRSourcePath_); resolvePath(resourcePath, &modulesRSourcePath_); resolvePath(resourcePath, &sessionLibraryPath_); resolvePath(resourcePath, &sessionPackagesPath_); resolvePath(resourcePath, &sessionPackageArchivesPath_); resolvePostbackPath(resourcePath, &rpostbackPath_); #ifdef _WIN32 resolvePath(resourcePath, &consoleIoPath_); resolvePath(resourcePath, &gnudiffPath_); resolvePath(resourcePath, &gnugrepPath_); resolvePath(resourcePath, &msysSshPath_); resolvePath(resourcePath, &sumatraPath_); #endif resolvePath(resourcePath, &hunspellDictionariesPath_); resolvePath(resourcePath, &mathjaxPath_); resolvePandocPath(resourcePath, &pandocPath_); // shared secret with parent secret_ = core::system::getenv("RS_SHARED_SECRET"); /* SECURITY: Need RS_SHARED_SECRET to be available to rpostback. However, we really ought to communicate it in a more secure manner than this, at least on Windows where even within the same user session some processes can have different priviliges (integrity levels) than others. For example, using a named pipe with proper SACL to retrieve the shared secret, where the name of the pipe is in an environment variable. */ //core::system::unsetenv("RS_SHARED_SECRET"); // initial working dir override initialWorkingDirOverride_ = core::system::getenv(kRStudioInitialWorkingDir); core::system::unsetenv(kRStudioInitialWorkingDir); // initial environment file override initialEnvironmentFileOverride_ = core::system::getenv(kRStudioInitialEnvironment); core::system::unsetenv(kRStudioInitialEnvironment); // initial project initialProjectPath_ = core::system::getenv(kRStudioInitialProject); core::system::unsetenv(kRStudioInitialProject); // limit rpc client uid limitRpcClientUid_ = -1; std::string limitUid = core::system::getenv(kRStudioLimitRpcClientUid); if (!limitUid.empty()) { limitRpcClientUid_ = core::safe_convert::stringTo<int>(limitUid, -1); core::system::unsetenv(kRStudioLimitRpcClientUid); } // return status return status; }
bool MoveCartridge( int slotIDSrc, int slotIDDst, Cartridge & cartridge, Error & error) { if ( slotIDSrc == slotIDDst ) { return true; } if ( fs::exists( "/tmp/.bdt.move_error") ) { error.SetError( Error::ERROR_NO_ENTRY, "Force error for debug" ); return false; } string barcode; if ( ! cartridge.GetBarcode(barcode,error) ) { return false; } Factory * factory = Factory::Instance(); SlotImpl * slotSrc = factory->GetSlot(changer,slotIDSrc); if ( NULL == slotSrc ) { error.SetError( Error::ERROR_NO_ENTRY, string("No such slot(drive) ") + boost::lexical_cast<string>(slotIDSrc) + " in changer " + boost::lexical_cast<string>(changer) ); return false; } SlotImpl * slotDst = factory->GetSlot(changer,slotIDDst); if ( NULL == slotDst ) { error.SetError( Error::ERROR_NO_ENTRY, string("No such slot(drive) ") + boost::lexical_cast<string>(slotIDDst) + " in changer " + boost::lexical_cast<string>(changer) ); return false; } CartridgeImpl * cartridgeImpl = factory->GetCartridge(barcode); if ( NULL == slotDst ) { error.SetError( Error::ERROR_NO_ENTRY, string("No such cartridge ") + barcode + " in changer " + boost::lexical_cast<string>(changer) ); return false; } if ( ! slotDst->Empty() ) { error.SetError( Error::ERROR_ENTRY_FULL, string("Slot(Drive) ") + boost::lexical_cast<string>(slotIDDst) + " is full in changer " + boost::lexical_cast<string>(changer) ); return false; } //boost::this_thread::sleep(boost::posix_time::seconds(1)); slotDst->SetEmpty(false); slotDst->SetBarcode(barcode); slotSrc->SetEmpty(true); cartridgeImpl->SetSlotID(slotIDDst); return true; }
bool BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error) { Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS); Mutex::Locker evaluation_locker(m_condition_mutex); size_t condition_hash; const char *condition_text = GetConditionText(&condition_hash); if (!condition_text) { m_user_expression_sp.reset(); return false; } if (condition_hash != m_condition_hash || !m_user_expression_sp || !m_user_expression_sp->MatchesContext(exe_ctx)) { m_user_expression_sp.reset(new ClangUserExpression(condition_text, NULL, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny)); StreamString errors; if (!m_user_expression_sp->Parse(errors, exe_ctx, eExecutionPolicyOnlyWhenNeeded, true)) { error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s", errors.GetData()); m_user_expression_sp.reset(); return false; } m_condition_hash = condition_hash; } // We need to make sure the user sees any parse errors in their condition, so we'll hook the // constructor errors up to the debugger's Async I/O. ValueObjectSP result_value_sp; EvaluateExpressionOptions options; options.SetUnwindOnError(true); options.SetIgnoreBreakpoints(true); options.SetRunOthers(true); Error expr_error; StreamString execution_errors; ClangExpressionVariableSP result_variable_sp; ExecutionResults result_code = m_user_expression_sp->Execute(execution_errors, exe_ctx, options, m_user_expression_sp, result_variable_sp); bool ret; if (result_code == eExecutionCompleted) { if (!result_variable_sp) { ret = false; error.SetErrorString("Expression did not return a result"); return false; } result_value_sp = result_variable_sp->GetValueObject(); if (result_value_sp) { Scalar scalar_value; if (result_value_sp->ResolveValue (scalar_value)) { if (scalar_value.ULongLong(1) == 0) ret = false; else ret = true; if (log) log->Printf("Condition successfully evaluated, result is %s.\n", ret ? "true" : "false"); } else { ret = false; error.SetErrorString("Failed to get an integer result from the expression"); } } else { ret = false; error.SetErrorString("Failed to get any result from the expression"); } } else { ret = false; error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData()); } return ret; }
void CompactUnwindInfo::ScanIndex (const ProcessSP &process_sp) { Mutex::Locker locker(m_mutex); if (m_indexes_computed == eLazyBoolYes && m_unwindinfo_data_computed) return; // We can't read the index for some reason. if (m_indexes_computed == eLazyBoolNo) { return; } Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); if (log) m_objfile.GetModule()->LogMessage(log, "Reading compact unwind first-level indexes"); if (m_unwindinfo_data_computed == false) { if (m_section_sp->IsEncrypted()) { // Can't get section contents of a protected/encrypted section until we have a live // process and can read them out of memory. if (process_sp.get() == nullptr) return; m_section_contents_if_encrypted.reset (new DataBufferHeap (m_section_sp->GetByteSize(), 0)); Error error; if (process_sp->ReadMemory ( m_section_sp->GetLoadBaseAddress (&process_sp->GetTarget()), m_section_contents_if_encrypted->GetBytes(), m_section_sp->GetByteSize(), error) == m_section_sp->GetByteSize() && error.Success()) { m_unwindinfo_data.SetAddressByteSize (process_sp->GetTarget().GetArchitecture().GetAddressByteSize()); m_unwindinfo_data.SetByteOrder (process_sp->GetTarget().GetArchitecture().GetByteOrder()); m_unwindinfo_data.SetData (m_section_contents_if_encrypted, 0); } } else { m_objfile.ReadSectionData (m_section_sp.get(), m_unwindinfo_data); } if (m_unwindinfo_data.GetByteSize() != m_section_sp->GetByteSize()) return; m_unwindinfo_data_computed = true; } if (m_unwindinfo_data.GetByteSize() > 0) { offset_t offset = 0; // struct unwind_info_section_header // { // uint32_t version; // UNWIND_SECTION_VERSION // uint32_t commonEncodingsArraySectionOffset; // uint32_t commonEncodingsArrayCount; // uint32_t personalityArraySectionOffset; // uint32_t personalityArrayCount; // uint32_t indexSectionOffset; // uint32_t indexCount; m_unwind_header.version = m_unwindinfo_data.GetU32(&offset); m_unwind_header.common_encodings_array_offset = m_unwindinfo_data.GetU32(&offset); m_unwind_header.common_encodings_array_count = m_unwindinfo_data.GetU32(&offset); m_unwind_header.personality_array_offset = m_unwindinfo_data.GetU32(&offset); m_unwind_header.personality_array_count = m_unwindinfo_data.GetU32(&offset); uint32_t indexSectionOffset = m_unwindinfo_data.GetU32(&offset); uint32_t indexCount = m_unwindinfo_data.GetU32(&offset); if (m_unwind_header.common_encodings_array_offset > m_unwindinfo_data.GetByteSize() || m_unwind_header.personality_array_offset > m_unwindinfo_data.GetByteSize() || indexSectionOffset > m_unwindinfo_data.GetByteSize() || offset > m_unwindinfo_data.GetByteSize()) { Host::SystemLog (Host::eSystemLogError, "error: Invalid offset encountered in compact unwind info, skipping\n"); // don't trust anything from this compact_unwind section if it looks // blatantly invalid data in the header. m_indexes_computed = eLazyBoolNo; return; } // Parse the basic information from the indexes // We wait to scan the second level page info until it's needed // struct unwind_info_section_header_index_entry // { // uint32_t functionOffset; // uint32_t secondLevelPagesSectionOffset; // uint32_t lsdaIndexArraySectionOffset; // }; offset = indexSectionOffset; for (uint32_t idx = 0; idx < indexCount; idx++) { uint32_t function_offset = m_unwindinfo_data.GetU32(&offset); // functionOffset uint32_t second_level_offset = m_unwindinfo_data.GetU32(&offset); // secondLevelPagesSectionOffset uint32_t lsda_offset = m_unwindinfo_data.GetU32(&offset); // lsdaIndexArraySectionOffset if (second_level_offset > m_section_sp->GetByteSize() || lsda_offset > m_section_sp->GetByteSize()) { m_indexes_computed = eLazyBoolNo; } UnwindIndex this_index; this_index.function_offset = function_offset; // this_index.second_level = second_level_offset; this_index.lsda_array_start = lsda_offset; if (m_indexes.size() > 0) { m_indexes[m_indexes.size() - 1].lsda_array_end = lsda_offset; } if (second_level_offset == 0) { this_index.sentinal_entry = true; } m_indexes.push_back (this_index); } m_indexes_computed = eLazyBoolYes; } else { m_indexes_computed = eLazyBoolNo; } }
Error Host::LaunchProcessPosixSpawn(const char *exe_path, const ProcessLaunchInfo &launch_info, lldb::pid_t &pid) { Error error; Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS)); posix_spawnattr_t attr; error.SetError(::posix_spawnattr_init(&attr), eErrorTypePOSIX); if (error.Fail() || log) error.PutToLog(log, "::posix_spawnattr_init ( &attr )"); if (error.Fail()) return error; // Make a quick class that will cleanup the posix spawn attributes in case // we return in the middle of this function. lldb_utility::CleanUp<posix_spawnattr_t *, int> posix_spawnattr_cleanup( &attr, posix_spawnattr_destroy); sigset_t no_signals; sigset_t all_signals; sigemptyset(&no_signals); sigfillset(&all_signals); ::posix_spawnattr_setsigmask(&attr, &no_signals); #if defined(__linux__) || defined(__FreeBSD__) ::posix_spawnattr_setsigdefault(&attr, &no_signals); #else ::posix_spawnattr_setsigdefault(&attr, &all_signals); #endif short flags = GetPosixspawnFlags(launch_info); error.SetError(::posix_spawnattr_setflags(&attr, flags), eErrorTypePOSIX); if (error.Fail() || log) error.PutToLog(log, "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags); if (error.Fail()) return error; // posix_spawnattr_setbinpref_np appears to be an Apple extension per: // http://www.unix.com/man-page/OSX/3/posix_spawnattr_setbinpref_np/ #if defined(__APPLE__) && !defined(__arm__) // Don't set the binpref if a shell was provided. After all, that's only // going to affect what version of the shell // is launched, not what fork of the binary is launched. We insert "arch // --arch <ARCH> as part of the shell invocation // to do that job on OSX. if (launch_info.GetShell() == nullptr) { // We don't need to do this for ARM, and we really shouldn't now that we // have multiple CPU subtypes and no posix_spawnattr call that allows us // to set which CPU subtype to launch... const ArchSpec &arch_spec = launch_info.GetArchitecture(); cpu_type_t cpu = arch_spec.GetMachOCPUType(); cpu_type_t sub = arch_spec.GetMachOCPUSubType(); if (cpu != 0 && cpu != static_cast<cpu_type_t>(UINT32_MAX) && cpu != static_cast<cpu_type_t>(LLDB_INVALID_CPUTYPE) && !(cpu == 0x01000007 && sub == 8)) // If haswell is specified, don't try // to set the CPU type or we will fail { size_t ocount = 0; error.SetError(::posix_spawnattr_setbinpref_np(&attr, 1, &cpu, &ocount), eErrorTypePOSIX); if (error.Fail() || log) error.PutToLog(log, "::posix_spawnattr_setbinpref_np ( &attr, 1, " "cpu_type = 0x%8.8x, count => %llu )", cpu, (uint64_t)ocount); if (error.Fail() || ocount != 1) return error; } } #endif const char *tmp_argv[2]; char *const *argv = const_cast<char *const *>( launch_info.GetArguments().GetConstArgumentVector()); char *const *envp = const_cast<char *const *>( launch_info.GetEnvironmentEntries().GetConstArgumentVector()); if (argv == NULL) { // posix_spawn gets very unhappy if it doesn't have at least the program // name in argv[0]. One of the side affects I have noticed is the // environment // variables don't make it into the child process if "argv == NULL"!!! tmp_argv[0] = exe_path; tmp_argv[1] = NULL; argv = const_cast<char *const *>(tmp_argv); } #if !defined(__APPLE__) // manage the working directory char current_dir[PATH_MAX]; current_dir[0] = '\0'; #endif FileSpec working_dir{launch_info.GetWorkingDirectory()}; if (working_dir) { #if defined(__APPLE__) // Set the working directory on this thread only if (__pthread_chdir(working_dir.GetCString()) < 0) { if (errno == ENOENT) { error.SetErrorStringWithFormat("No such file or directory: %s", working_dir.GetCString()); } else if (errno == ENOTDIR) { error.SetErrorStringWithFormat("Path doesn't name a directory: %s", working_dir.GetCString()); } else { error.SetErrorStringWithFormat("An unknown error occurred when " "changing directory for process " "execution."); } return error; } #else if (::getcwd(current_dir, sizeof(current_dir)) == NULL) { error.SetError(errno, eErrorTypePOSIX); error.LogIfError(log, "unable to save the current directory"); return error; } if (::chdir(working_dir.GetCString()) == -1) { error.SetError(errno, eErrorTypePOSIX); error.LogIfError(log, "unable to change working directory to %s", working_dir.GetCString()); return error; } #endif } ::pid_t result_pid = LLDB_INVALID_PROCESS_ID; const size_t num_file_actions = launch_info.GetNumFileActions(); if (num_file_actions > 0) { posix_spawn_file_actions_t file_actions; error.SetError(::posix_spawn_file_actions_init(&file_actions), eErrorTypePOSIX); if (error.Fail() || log) error.PutToLog(log, "::posix_spawn_file_actions_init ( &file_actions )"); if (error.Fail()) return error; // Make a quick class that will cleanup the posix spawn attributes in case // we return in the middle of this function. lldb_utility::CleanUp<posix_spawn_file_actions_t *, int> posix_spawn_file_actions_cleanup(&file_actions, posix_spawn_file_actions_destroy); for (size_t i = 0; i < num_file_actions; ++i) { const FileAction *launch_file_action = launch_info.GetFileActionAtIndex(i); if (launch_file_action) { if (!AddPosixSpawnFileAction(&file_actions, launch_file_action, log, error)) return error; } } error.SetError( ::posix_spawnp(&result_pid, exe_path, &file_actions, &attr, argv, envp), eErrorTypePOSIX); if (error.Fail() || log) { error.PutToLog( log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, " "attr = %p, argv = %p, envp = %p )", result_pid, exe_path, static_cast<void *>(&file_actions), static_cast<void *>(&attr), reinterpret_cast<const void *>(argv), reinterpret_cast<const void *>(envp)); if (log) { for (int ii = 0; argv[ii]; ++ii) log->Printf("argv[%i] = '%s'", ii, argv[ii]); } } } else { error.SetError( ::posix_spawnp(&result_pid, exe_path, NULL, &attr, argv, envp), eErrorTypePOSIX); if (error.Fail() || log) { error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', " "file_actions = NULL, attr = %p, argv = %p, envp = " "%p )", result_pid, exe_path, static_cast<void *>(&attr), reinterpret_cast<const void *>(argv), reinterpret_cast<const void *>(envp)); if (log) { for (int ii = 0; argv[ii]; ++ii) log->Printf("argv[%i] = '%s'", ii, argv[ii]); } } } pid = result_pid; if (working_dir) { #if defined(__APPLE__) // No more thread specific current working directory __pthread_fchdir(-1); #else if (::chdir(current_dir) == -1 && error.Success()) { error.SetError(errno, eErrorTypePOSIX); error.LogIfError(log, "unable to change current directory back to %s", current_dir); } #endif } return error; }
bool CompactUnwindInfo::CreateUnwindPlan_x86_64 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start) { unwind_plan.SetSourceName ("compact unwind info"); unwind_plan.SetSourcedFromCompiler (eLazyBoolYes); unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolNo); unwind_plan.SetRegisterKind (eRegisterKindEHFrame); unwind_plan.SetLSDAAddress (function_info.lsda_address); unwind_plan.SetPersonalityFunctionPtr (function_info.personality_ptr_address); UnwindPlan::RowSP row (new UnwindPlan::Row); const int wordsize = 8; int mode = function_info.encoding & UNWIND_X86_64_MODE_MASK; switch (mode) { case UNWIND_X86_64_MODE_RBP_FRAME: { row->GetCFAValue().SetIsRegisterPlusOffset ( translate_to_eh_frame_regnum_x86_64 (UNWIND_X86_64_REG_RBP), 2 * wordsize); row->SetOffset (0); row->SetRegisterLocationToAtCFAPlusOffset (x86_64_eh_regnum::rbp, wordsize * -2, true); row->SetRegisterLocationToAtCFAPlusOffset (x86_64_eh_regnum::rip, wordsize * -1, true); row->SetRegisterLocationToIsCFAPlusOffset (x86_64_eh_regnum::rsp, 0, true); uint32_t saved_registers_offset = EXTRACT_BITS (function_info.encoding, UNWIND_X86_64_RBP_FRAME_OFFSET); uint32_t saved_registers_locations = EXTRACT_BITS (function_info.encoding, UNWIND_X86_64_RBP_FRAME_REGISTERS); saved_registers_offset += 2; for (int i = 0; i < 5; i++) { uint32_t regnum = saved_registers_locations & 0x7; switch (regnum) { case UNWIND_X86_64_REG_NONE: break; case UNWIND_X86_64_REG_RBX: case UNWIND_X86_64_REG_R12: case UNWIND_X86_64_REG_R13: case UNWIND_X86_64_REG_R14: case UNWIND_X86_64_REG_R15: row->SetRegisterLocationToAtCFAPlusOffset (translate_to_eh_frame_regnum_x86_64 (regnum), wordsize * -saved_registers_offset, true); break; } saved_registers_offset--; saved_registers_locations >>= 3; } unwind_plan.AppendRow (row); return true; } break; case UNWIND_X86_64_MODE_STACK_IND: { // The clang in Xcode 6 is emitting incorrect compact unwind encodings for this // style of unwind. It was fixed in llvm r217020. // The clang in Xcode 7 has this fixed. return false; } break; case UNWIND_X86_64_MODE_STACK_IMMD: { uint32_t stack_size = EXTRACT_BITS (function_info.encoding, UNWIND_X86_64_FRAMELESS_STACK_SIZE); uint32_t register_count = EXTRACT_BITS (function_info.encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT); uint32_t permutation = EXTRACT_BITS (function_info.encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION); if (mode == UNWIND_X86_64_MODE_STACK_IND && function_info.valid_range_offset_start != 0) { uint32_t stack_adjust = EXTRACT_BITS (function_info.encoding, UNWIND_X86_64_FRAMELESS_STACK_ADJUST); // offset into the function instructions; 0 == beginning of first instruction uint32_t offset_to_subl_insn = EXTRACT_BITS (function_info.encoding, UNWIND_X86_64_FRAMELESS_STACK_SIZE); SectionList *sl = m_objfile.GetSectionList (); if (sl) { ProcessSP process_sp = target.GetProcessSP(); if (process_sp) { Address subl_payload_addr (function_info.valid_range_offset_start, sl); subl_payload_addr.Slide (offset_to_subl_insn); Error error; uint64_t large_stack_size = process_sp->ReadUnsignedIntegerFromMemory (subl_payload_addr.GetLoadAddress (&target), 4, 0, error); if (large_stack_size != 0 && error.Success ()) { // Got the large stack frame size correctly - use it stack_size = large_stack_size + (stack_adjust * wordsize); } else { return false; } } else { return false; } } else { return false; } } int32_t offset = mode == UNWIND_X86_64_MODE_STACK_IND ? stack_size : stack_size * wordsize; row->GetCFAValue().SetIsRegisterPlusOffset (x86_64_eh_regnum::rsp, offset); row->SetOffset (0); row->SetRegisterLocationToAtCFAPlusOffset (x86_64_eh_regnum::rip, wordsize * -1, true); row->SetRegisterLocationToIsCFAPlusOffset (x86_64_eh_regnum::rsp, 0, true); if (register_count > 0) { // We need to include (up to) 6 registers in 10 bits. // That would be 18 bits if we just used 3 bits per reg to indicate // the order they're saved on the stack. // // This is done with Lehmer code permutation, e.g. see // http://stackoverflow.com/questions/1506078/fast-permutation-number-permutation-mapping-algorithms int permunreg[6] = {0, 0, 0, 0, 0, 0}; // This decodes the variable-base number in the 10 bits // and gives us the Lehmer code sequence which can then // be decoded. switch (register_count) { case 6: permunreg[0] = permutation/120; // 120 == 5! permutation -= (permunreg[0]*120); permunreg[1] = permutation/24; // 24 == 4! permutation -= (permunreg[1]*24); permunreg[2] = permutation/6; // 6 == 3! permutation -= (permunreg[2]*6); permunreg[3] = permutation/2; // 2 == 2! permutation -= (permunreg[3]*2); permunreg[4] = permutation; // 1 == 1! permunreg[5] = 0; break; case 5: permunreg[0] = permutation/120; permutation -= (permunreg[0]*120); permunreg[1] = permutation/24; permutation -= (permunreg[1]*24); permunreg[2] = permutation/6; permutation -= (permunreg[2]*6); permunreg[3] = permutation/2; permutation -= (permunreg[3]*2); permunreg[4] = permutation; break; case 4: permunreg[0] = permutation/60; permutation -= (permunreg[0]*60); permunreg[1] = permutation/12; permutation -= (permunreg[1]*12); permunreg[2] = permutation/3; permutation -= (permunreg[2]*3); permunreg[3] = permutation; break; case 3: permunreg[0] = permutation/20; permutation -= (permunreg[0]*20); permunreg[1] = permutation/4; permutation -= (permunreg[1]*4); permunreg[2] = permutation; break; case 2: permunreg[0] = permutation/5; permutation -= (permunreg[0]*5); permunreg[1] = permutation; break; case 1: permunreg[0] = permutation; break; } // Decode the Lehmer code for this permutation of // the registers v. http://en.wikipedia.org/wiki/Lehmer_code int registers[6] = { UNWIND_X86_64_REG_NONE, UNWIND_X86_64_REG_NONE, UNWIND_X86_64_REG_NONE, UNWIND_X86_64_REG_NONE, UNWIND_X86_64_REG_NONE, UNWIND_X86_64_REG_NONE }; bool used[7] = { false, false, false, false, false, false, false }; for (uint32_t i = 0; i < register_count; i++) { int renum = 0; for (int j = 1; j < 7; j++) { if (used[j] == false) { if (renum == permunreg[i]) { registers[i] = j; used[j] = true; break; } renum++; } } } uint32_t saved_registers_offset = 1; saved_registers_offset++; for (int i = (sizeof (registers) / sizeof (int)) - 1; i >= 0; i--) { switch (registers[i]) { case UNWIND_X86_64_REG_NONE: break; case UNWIND_X86_64_REG_RBX: case UNWIND_X86_64_REG_R12: case UNWIND_X86_64_REG_R13: case UNWIND_X86_64_REG_R14: case UNWIND_X86_64_REG_R15: case UNWIND_X86_64_REG_RBP: row->SetRegisterLocationToAtCFAPlusOffset (translate_to_eh_frame_regnum_x86_64 (registers[i]), wordsize * -saved_registers_offset, true); saved_registers_offset++; break; } } } unwind_plan.AppendRow (row); return true; } break; case UNWIND_X86_64_MODE_DWARF: { return false; } break; case 0: { return false; } break; } return false; }
void LogError(const Error &error) { LogString(error.GetMessage()); }
bool DoExecute (Args& command, CommandReturnObject &result) { const size_t argc = command.GetArgumentCount(); if (argc == 0) { if (!m_command_byte.GetOptionValue().OptionWasSet()) { result.AppendError ("the --command option must be set to a valid command byte"); result.SetStatus (eReturnStatusFailed); } else { const uint64_t command_byte = m_command_byte.GetOptionValue().GetUInt64Value(0); if (command_byte > 0 && command_byte <= UINT8_MAX) { ProcessKDP *process = (ProcessKDP *)m_interpreter.GetExecutionContext().GetProcessPtr(); if (process) { const StateType state = process->GetState(); if (StateIsStoppedState (state, true)) { std::vector<uint8_t> payload_bytes; const char *ascii_hex_bytes_cstr = m_packet_data.GetOptionValue().GetCurrentValue(); if (ascii_hex_bytes_cstr && ascii_hex_bytes_cstr[0]) { StringExtractor extractor(ascii_hex_bytes_cstr); const size_t ascii_hex_bytes_cstr_len = extractor.GetStringRef().size(); if (ascii_hex_bytes_cstr_len & 1) { result.AppendErrorWithFormat ("payload data must contain an even number of ASCII hex characters: '%s'", ascii_hex_bytes_cstr); result.SetStatus (eReturnStatusFailed); return false; } payload_bytes.resize(ascii_hex_bytes_cstr_len/2); if (extractor.GetHexBytes(&payload_bytes[0], payload_bytes.size(), '\xdd') != payload_bytes.size()) { result.AppendErrorWithFormat ("payload data must only contain ASCII hex characters (no spaces or hex prefixes): '%s'", ascii_hex_bytes_cstr); result.SetStatus (eReturnStatusFailed); return false; } } Error error; DataExtractor reply; process->GetCommunication().SendRawRequest (command_byte, payload_bytes.empty() ? NULL : payload_bytes.data(), payload_bytes.size(), reply, error); if (error.Success()) { // Copy the binary bytes into a hex ASCII string for the result StreamString packet; packet.PutBytesAsRawHex8(reply.GetDataStart(), reply.GetByteSize(), lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder()); result.AppendMessage(packet.GetString().c_str()); result.SetStatus (eReturnStatusSuccessFinishResult); return true; } else { const char *error_cstr = error.AsCString(); if (error_cstr && error_cstr[0]) result.AppendError (error_cstr); else result.AppendErrorWithFormat ("unknown error 0x%8.8x", error.GetError()); result.SetStatus (eReturnStatusFailed); return false; } } else { result.AppendErrorWithFormat ("process must be stopped in order to send KDP packets, state is %s", StateAsCString (state)); result.SetStatus (eReturnStatusFailed); } } else { result.AppendError ("invalid process"); result.SetStatus (eReturnStatusFailed); } } else { result.AppendErrorWithFormat ("invalid command byte 0x%" PRIx64 ", valid values are 1 - 255", command_byte); result.SetStatus (eReturnStatusFailed); } } } else { result.AppendErrorWithFormat ("'%s' takes no arguments, only options.", m_cmd_name.c_str()); result.SetStatus (eReturnStatusFailed); } return false; }
Error ModuleList::GetSharedModule ( const ModuleSpec &module_spec, ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr, bool *did_create_ptr, bool always_create ) { ModuleList &shared_module_list = GetSharedModuleList (); Mutex::Locker locker(shared_module_list.m_modules_mutex); char path[PATH_MAX]; Error error; module_sp.reset(); if (did_create_ptr) *did_create_ptr = false; if (old_module_sp_ptr) old_module_sp_ptr->reset(); const UUID *uuid_ptr = module_spec.GetUUIDPtr(); const FileSpec &module_file_spec = module_spec.GetFileSpec(); const ArchSpec &arch = module_spec.GetArchitecture(); // Make sure no one else can try and get or create a module while this // function is actively working on it by doing an extra lock on the // global mutex list. if (always_create == false) { ModuleList matching_module_list; const size_t num_matching_modules = shared_module_list.FindModules (module_spec, matching_module_list); if (num_matching_modules > 0) { for (size_t module_idx = 0; module_idx < num_matching_modules; ++module_idx) { module_sp = matching_module_list.GetModuleAtIndex(module_idx); // Make sure the file for the module hasn't been modified if (module_sp->FileHasChanged()) { if (old_module_sp_ptr && !old_module_sp_ptr->get()) *old_module_sp_ptr = module_sp; Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_MODULES)); if (log) log->Printf("module changed: %p, removing from global module list", static_cast<void*>(module_sp.get())); shared_module_list.Remove (module_sp); module_sp.reset(); } else { // The module matches and the module was not modified from // when it was last loaded. return error; } } } } if (module_sp) return error; module_sp.reset (new Module (module_spec)); // Make sure there are a module and an object file since we can specify // a valid file path with an architecture that might not be in that file. // By getting the object file we can guarantee that the architecture matches if (module_sp->GetObjectFile()) { // If we get in here we got the correct arch, now we just need // to verify the UUID if one was given if (uuid_ptr && *uuid_ptr != module_sp->GetUUID()) module_sp.reset(); else { if (did_create_ptr) *did_create_ptr = true; shared_module_list.ReplaceEquivalent(module_sp); return error; } } else module_sp.reset(); if (module_search_paths_ptr) { const auto num_directories = module_search_paths_ptr->GetSize(); for (size_t idx = 0; idx < num_directories; ++idx) { auto search_path_spec = module_search_paths_ptr->GetFileSpecAtIndex(idx); if (!search_path_spec.ResolvePath()) continue; if (!search_path_spec.Exists() || !search_path_spec.IsDirectory()) continue; search_path_spec.AppendPathComponent(module_spec.GetFileSpec().GetFilename().AsCString()); if (!search_path_spec.Exists()) continue; auto resolved_module_spec(module_spec); resolved_module_spec.GetFileSpec() = search_path_spec; module_sp.reset (new Module (resolved_module_spec)); if (module_sp->GetObjectFile()) { // If we get in here we got the correct arch, now we just need // to verify the UUID if one was given if (uuid_ptr && *uuid_ptr != module_sp->GetUUID()) module_sp.reset(); else { if (did_create_ptr) *did_create_ptr = true; shared_module_list.ReplaceEquivalent(module_sp); return Error(); } } else module_sp.reset(); } } // Either the file didn't exist where at the path, or no path was given, so // we now have to use more extreme measures to try and find the appropriate // module. // Fixup the incoming path in case the path points to a valid file, yet // the arch or UUID (if one was passed in) don't match. FileSpec file_spec = Symbols::LocateExecutableObjectFile (module_spec); // Don't look for the file if it appears to be the same one we already // checked for above... if (file_spec != module_file_spec) { if (!file_spec.Exists()) { file_spec.GetPath(path, sizeof(path)); if (path[0] == '\0') module_file_spec.GetPath(path, sizeof(path)); // How can this check ever be true? This branch it is false, and we haven't modified file_spec. if (file_spec.Exists()) { std::string uuid_str; if (uuid_ptr && uuid_ptr->IsValid()) uuid_str = uuid_ptr->GetAsString(); if (arch.IsValid()) { if (!uuid_str.empty()) error.SetErrorStringWithFormat("'%s' does not contain the %s architecture and UUID %s", path, arch.GetArchitectureName(), uuid_str.c_str()); else error.SetErrorStringWithFormat("'%s' does not contain the %s architecture.", path, arch.GetArchitectureName()); } } else { error.SetErrorStringWithFormat("'%s' does not exist", path); } if (error.Fail()) module_sp.reset(); return error; } // Make sure no one else can try and get or create a module while this // function is actively working on it by doing an extra lock on the // global mutex list. ModuleSpec platform_module_spec(module_spec); platform_module_spec.GetFileSpec() = file_spec; platform_module_spec.GetPlatformFileSpec() = file_spec; ModuleList matching_module_list; if (shared_module_list.FindModules (platform_module_spec, matching_module_list) > 0) { module_sp = matching_module_list.GetModuleAtIndex(0); // If we didn't have a UUID in mind when looking for the object file, // then we should make sure the modification time hasn't changed! if (platform_module_spec.GetUUIDPtr() == NULL) { TimeValue file_spec_mod_time(file_spec.GetModificationTime()); if (file_spec_mod_time.IsValid()) { if (file_spec_mod_time != module_sp->GetModificationTime()) { if (old_module_sp_ptr) *old_module_sp_ptr = module_sp; shared_module_list.Remove (module_sp); module_sp.reset(); } } } } if (module_sp.get() == NULL) { module_sp.reset (new Module (platform_module_spec)); // Make sure there are a module and an object file since we can specify // a valid file path with an architecture that might not be in that file. // By getting the object file we can guarantee that the architecture matches if (module_sp && module_sp->GetObjectFile()) { if (did_create_ptr) *did_create_ptr = true; shared_module_list.ReplaceEquivalent(module_sp); } else { file_spec.GetPath(path, sizeof(path)); if (file_spec) { if (arch.IsValid()) error.SetErrorStringWithFormat("unable to open %s architecture in '%s'", arch.GetArchitectureName(), path); else error.SetErrorStringWithFormat("unable to open '%s'", path); } else { std::string uuid_str; if (uuid_ptr && uuid_ptr->IsValid()) uuid_str = uuid_ptr->GetAsString(); if (!uuid_str.empty()) error.SetErrorStringWithFormat("cannot locate a module for UUID '%s'", uuid_str.c_str()); else error.SetErrorStringWithFormat("cannot locate a module"); } } } } return error; }
Error ProcessKDP::DoConnectRemote (Stream *strm, const char *remote_url) { Error error; // Don't let any JIT happen when doing KDP as we can't allocate // memory and we don't want to be mucking with threads that might // already be handling exceptions SetCanJIT(false); if (remote_url == NULL || remote_url[0] == '\0') { error.SetErrorStringWithFormat ("invalid connection URL '%s'", remote_url); return error; } std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor()); if (conn_ap.get()) { // Only try once for now. // TODO: check if we should be retrying? const uint32_t max_retry_count = 1; for (uint32_t retry_count = 0; retry_count < max_retry_count; ++retry_count) { if (conn_ap->Connect(remote_url, &error) == eConnectionStatusSuccess) break; usleep (100000); } } if (conn_ap->IsConnected()) { const Socket& socket = static_cast<const Socket&>(*conn_ap->GetReadObject()); const uint16_t reply_port = socket.GetPortNumber(); if (reply_port != 0) { m_comm.SetConnection(conn_ap.release()); if (m_comm.SendRequestReattach(reply_port)) { if (m_comm.SendRequestConnect(reply_port, reply_port, "Greetings from LLDB...")) { m_comm.GetVersion(); uint32_t cpu = m_comm.GetCPUType(); uint32_t sub = m_comm.GetCPUSubtype(); ArchSpec kernel_arch; kernel_arch.SetArchitecture(eArchTypeMachO, cpu, sub); m_target.SetArchitecture(kernel_arch); /* Get the kernel's UUID and load address via KDP_KERNELVERSION packet. */ /* An EFI kdp session has neither UUID nor load address. */ UUID kernel_uuid = m_comm.GetUUID (); addr_t kernel_load_addr = m_comm.GetLoadAddress (); if (m_comm.RemoteIsEFI ()) { // Select an invalid plugin name for the dynamic loader so one doesn't get used // since EFI does its own manual loading via python scripting static ConstString g_none_dynamic_loader("none"); m_dyld_plugin_name = g_none_dynamic_loader; if (kernel_uuid.IsValid()) { // If EFI passed in a UUID= try to lookup UUID // The slide will not be provided. But the UUID // lookup will be used to launch EFI debug scripts // from the dSYM, that can load all of the symbols. ModuleSpec module_spec; module_spec.GetUUID() = kernel_uuid; module_spec.GetArchitecture() = m_target.GetArchitecture(); // Lookup UUID locally, before attempting dsymForUUID like action module_spec.GetSymbolFileSpec() = Symbols::LocateExecutableSymbolFile(module_spec); if (module_spec.GetSymbolFileSpec()) module_spec.GetFileSpec() = Symbols::LocateExecutableObjectFile (module_spec); if (!module_spec.GetSymbolFileSpec() || !module_spec.GetSymbolFileSpec()) Symbols::DownloadObjectAndSymbolFile (module_spec, true); if (module_spec.GetFileSpec().Exists()) { ModuleSP module_sp(new Module (module_spec.GetFileSpec(), m_target.GetArchitecture())); if (module_sp.get() && module_sp->MatchesModuleSpec (module_spec)) { // Get the current target executable ModuleSP exe_module_sp (m_target.GetExecutableModule ()); // Make sure you don't already have the right module loaded and they will be uniqued if (exe_module_sp.get() != module_sp.get()) m_target.SetExecutableModule (module_sp, false); } } } } else if (m_comm.RemoteIsDarwinKernel ()) { m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic(); if (kernel_load_addr != LLDB_INVALID_ADDRESS) { m_kernel_load_addr = kernel_load_addr; } } // Set the thread ID UpdateThreadListIfNeeded (); SetID (1); GetThreadList (); SetPrivateState (eStateStopped); StreamSP async_strm_sp(m_target.GetDebugger().GetAsyncOutputStream()); if (async_strm_sp) { const char *cstr; if ((cstr = m_comm.GetKernelVersion ()) != NULL) { async_strm_sp->Printf ("Version: %s\n", cstr); async_strm_sp->Flush(); } // if ((cstr = m_comm.GetImagePath ()) != NULL) // { // async_strm_sp->Printf ("Image Path: %s\n", cstr); // async_strm_sp->Flush(); // } } } else { error.SetErrorString("KDP_REATTACH failed"); } } else { error.SetErrorString("KDP_REATTACH failed"); } } else { error.SetErrorString("invalid reply port from UDP connection"); } } else { if (error.Success()) error.SetErrorStringWithFormat ("failed to connect to '%s'", remote_url); } if (error.Fail()) m_comm.Disconnect(); return error; }
inline void example_print_error_common( Error& error, std::ostream& errstr ) { example_print_std_error_common(error, errstr); errstr << "in '" << error.GLSymbol() << "'" << std::endl; errstr << "at ["; errstr << error.File() << ":" << error.Line(); errstr << "]" << std::endl; bool nl = false; if(std::strlen(error.ObjectTypeName())) { errstr << error.ObjectTypeName(); nl |= true; } if(!error.ObjectDescription().empty()) { if(nl) errstr << " "; errstr << "'" << error.ObjectDescription() << "'"; nl |= true; } if(std::strlen(error.BindTarget())) { if(!nl) errstr << "Object"; errstr << " bound to '" << error.BindTarget() << "'"; nl |= true; } if(nl) errstr << std::endl; auto i = error.Properties().begin(), e = error.Properties().end(); if(i != e) { errstr << "Properties: " << std::endl; while(i != e) { errstr << "<" << i->first << "='" << i->second << "'>"; ++i; if(i != e) errstr << ", "; else errstr << "."; } errstr << std::endl; } }
Error ProcessKDP::DoResume () { Error error; Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS)); // Only start the async thread if we try to do any process control if (!IS_VALID_LLDB_HOST_THREAD(m_async_thread)) StartAsyncThread (); bool resume = false; // With KDP there is only one thread we can tell what to do ThreadSP kernel_thread_sp (m_thread_list.FindThreadByProtocolID(g_kernel_tid)); if (kernel_thread_sp) { const StateType thread_resume_state = kernel_thread_sp->GetTemporaryResumeState(); if (log) log->Printf ("ProcessKDP::DoResume() thread_resume_state = %s", StateAsCString(thread_resume_state)); switch (thread_resume_state) { case eStateSuspended: // Nothing to do here when a thread will stay suspended // we just leave the CPU mask bit set to zero for the thread if (log) log->Printf ("ProcessKDP::DoResume() = suspended???"); break; case eStateStepping: { lldb::RegisterContextSP reg_ctx_sp (kernel_thread_sp->GetRegisterContext()); if (reg_ctx_sp) { if (log) log->Printf ("ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (true);"); reg_ctx_sp->HardwareSingleStep (true); resume = true; } else { error.SetErrorStringWithFormat("KDP thread 0x%llx has no register context", kernel_thread_sp->GetID()); } } break; case eStateRunning: { lldb::RegisterContextSP reg_ctx_sp (kernel_thread_sp->GetRegisterContext()); if (reg_ctx_sp) { if (log) log->Printf ("ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (false);"); reg_ctx_sp->HardwareSingleStep (false); resume = true; } else { error.SetErrorStringWithFormat("KDP thread 0x%llx has no register context", kernel_thread_sp->GetID()); } } break; default: // The only valid thread resume states are listed above assert (!"invalid thread resume state"); break; } } if (resume) { if (log) log->Printf ("ProcessKDP::DoResume () sending resume"); if (m_comm.SendRequestResume ()) { m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue); SetPrivateState(eStateRunning); } else error.SetErrorString ("KDP resume failed"); } else { error.SetErrorString ("kernel thread is suspended"); } return error; }
UINT CFlyCap2MFCDoc::DoGrabLoop() { Error error; CString csMessage; error = m_pCamera->StartCapture(); if( error != PGRERROR_OK ) { csMessage.Format( "StartCapture Failure: %s", error.GetDescription() ); AfxMessageBox( csMessage, MB_ICONSTOP ); return 0; } // // Start of main grab loop // while( m_continueGrabThread ) { error = m_pCamera->RetrieveBuffer( &m_rawImage ); if( error != PGRERROR_OK ) { csMessage.Format( "RetrieveBuffer Failure: %s", error.GetDescription() ); continue; } // Keep a reference to image so that we can save it // Doing this only when m_saveImage is not being saved if( m_beingSaved == false ) { m_saveImage = m_rawImage; } // // Check to see if the thread should die. // if( !m_continueGrabThread ) { break; } // // Update current framerate. // m_processedFrameRate.NewFrame(); // // We try to detect whether the view is getting behind on servicing // the invalidate requests we send to it. If there is still an // invalid area, don't bother color processing this frame. // bool skipProcessing = false; POSITION pos = GetFirstViewPosition(); while ( pos != NULL ) { if( GetUpdateRect( GetNextView( pos )->GetSafeHwnd(), NULL, FALSE ) != 0 ) { skipProcessing = true; } } if( !skipProcessing ) { // // Do post processing on the image. // unsigned int rows,cols,stride; PixelFormat format; m_rawImage.GetDimensions( &rows, &cols, &stride, &format ); CSingleLock dataLock( &m_csData ); dataLock.Lock(); error = m_rawImage.Convert( PIXEL_FORMAT_BGR, &m_processedImage ); if( error != PGRERROR_OK ) { csMessage.Format( "Convert Failure: %s", error.GetDescription() ); continue; } dataLock.Unlock(); InitBitmapStruct( cols, rows ); RedrawAllViews(); } } error = m_pCamera->StopCapture(); if( error != PGRERROR_OK ) { csMessage.Format( "Stop Failure: %s", error.GetDescription() ); AfxMessageBox( csMessage, MB_ICONSTOP ); } // // End of main grab loop // SetEvent( m_heventThreadDone ); return 0; }
lldb::addr_t ProcessKDP::DoAllocateMemory (size_t size, uint32_t permissions, Error &error) { error.SetErrorString ("memory allocation not suppported in kdp remote debugging"); return LLDB_INVALID_ADDRESS; }
BOOL CFlyCap2MFCDoc::OnNewDocument() { Error error; if (!CDocument::OnNewDocument()) { return FALSE; } // Set the default image processing parameters Image::SetDefaultColorProcessing( NEAREST_NEIGHBOR ); Image::SetDefaultOutputFormat( PIXEL_FORMAT_BGRU ); // If entering this function from File->New Camera, stop the grab thread // first before doing anything else if ( m_continueGrabThread == true ) { m_continueGrabThread = false; DWORD dwRet = WaitForSingleObject( m_heventThreadDone, 5000 ); if ( dwRet == WAIT_TIMEOUT ) { // Timed out while waiting for thread to exit } m_camCtlDlg.Hide(); m_camCtlDlg.Disconnect(); m_pCamera->Disconnect(); } // Let the user select a camera bool okSelected; PGRGuid arGuid[64]; unsigned int size = 64; CameraSelectionDlg camSlnDlg; camSlnDlg.ShowModal( &okSelected, arGuid, &size ); if ( okSelected != true ) { return FALSE; } BusManager busMgr; InterfaceType ifType; error = busMgr.GetInterfaceTypeFromGuid( &arGuid[0], &ifType ); if ( error != PGRERROR_OK ) { return FALSE; } if ( ifType == INTERFACE_GIGE ) { m_pCamera = new GigECamera; } else { m_pCamera = new Camera; } // Connect to the 0th selected camera error = m_pCamera->Connect( &arGuid[0] ); if( error != PGRERROR_OK ) { CString csMessage; csMessage.Format( "Connect Failure: %s", error.GetDescription() ); AfxMessageBox( csMessage, MB_ICONSTOP ); return FALSE; } error = m_pCamera->GetCameraInfo( &m_cameraInfo ); if( error != PGRERROR_OK ) { CString csMessage; csMessage.Format( "CameraInfo Failure: %s", error.GetDescription() ); AfxMessageBox( csMessage, MB_ICONSTOP ); return FALSE; } // Connect the camera control dialog to the camera object m_camCtlDlg.Connect( m_pCamera ); // Start the grab thread m_continueGrabThread = true; AfxBeginThread( ThreadGrabImage, this ); return TRUE; }
bool lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream) { ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); if (!runtime) return false; ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj)); if (!descriptor.get() || !descriptor->IsValid()) return false; uint32_t ptr_size = process_sp->GetAddressByteSize(); bool is_64bit = (ptr_size == 8); lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); if (!valobj_addr) return false; uint64_t value = 0; const char* class_name = descriptor->GetClassName().GetCString(); if (!class_name || !*class_name) return false; if (!strcmp(class_name,"__NSDictionaryI")) { Error error; value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error); if (error.Fail()) return false; value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); } else if (!strcmp(class_name,"__NSDictionaryM")) { Error error; value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error); if (error.Fail()) return false; value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); } /*else if (!strcmp(class_name,"__NSCFDictionary")) { Error error; value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), 4, 0, error); if (error.Fail()) return false; if (is_64bit) value &= ~0x0f1f000000000000UL; }*/ else { if (!ExtractValueFromObjCExpression(valobj, "int", "count", value)) return false; } stream.Printf("%s%" PRIu64 " %s%s", (name_entries ? "@\"" : ""), value, (name_entries ? (value == 1 ? "entry" : "entries") : (value == 1 ? "key/value pair" : "key/value pairs")), (name_entries ? "\"" : "")); return true; }