Skip to content

Commit

Permalink
improve ldebug -c + fix lack of dep on static dep
Browse files Browse the repository at this point in the history
  • Loading branch information
cesar-douady committed Apr 30, 2024
1 parent 87d1f6b commit 74363a4
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 31 deletions.
1 change: 1 addition & 0 deletions Manifest
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ unit_tests/manual_target.py
unit_tests/misc1.py
unit_tests/misc10.py
unit_tests/misc11.py
unit_tests/misc13.py
unit_tests/misc2.py
unit_tests/misc3.py
unit_tests/misc4.py
Expand Down
6 changes: 3 additions & 3 deletions _lib/lmake_dbg.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,15 @@ def run_pdb(dbg_dir,redirected,func,*args,**kwds) :
def run_vscode(dbg_dir,redirected,func,*args,**kwds) :
import json
import os
import signal
signal.signal(signal.SIGPIPE,signal.SIG_IGN) # vscode seems to be sensitive to SIGPIPE
try :
# Write python process information to vscode debug workspace to allow gdb to attache to it
workspace = dbg_dir + '/vscode/ldebug.code-workspace'
if os.path.exists(workspace) :
data = json.load(open(workspace))
for elmt in data['launch']['configurations'] :
if elmt.get('type') == 'by-gdb' :
if 'processId' in elmt : elmt['processId'] = os.getpid()
if 'program' in elmt : elmt['program' ] = open('/proc/self/cmdline').read().split('\x00')[:-1]
if elmt.get('type')=='by-gdb' and 'processId' in elmt : elmt['processId'] = os.getpid()
with open(workspace,'w') as out :
json.dump(data,out,indent='\t')
out.write('\n')
Expand Down
1 change: 1 addition & 0 deletions src/autodep/clmake.cc
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ static PyObject* get_autodep( PyObject* /*null*/ , PyObject* args , PyObject* kw
char c = 0/*garbage*/ ;
// we have a private Record with a private AutodepEnv, so we must go through the backdoor to alter the regular AutodepEnv
int rc [[maybe_unused]] = ::readlinkat( Record::s_root_fd() , (PrivateAdminDir+"/backdoor/autodep"s ).c_str() , &c , 1 ) ;
if (rc<0) return None.to_py_boost() ;
SWEAR( c=='0' || c=='1' , int(c) ) ;
SWEAR( rc==1 , rc ) ;
return Ptr<Bool>(c!='0')->to_py_boost() ;
Expand Down
15 changes: 8 additions & 7 deletions src/lmakeserver/cmd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ R"({
"type" : "by-gdb"
, "request" : "attach"
, "name" : "Attach C/C++"
, "program" : ""
, "program" : $interpreter
, "cwd" : $g_root_dir
, "processId" : 0
}
Expand All @@ -285,10 +285,11 @@ R"({
/**/ append_to_string( extensions , '"',ext,'"' ) ;
first = false ;
}
res = ::regex_replace( res , ::regex("\\$extensions") , extensions ) ;
res = ::regex_replace( res , ::regex("\\$name" ) , mk_json_str( j->name() ) ) ;
res = ::regex_replace( res , ::regex("\\$g_root_dir") , mk_json_str( *g_root_dir ) ) ;
res = ::regex_replace( res , ::regex("\\$program" ) , mk_json_str(to_string(*g_root_dir,'/',dbg_dir,"/cmd")) ) ;
res = ::regex_replace( res , ::regex("\\$extensions" ) , extensions ) ;
res = ::regex_replace( res , ::regex("\\$name" ) , mk_json_str( j->name() ) ) ;
res = ::regex_replace( res , ::regex("\\$g_root_dir" ) , mk_json_str( *g_root_dir ) ) ;
res = ::regex_replace( res , ::regex("\\$program" ) , mk_json_str(to_string(*g_root_dir,'/',dbg_dir,"/cmd")) ) ;
res = ::regex_replace( res , ::regex("\\$interpreter") , mk_json_str(to_string(start.interpreter[0] )) ) ;
//
::vmap_ss env = _mk_env(start.env,report_end.end.dynamic_env) ;
size_t kw = 13/*SEQUENCE_ID*/ ; for( auto&& [k,v] : env ) if (k!="TMPDIR") kw = ::max(kw,mk_json_str(k).size()) ;
Expand Down Expand Up @@ -370,8 +371,8 @@ R"({
append_to_string( script , "args=()\n" ) ;
append_to_string( script , "type code | grep -q .vscode-server || args+=( \"--user-data-dir ${DEBUG_DIR}/vscode/user\" )\n" ) ;
for( Dep const& dep : j->deps )
if (dep.dflags[Dflag::Static]) append_to_string( script , "args+=( ",mk_shell_str("-g "+dep->name()),")\n" ) ; // list dependences file to open in vscode
append_to_string( script , "args+=(\"-g ${DEBUG_DIR}/cmd\")\n" ) ;
if (dep.dflags[Dflag::Static]) append_to_string( script , "args+=( ",mk_shell_str(dep->name()),")\n" ) ; // list dependences file to open in vscode
append_to_string( script , "args+=(\"${DEBUG_DIR}/cmd\")\n" ) ;
append_to_string( script , "args+=(\"${DEBUG_DIR}/vscode/ldebug.code-workspace\")\n" ) ;
append_to_string( script , "code -n -w ${args[@]} &" ) ;
} else {
Expand Down
12 changes: 6 additions & 6 deletions src/lmakeserver/job.cc
Original file line number Diff line number Diff line change
Expand Up @@ -838,17 +838,17 @@ namespace Engine {
state.reason |= {JobReasonTag::DepMissingStatic,+dep} ;
dep_err = RunStatus::MissingStatic ;
}
continue ; // dont check modifs and errors
continue ; // dont check modifs and errors
}
if (!care) goto Continue ;
dep_modif = !dep.up_to_date() ;
if ( dep_modif && status==Status::Ok && dep.no_trigger() ) { // no_trigger only applies to successful jobs
dep_modif = !dep.up_to_date( is_static && modif ) ; // after a modified dep, consider static deps as being fully accessed to avoid reruns due to previous errors
if ( dep_modif && status==Status::Ok && dep.no_trigger() ) { // no_trigger only applies to successful jobs
trace("no_trigger",dep) ;
req->no_triggers.emplace(dep,req->no_triggers.size()) ; // record to repeat in summary, value is just to order summary in discovery order
req->no_triggers.emplace(dep,req->no_triggers.size()) ; // record to repeat in summary, value is just to order summary in discovery order
dep_modif = false ;
}
if ( +state.stamped_err ) goto Continue ; // we are already in error, no need to analyze errors any further
if ( !is_static && modif ) goto Continue ; // if not static, errors may be washed by previous modifs, dont record them
if ( +state.stamped_err ) goto Continue ; // we are already in error, no need to analyze errors any further
if ( !is_static && modif ) goto Continue ; // if not static, errors may be washed by previous modifs, dont record them
if ( dep_modif ) state.reason |= {JobReasonTag::DepOutOfDate,+dep} ;
//
switch (dnd.ok(*cdri,dep.accesses)) {
Expand Down
32 changes: 17 additions & 15 deletions src/lmakeserver/node.x.hh
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ namespace Engine {
::string accesses_str() const ;
::string dflags_str () const ;
// services
bool up_to_date () const ;
bool up_to_date (bool full=false) const ;
void acquire_crc() ;
} ;
static_assert(sizeof(Dep)==16) ;
Expand Down Expand Up @@ -358,7 +358,7 @@ namespace Engine {
void full_refresh( bool report_no_file , ::vector<Req> const& reqs , ::string const& name ) {
set_buildable() ;
if (is_src_anti()) refresh_src_anti(report_no_file,reqs,name) ;
else manual_refresh (Req() ) ; // no manual_steady diagnostic as this may be because of another job
else manual_refresh (Req() ) ; // no manual_steady diagnostic as this may be because of another job
}
//
RuleIdx conform_idx( ) const { if (_conform_idx<=MaxRuleIdx) return _conform_idx ; else return NoIdx ; }
Expand All @@ -374,7 +374,7 @@ namespace Engine {
Job cj = conform_job() ;
return +cj && ( cj->is_special() || has_actual_job(cj) ) ;
}
Bool3 ok(bool force_err=false) const { // if Maybe <=> not built
Bool3 ok(bool force_err=false) const { // if Maybe <=> not built
switch (status()) {
case NodeStatus::Plain : return No | !( force_err || conform_job()->err() ) ;
case NodeStatus::Multi : return No ;
Expand Down Expand Up @@ -411,14 +411,16 @@ namespace Engine {
}
//
// services
bool read(Accesses a) const { // return true <= file was perceived different from non-existent, assuming access provided in a
if (crc==Crc::None ) return false ; // file does not exist, cannot perceive difference
if (a[Access::Stat]) return true ; // if file exists, stat is different
bool read(Accesses a) const { // return true <= file was perceived different from non-existent, assuming access provided in a
if (crc==Crc::None ) return false ; // file does not exist, cannot perceive difference
if (a[Access::Stat]) return true ; // if file exists, stat is different
if (crc.is_lnk() ) return a[Access::Lnk] ;
if (crc.is_reg() ) return a[Access::Reg] ;
else return +a ; // dont know if file is a link, any access may have perceived a difference
else return +a ; // dont know if file is a link, any access may have perceived a difference
}
bool up_to_date( DepDigest const& dd , bool full=false ) const { // only manage crc, not dates
return crc.match( dd.crc() , full?~Accesses():dd.accesses ) ;
}
bool up_to_date(DepDigest const& dd) const { return crc.match(dd.crc(),dd.accesses) ; } // only manage crc, not dates
//
Manual manual_wash( ReqInfo& ri , bool lazy=false ) ;
//
Expand All @@ -430,13 +432,13 @@ namespace Engine {
::c_vector_view<JobTgt> prio_job_tgts (RuleIdx prio_idx) const ;
::c_vector_view<JobTgt> conform_job_tgts (ReqInfo const& ) const ;
::c_vector_view<JobTgt> conform_job_tgts ( ) const ;
::c_vector_view<JobTgt> candidate_job_tgts( ) const ; // all jobs above prio provided in conform_idx
::c_vector_view<JobTgt> candidate_job_tgts( ) const ; // all jobs above prio provided in conform_idx
//
void set_buildable( Req={} , DepDepth lvl=0 ) ; // data independent, may be pessimistic (Maybe instead of Yes), req is for error reporing only
void set_buildable( Req={} , DepDepth lvl=0 ) ; // data independent, may be pessimistic (Maybe instead of Yes), req is for error reporing only
void set_pressure ( ReqInfo& , CoarseDelay pressure ) const ;
//
void propag_speculate( Req req , Bool3 speculate ) const {
/**/ if (speculate==Yes ) return ; // fast path : nothing to propagate
/**/ if (speculate==Yes ) return ; // fast path : nothing to propagate
ReqInfo& ri = req_info(req) ; if (speculate>=ri.speculate) return ;
ri.speculate = speculate ;
_propag_speculate(ri) ;
Expand All @@ -454,7 +456,7 @@ namespace Engine {
bool/*modified*/ refresh( Crc , SigDate const& ={} ) ;
void refresh( ) ;
private :
void _set_buildable_raw( Req , DepDepth ) ; // req is for error reporting only
void _set_buildable_raw( Req , DepDepth ) ; // req is for error reporting only
bool/*done*/ _make_pre ( ReqInfo& ) ;
void _make_raw ( ReqInfo& , MakeAction , Bool3 speculate=Yes ) ;
void _set_pressure_raw ( ReqInfo& ) const ;
Expand All @@ -463,7 +465,7 @@ namespace Engine {
Buildable _gather_special_rule_tgts( ::string const& name ) ;
Buildable _gather_prio_job_tgts ( ::string const& name , Req , DepDepth lvl=0 ) ;
Buildable _gather_prio_job_tgts ( Req r , DepDepth lvl=0 ) {
if (!rule_tgts()) return Buildable::No ; // fast path : avoid computing name()
if (!rule_tgts()) return Buildable::No ; // fast path : avoid computing name()
else return _gather_prio_job_tgts( name() , r , lvl ) ;
}
//
Expand Down Expand Up @@ -612,8 +614,8 @@ namespace Engine {
// Dep
//

inline bool Dep::up_to_date() const {
return is_crc && crc().match((*this)->crc,accesses) ;
inline bool Dep::up_to_date(bool full) const {
return is_crc && crc().match( (*this)->crc , full?~Accesses():accesses ) ;
}

inline void Dep::acquire_crc() {
Expand Down
42 changes: 42 additions & 0 deletions unit_tests/misc13.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# This file is part of the open-lmake distribution ([email protected]:cesar-douady/open-lmake.git)
# Copyright (c) 2023 Doliam
# This program is free software: you can redistribute/modify under the terms of the GPL-v3 (https://www.gnu.org/licenses/gpl-3.0.html).
# This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

if __name__!='__main__' :

import sys
import time

import lmake
from lmake.rules import Rule

lmake.manifest = (
'Lmakefile.py'
, 'step.py'
)

from step import step

class Hdep(Rule) :
target = r'hdep'
cmd = 'echo 2'

class Sdep(Rule) :
target = r'sdep'
cmd = 'echo {step}'

class Dut(Rule) :
target = 'dut'
dep = 'sdep'
cmd = '[ $(cat hdep) = {step} ] && cat sdep'

else :

import ut

print('step=1',file=open('step.py','w'))
ut.lmake( 'dut' , may_rerun=1 , done=2 , failed=1 , rc=1 )

print('step=2',file=open('step.py','w'))
ut.lmake( 'dut' , done=2 ) # check sdep is not forgetten due to execution w/o hdep

0 comments on commit 74363a4

Please sign in to comment.