* dtrace.in (provider): Turn on semaphores * includes/sys/sdt.h: Likewise * tapset-utrace.cxx: Add TOK_LIBRARY. (utrace_derived_probe): Add has_library and library (utrace_derived_probe_group::emit_module_decls): Add sdt_sem_offset to stap_utrace_probes. Emit an stap_utrace_probe for stap_utrace_mmap_found Add sdt_sem_offset to stap_utrace_probe. Cleanup semaphore increment. Emit new stap_utrace_mmap_found. * tapsets.cxx (X): Add new TOK_LIBRARY. (dwarf_derived_probe): Add path and has_library. (base_query::base_query): Check for TOK_LIBRARY. (sdt_query::convert_location): Allow for TOK_LIBRARY. (uprobe_derived_probe_group::emit_module_decls): Add procname to stap_uprobe_finders. Add new sdt_sem_address. Change signature of stap_uprobe_change_plus to add offset and vm_flags. Add emit to set sdt_sem_address diff --git a/dtrace.in b/dtrace.in index 74d70e7..269f398 100755 --- a/dtrace.in +++ b/dtrace.in @@ -48,3 +48,3 @@ class provider: self.h.write("/* Generated by the Systemtap dtrace wrapper */\n") - # self.h.write("\n#define STAP_HAS_SEMAPHORES 1\n\n") + self.h.write("\n#define STAP_HAS_SEMAPHORES 1\n\n") self.h.write("\n#include \n\n") @@ -109,3 +109,3 @@ class provider: # XXX Enable this when .so semaphores work properly - self.h.write ('#define %s_ENABLED() 1 /*%s_semaphore*/\n' % (this_probe_canon,this_probe)) + self.h.write ('#define %s_ENABLED() %s_semaphore\n' % (this_probe_canon,this_probe)) # NB: unsigned short is fixed in ABI diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h index 3847c49..fb813cc 100644 --- a/includes/sys/sdt.h +++ b/includes/sys/sdt.h @@ -42,3 +42,4 @@ -#if defined STAP_HAS_SEMAPHORES && defined EXPERIMENTAL_UTRACE_SDT +// #if defined STAP_HAS_SEMAPHORES && defined EXPERIMENTAL_UTRACE_SDT +#if defined STAP_HAS_SEMAPHORES && ! defined EXPERIMENTAL_KPROBE_SDT #define STAP_SEMAPHORE(probe) \ diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx index 795d88b..23029e9 100644 --- a/tapset-utrace.cxx +++ b/tapset-utrace.cxx @@ -31,2 +31,3 @@ static const string TOK_SYSCALL("syscall"); static const string TOK_RETURN("return"); +static const string TOK_LIBRARY("library"); @@ -54,2 +55,4 @@ struct utrace_derived_probe: public derived_probe string path; + bool has_library; + string library; int64_t pid; @@ -59,4 +62,4 @@ struct utrace_derived_probe: public derived_probe utrace_derived_probe (systemtap_session &s, probe* p, probe_point* l, - bool hp, string &pn, int64_t pd, - enum utrace_derived_probe_flags f); + bool hp, string &pn, bool hl, string &ln, + int64_t pd, enum utrace_derived_probe_flags f); void join_group (systemtap_session& s); @@ -117,6 +120,6 @@ utrace_derived_probe::utrace_derived_probe (systemtap_session &s, probe* p, probe_point* l, - bool hp, string &pn, int64_t pd, - enum utrace_derived_probe_flags f): + bool hp, string &pn, bool hl, string &ln, + int64_t pd, enum utrace_derived_probe_flags f): derived_probe (p, new probe_point (*l) /* .components soon rewritten */ ), - has_path(hp), path(pn), pid(pd), flags(f), + has_path(hp), path(pn), has_library(hl), library(ln), pid(pd), flags(f), target_symbol_seen(false) @@ -601,2 +604,3 @@ struct utrace_builder: public derived_probe_builder string path; + string lib; int64_t pid; @@ -604,2 +608,3 @@ struct utrace_builder: public derived_probe_builder bool has_path = get_param (parameters, TOK_PROCESS, path); + bool has_lib = get_param (parameters, TOK_LIBRARY, lib); bool has_pid = get_param (parameters, TOK_PROCESS, pid); @@ -649,5 +654,7 @@ struct utrace_builder: public derived_probe_builder } + if (has_lib) + lib = find_executable (lib); // FIXME: Search LD_LIBRARY_PATH finished_results.push_back(new utrace_derived_probe(sess, base, location, - has_path, path, pid, + has_path, path, has_lib, lib, pid, flags)); @@ -752,7 +759,21 @@ utrace_derived_probe_group::emit_probe_decl (systemtap_session& s, if (p->sdt_semaphore_addr != 0) - s.op->line() << " .sdt_sem_address=(unsigned long)0x" + s.op->line() << " .sdt_sem_offset=(unsigned long)0x" << hex << p->sdt_semaphore_addr << dec << "ULL,"; - + s.op->line() << " .sdt_sem_address=0,"; s.op->line() << " .tsk=0,"; s.op->line() << " },"; + + if (p->sdt_semaphore_addr != 0) + { + s.op->newline() << "{"; + s.op->line() << " .tgt={"; + s.op->line() << " .procname=\"" << p->path << "\","; + s.op->line() << " .mmap_callback=&stap_utrace_mmap_found,"; + s.op->line() << " },"; + s.op->line() << " .pathname=\"" << p->library << "\","; + s.op->line() << " .sdt_sem_offset=(unsigned long)0x" + << hex << p->sdt_semaphore_addr << dec << "ULL,"; + s.op->line() << " .sdt_sem_address=0,"; + s.op->line() << " },"; + } } @@ -791,3 +812,7 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "struct task_struct *tsk;"; + s.op->newline() << "unsigned long sdt_sem_offset;"; + // FIXME: if this probe is attached to more than 1 task, having 1 + // address here won't work s.op->newline() << "unsigned long sdt_sem_address;"; + s.op->newline(0) << "const char *pathname;"; s.op->newline(-1) << "};"; @@ -915,2 +940,3 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s) + // Before writing to the semaphore, we need to check for VM_WRITE access. s.op->newline() << "if (p->sdt_sem_address != 0) {"; @@ -919,7 +945,11 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "p->tsk = tsk;"; - s.op->newline() << "__access_process_vm (tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0);"; - s.op->newline() << "sdt_semaphore += 1;"; + + s.op->newline() << "if (__access_process_vm (tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0) == sizeof (sdt_semaphore)) {"; + s.op->newline(1) << "sdt_semaphore ++;"; s.op->newline() << "__access_process_vm (tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 1);"; s.op->newline(-1) << "}"; - + s.op->newline() << "else {"; + s.op->newline(1) << "_stp_error(\"__access_process_vm failed at %s:%d\", __FUNCTION__, __LINE__);"; + s.op->newline(-1) << "}"; + s.op->newline(-1) << "}"; s.op->newline(-1) << "}"; @@ -987,2 +1017,44 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s) + // The task_finder_mmap_callback + s.op->newline() << "static int stap_utrace_mmap_found (struct stap_task_finder_target *tgt, struct task_struct *tsk, char *path, unsigned long addr, unsigned long length, unsigned long offset, unsigned long vm_flags) {"; + s.op->newline(1) << "struct stap_utrace_probe *p = container_of(tgt, struct stap_utrace_probe, tgt);"; + s.op->newline() << "int rc = 0;"; + // the shared library we're interested in + s.op->newline() << "if (path == NULL || strcmp (path, p->pathname)) return 0;"; + s.op->newline() << "_stp_printf (\"stap_utrace_mmap_found %s %#lx path %s reloc %#lx %#lx\\n\",p->pathname,p->sdt_sem_offset,path,addr,offset);"; + s.op->newline() << "if (p->sdt_sem_address == 0) {"; + s.op->indent(1); + // If the probe is in the executable itself, the offset *is* the + // address. + s.op->newline() << "if (vm_flags & VM_EXECUTABLE) {"; + s.op->indent(1); + s.op->newline() << "p->sdt_sem_address = p->sdt_sem_offset;"; + s.op->newline(-1) << "}"; + // If the probe is in a .so, we have to calculate the address. + s.op->newline() << "else {"; + s.op->indent(1); + s.op->newline() << "p->sdt_sem_address = (addr - offset) + p->sdt_sem_offset;"; + s.op->newline(-1) << "}"; + s.op->newline() << "_stp_printf (\"stap_utrace_mmap_found: sdt_sem_address %#lx = (%#lx - %#lx) + %#lx (%#lx)\\n\",p->sdt_sem_address,addr,offset,p->sdt_sem_offset, vm_flags);"; + s.op->newline(-1) << "}"; + + s.op->newline() << "if (p->sdt_sem_address) {"; + s.op->newline(1) << "unsigned short sdt_semaphore = 0;"; // NB: fixed size + s.op->newline() << "_stp_printf (\"+semaphore %#lx @ %#lx reloc %#lx addr %#lx \\n\", sdt_semaphore, p->sdt_sem_address,addr,p->sdt_sem_offset);"; + + s.op->newline() << "if (__access_process_vm (tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0) == sizeof (sdt_semaphore)) {"; + + s.op->newline(1) << "if (vm_flags & VM_WRITE) {"; + s.op->indent(1); + s.op->newline() << "sdt_semaphore ++;"; + s.op->newline() << "#ifdef DEBUG_UTRACE"; + s.op->newline() << "_stp_dbug (__FUNCTION__,__LINE__, \"+semaphore %#x @ %#lx\\n\", sdt_semaphore, p->sdt_sem_address);"; + s.op->newline() << "#endif"; + s.op->newline() << "__access_process_vm (tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 1);"; + s.op->newline(-1) << "}"; + s.op->newline(-1) << "}"; + s.op->newline(-1) << "}"; + s.op->newline() << "return 0;"; + s.op->newline(-1) << "}"; + s.op->newline() << "static struct stap_utrace_probe stap_utrace_probes[] = {"; @@ -1018,2 +1090,3 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline(-1) << "};"; + } @@ -1057,2 +1130,3 @@ utrace_derived_probe_group::emit_module_exit (systemtap_session& s) + // Before writing to the semaphore, we need to check for VM_WRITE access. s.op->newline() << "if (p->sdt_sem_address) {"; @@ -1060,7 +1134,11 @@ utrace_derived_probe_group::emit_module_exit (systemtap_session& s) // XXX p could get registered to more than one task! - s.op->newline() << "__access_process_vm (p->tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0);"; - s.op->newline() << "sdt_semaphore -= 1;"; + s.op->newline() << "if (__access_process_vm (p->tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0) == sizeof (sdt_semaphore)) {"; + s.op->newline(1) << "sdt_semaphore -= 1;"; s.op->newline() << "__access_process_vm (p->tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 1);"; s.op->newline(-1) << "}"; - + s.op->newline() << "else {"; + s.op->indent(1); + s.op->newline() << "_stp_error(\"__access_process_vm failed at %s:%d\", __FUNCTION__, __LINE__);"; + s.op->newline(-1) << "}"; + s.op->newline(-1) << "}"; s.op->newline(-1) << "}"; @@ -1096,2 +1174,4 @@ register_tapset_utrace(systemtap_session& s) ->bind(builder); + roots[i]->bind_str(TOK_LIBRARY)->bind(TOK_SYSCALL) + ->bind(builder); } diff --git a/tapsets.cxx b/tapsets.cxx index 7bae461..a261d7f 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -262,2 +262,3 @@ static const string TOK_TRACE("trace"); static const string TOK_LABEL("label"); +static const string TOK_LIBRARY("library"); @@ -351,4 +352,6 @@ struct dwarf_derived_probe: public derived_probe Dwarf_Addr addr; + string path; bool has_return; bool has_maxactive; + bool has_library; long maxactive_val; @@ -462,3 +465,5 @@ struct base_query bool has_process; + bool has_library; string module_val; // has_kernel => module_val = "kernel" + string path; // executable path if module is a .so @@ -480,3 +485,12 @@ base_query::base_query(dwflpp & dw, literal_map_t const & params): { + string library_name; has_process = get_string_param(params, TOK_PROCESS, module_val); + if (get_string_param (params, TOK_LIBRARY, library_name)) + { + has_library = true; + path = find_executable (module_val); + module_val = library_name; // FIXME: Search LD_LIBRARY_PATH + } + else + has_library = false; if (has_process) @@ -2842,7 +2856,9 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname, module (module), section (section), addr (addr), + path (q.path), has_return (q.has_return), has_maxactive (q.has_maxactive), + has_library (q.has_library), maxactive_val (q.maxactive_val), access_vars(false), - saved_longs(0), saved_strings(0), + saved_longs(0), saved_strings(0), entry_handler(0) @@ -3142,2 +3158,4 @@ dwarf_derived_probe::register_patterns(systemtap_session& s) ->bind(dw); + root->bind_str(TOK_PROCESS)->bind_str(TOK_LIBRARY)->bind_str(TOK_MARK) + ->bind(dw); root->bind_str(TOK_PROCESS)->bind_str(TOK_MARK) @@ -3985,42 +4003,48 @@ sdt_query::convert_location (probe *base, probe_point *location) { - switch (probe_type) - { - case uprobe_type: - if (sess.verbose > 3) - clog << "probe_type == uprobe_type, use statement addr: 0x" - << hex << probe_arg << dec << endl; - // process("executable").statement(probe_arg) - location->components[1]->functor = TOK_STATEMENT; - location->components[1]->arg = new literal_number(probe_arg); - break; + for (unsigned i = 0; i < location->components.size(); ++i) + if (location->components[i]->functor == TOK_MARK) + switch (probe_type) + { + case uprobe_type: + if (sess.verbose > 3) + clog << "probe_type == uprobe_type, use statement addr: 0x" + << hex << probe_arg << dec << endl; + // process("executable").statement(probe_arg) + location->components[i]->functor = TOK_STATEMENT; + location->components[i]->arg = new literal_number(probe_arg); + break; - case kprobe_type: - if (sess.verbose > 3) - clog << "probe_type == kprobe_type" << endl; - // kernel.function("*getegid*") - location->components[0]->functor = TOK_KERNEL; - location->components[0]->arg = NULL; - location->components[1]->functor = TOK_FUNCTION; - location->components[1]->arg = new literal_string("*getegid*"); - break; + case kprobe_type: + if (sess.verbose > 3) + clog << "probe_type == kprobe_type" << endl; + // kernel.function("*getegid*") + location->components[i]->functor = TOK_FUNCTION; + location->components[i]->arg = new literal_string("*getegid*"); + break; - case utrace_type: - if (sess.verbose > 3) - clog << "probe_type == utrace_type" << endl; - // process("executable").syscall - location->components[1]->functor = "syscall"; - location->components[1]->arg = NULL; - break; + case utrace_type: + if (sess.verbose > 3) + clog << "probe_type == utrace_type" << endl; + // process("executable").syscall + location->components[i]->functor = "syscall"; + location->components[i]->arg = NULL; + break; - default: - if (sess.verbose > 3) - clog << "probe_type == use_uprobe_no_dwarf, use label name: " - << "_stapprobe1_" << mark_name << endl; - // process("executable").function("*").label("_stapprobe1_MARK_NAME") - location->components[1]->functor = TOK_FUNCTION; - location->components[1]->arg = new literal_string("*"); - location->components.push_back(new probe_point::component(TOK_LABEL)); - location->components[2]->arg = new literal_string("_stapprobe1_" + mark_name); - break; - } + default: + if (sess.verbose > 3) + clog << "probe_type == use_uprobe_no_dwarf, use label name: " + << "_stapprobe1_" << mark_name << endl; + // process("executable").function("*").label("_stapprobe1_MARK_NAME") + location->components[1]->functor = TOK_FUNCTION; + location->components[1]->arg = new literal_string("*"); + location->components.push_back(new probe_point::component(TOK_LABEL)); + location->components[2]->arg = new literal_string("_stapprobe1_" + mark_name); + break; + } + else if (location->components[i]->functor == TOK_PROCESS + && probe_type == kprobe_type) + { + location->components[i]->functor = TOK_KERNEL; + location->components[i]->arg = NULL; + } @@ -4055,2 +4079,5 @@ dwarf_builder::build(systemtap_session & sess, { + string library_name; + if (get_param (parameters, TOK_LIBRARY, library_name)) + module_name = library_name; // FIXME: search LD_LIBRARY_PATH module_name = find_executable (module_name); // canonicalize it @@ -4559,3 +4586,2 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline(1) << "union { struct uprobe up; struct uretprobe urp; };"; - s.op->newline() << "unsigned long sdt_sem_address;"; // relocated to this process s.op->newline() << "int spec_index;"; // index into stap_uprobe_specs; <0 == free && unregistered @@ -4602,2 +4628,4 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) { + if (p->sdt_semaphore_addr != 0) + s.op->line() << " .procname=\"" << p->path << "\", "; s.op->line() << " .mmap_callback=&stap_uprobe_mmap_found, "; @@ -4617,2 +4645,6 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) + s.op->newline() << "unsigned long sdt_sem_address [] = {"; + for (unsigned i =0; iline() << "0,"; + s.op->line() << "0};"; s.op->newline() << "static const struct stap_uprobe_spec {"; // NB: read-only structure @@ -4623,3 +4655,3 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "void (*ph) (struct context*);"; - s.op->newline() << "unsigned long sdt_sem_address;"; + s.op->newline() << "unsigned long sdt_sem_offset;"; s.op->newline(-1) << "} stap_uprobe_specs [] = {"; // NB: read-only structure @@ -4639,3 +4671,3 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) if (p->sdt_semaphore_addr != 0) - s.op->line() << " .sdt_sem_address=(unsigned long)0x" + s.op->line() << " .sdt_sem_offset=(unsigned long)0x" << hex << p->sdt_semaphore_addr << dec << "ULL,"; @@ -4708,3 +4740,3 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline(); - s.op->newline() << "static int stap_uprobe_change_plus (struct task_struct *tsk, unsigned long relocation, unsigned long length, const struct stap_uprobe_tf *stf) {"; + s.op->newline() << "static int stap_uprobe_change_plus (struct task_struct *tsk, unsigned long relocation, unsigned long length, const struct stap_uprobe_tf *stf, unsigned long offset, unsigned long vm_flags) {"; s.op->newline(1) << "int tfi = (stf - stap_uprobe_finders);"; @@ -4759,2 +4791,16 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) + s.op->newline() << "if (sups->sdt_sem_offset && sdt_sem_address[spec_index] == 0) {"; + s.op->indent(1); + // If the probe is in the executable itself, the offset *is* the address. + s.op->newline() << "if (vm_flags & VM_EXECUTABLE) {"; + s.op->indent(1); + s.op->newline() << "sdt_sem_address[spec_index] = sups->sdt_sem_offset;"; + s.op->newline(-1) << "}"; + // If the probe is in a .so, we have to calculate the address. + s.op->newline() << "else {"; + s.op->indent(1); + s.op->newline() << "sdt_sem_address[spec_index] = (relocation - offset) + sups->sdt_sem_offset;"; + s.op->newline(-1) << "}"; + s.op->newline(-1) << "}"; // sdt_sem_offset + s.op->newline() << "if (slotted_p) {"; @@ -4772,15 +4818,14 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) - // PR10655: also handle ENABLED semaphore manipulations here - s.op->newline() << "if (!rc && sups->sdt_sem_address) {"; - s.op->newline(1) << "unsigned short sdt_semaphore;"; // NB: fixed size - s.op->newline() << "sup->sdt_sem_address = relocation + sups->sdt_sem_address;"; - s.op->newline() << "(void) __access_process_vm (tsk, sup->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0);"; - s.op->newline() << "sdt_semaphore ++;"; - s.op->newline() << "#ifdef DEBUG_UPROBES"; - s.op->newline() << "_stp_dbug (__FUNCTION__,__LINE__, \"+semaphore %#x @ %#lx\\n\", sdt_semaphore, sup->sdt_sem_address);"; - s.op->newline() << "#endif"; - - s.op->newline() << "(void) __access_process_vm (tsk, sup->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 1);"; + s.op->newline() << "if (sdt_sem_address[spec_index]) {"; + s.op->newline(1) << "unsigned short sdt_semaphore = 0;"; // NB: fixed size + s.op->newline() << "if ( __access_process_vm (tsk, sdt_sem_address[spec_index], &sdt_semaphore, sizeof (sdt_semaphore), 0)) {"; + s.op->newline(1) << "if (vm_flags & VM_WRITE) {"; + s.op->newline(1) << "sdt_semaphore ++;"; + s.op->newline() << "__access_process_vm (tsk, sdt_sem_address[spec_index], &sdt_semaphore, sizeof (sdt_semaphore), 1);"; + s.op->newline() << "rc = 0;"; + s.op->newline(-1) << "}"; + s.op->newline(-1) << "}"; // sdt_sem_address // XXX: error handling in __access_process_vm! // XXX: need to analyze possibility of race condition + s.op->newline(-1) << "}"; @@ -4788,2 +4833,3 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline(-1) << "}"; + s.op->newline() << "if (rc) {"; // failed to register @@ -4921,3 +4967,3 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "if (register_p)"; - s.op->newline(1) << "return stap_uprobe_change_plus (tsk, 0, TASK_SIZE, stf);"; + s.op->newline(1) << "return stap_uprobe_change_plus (tsk, 0, TASK_SIZE, stf, 0, 0);"; s.op->newline(-1) << "else"; @@ -4934,7 +4980,8 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) // 1 - shared libraries' executable segments load from offset 0 - ld.so convention - s.op->newline() << "if (offset != 0) return 0;"; + // offset != 0 is now allowed so stap_uprobe_change_plus can set a semaphore, + // i.e. a static extern, in a shared object // 2 - the shared library we're interested in s.op->newline() << "if (path == NULL || strcmp (path, stf->pathname)) return 0;"; - // 3 - mapping should be executable - s.op->newline() << "if (!(vm_flags & VM_EXEC)) return 0;"; + // 3 - mapping should be executable or writeable (for semaphore in .so) + s.op->newline() << "if (!((vm_flags & VM_EXEC) || (vm_flags & VM_WRITE))) return 0;"; @@ -4945,3 +4992,3 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) - s.op->newline() << "return stap_uprobe_change_plus (tsk, addr, length, stf);"; + s.op->newline() << "return stap_uprobe_change_plus (tsk, addr, length, stf, offset, vm_flags);"; s.op->newline(-1) << "}"; @@ -4963,2 +5010,3 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) + s.op->assert_0_indent(); @@ -5023,3 +5071,3 @@ uprobe_derived_probe_group::emit_module_exit (systemtap_session& s) // PR10655: decrement that ENABLED semaphore - s.op->newline() << "if (sups->sdt_sem_address != 0) {"; + s.op->newline() << "if (sdt_sem_address[sup->spec_index]) {"; s.op->newline(1) << "unsigned short sdt_semaphore;"; // NB: fixed size @@ -5043,8 +5091,9 @@ uprobe_derived_probe_group::emit_module_exit (systemtap_session& s) s.op->newline() << "if (tsk) {"; // just in case the thing exited while we weren't watching - s.op->newline(1) << "(void) __access_process_vm (tsk, sup->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0);"; - s.op->newline() << "sdt_semaphore --;"; + s.op->newline(1) << "if (__access_process_vm (tsk, sdt_sem_address[sup->spec_index], &sdt_semaphore, sizeof (sdt_semaphore), 0)) {"; + s.op->newline(1) << "sdt_semaphore --;"; s.op->newline() << "#ifdef DEBUG_UPROBES"; - s.op->newline() << "_stp_dbug (__FUNCTION__,__LINE__, \"-semaphore %#x @ %#lx\\n\", sdt_semaphore, sup->sdt_sem_address);"; + s.op->newline() << "_stp_dbug (__FUNCTION__,__LINE__, \"-semaphore %#x @ %#lx\\n\", sdt_semaphore, sdt_sem_address[sup->spec_index]);"; s.op->newline() << "#endif"; - s.op->newline() << "(void) __access_process_vm (tsk, sup->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 1);"; + s.op->newline() << "(void) __access_process_vm (tsk, sdt_sem_address[sup->spec_index], &sdt_semaphore, sizeof (sdt_semaphore), 1);"; + s.op->newline(-1) << "}"; // access_process_vm // XXX: error handling in __access_process_vm!