How to avoid insn beeing scheduled into a delay slot - gcc

I try to patch gcc so that after a fdivd the destination register is
stored to the stack,i.e:
fdivd %f0, %f2, %f4; => becomes
fdivd %f0, %f2, %f4; std %f4, [%fp+...]
I generate the rtl for divdf3 using a (emit_insn,DONE) sequence in a
define_expand pattern (see below).
In the assembler output phase I use a define_insn and write
out "fdivd\t%%1, %%2, %%0; std %%0, %%3" as the expression string.
The code generated seems to be ok. However:
My question:
How can I mark the pattern so, that it will not be sheduled into a
delay slot? How can I specify that the output will be 2 instructions
and hint the scheduler about it?
Is the (set_attr "length" "2") attribute in define_insn divdf3_store
(below) already sufficient?
-- Greetings Konrad
-------------- changed sparc.md -------------------------
;;;;;;;;;;;;;;;;;; handle divdf3 ;;;;;;;;;;;;;;;;
(define_expand "divdf3"
[(parallel [(set (match_operand:DF 0 "register_operand" "=e")
(div:DF (match_operand:DF 1 "register_operand" "e")
(match_operand:DF 2 "register_operand" "e")))
(clobber (match_scratch:SI 3 ""))])]
"TARGET_FPU"
"{
output_divdf3_emit (operands[0], operands[1], operands[2], operands[3]);
DONE;
}")
(define_insn "divdf3_store"
[(set (match_operand:DF 0 "register_operand" "=e")
(div:DF (match_operand:DF 1 "register_operand" "e")
(match_operand:DF 2 "register_operand" "e")))
(clobber (match_operand:DF 3 "memory_operand" "" ))]
"TARGET_FPU && TARGET_STORE_AFTER_DIVSQRT"
{
return output_divdf3 (operands[0], operands[1], operands[2], operands[3]);
}
[(set_attr "type" "fpdivd")
(set_attr "fptype" "double")
(set_attr "length" "2")])
(define_insn "divdf3_nostore"
[(set (match_operand:DF 0 "register_operand" "=e")
(div:DF (match_operand:DF 1 "register_operand" "e")
(match_operand:DF 2 "register_operand" "e")))]
"TARGET_FPU && (!TARGET_STORE_AFTER_DIVSQRT)"
"fdivd\t%1, %2, %0"
[(set_attr "type" "fpdivd")
(set_attr "fptype" "double")])
-------------- changed sparc.c -------------------------
/**************************** handle fdivd ****************************/
char *
output_divdf3 (rtx op0, rtx op1, rtx dest, rtx scratch)
{
static char string[128];
if (debug_patch_divsqrt) {
fprintf(stderr, "debug_patch_divsqrt:\n");
debug_rtx(op0);
debug_rtx(op1);
debug_rtx(dest);
fprintf(stderr, "scratch: 0x%x\n",(int)scratch);
}
sprintf(string,"fdivd\t%%1, %%2, %%0; std %%0, %%3 !!!");
return string;
}
void
output_divdf3_emit (rtx dest, rtx op0, rtx op1, rtx scratch)
{
rtx slot0, div, divsave;
if (debug_patch_divsqrt) {
fprintf(stderr, "output_divdf3_emit:\n");
debug_rtx(op0);
debug_rtx(op1);
debug_rtx(dest);
fprintf(stderr, "scratch: 0x%x\n",(int)scratch);
}
div = gen_rtx_SET (VOIDmode,
dest,
gen_rtx_DIV (DFmode,
op0,
op1));
if (TARGET_STORE_AFTER_DIVSQRT) {
slot0 = assign_stack_local (DFmode, 8, 8);
divsave = gen_rtx_SET (VOIDmode, slot0, dest);
emit_insn(divsave);
emit_insn (gen_rtx_PARALLEL(VOIDmode,
gen_rtvec (2,
div,
gen_rtx_CLOBBER (SImode,
slot0))));
} else {
emit_insn(div);
}
}

I second Laurynas. For such a precise question, gcc#gcc.gnu.org will be very helpful.

Related

ESP32: Can't start Serial Bluetooth after creating FreeRTOS task handlers or vice versa, can't create the task handlers after initializing Bluetooth

Well, I'm just starting with FreeRTOS, tried reading the docs but not getting much help. I'm using:
PlatformIO
ESP32 Dev Module
The task handlers run voice command detection from Atomic14's implementation of Tensorflow's micro-speech example.
If Serial Bluetooth is initialized first, it works but the voice
command detection doesn't as Guru Meditation Errors are thrown.
If the voice command detection task
handlers are created first, Serial Bluetooth fails to start.
The code compiles and uploads to the board with no errors. But when the board restarts, the errors are thrown.
If the task handers are created first, Serial BT throws the error below:
[E][BluetoothSerial.cpp:538] _init_bt(): initialize bluedroid failed
If Serial BT is initialized first, the task handlers throw the error below:
-------> Loaded Voice Prefs!
Created Neral Net
Guru Meditation Error: Core 1 panic'ed (StoreProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x400d62aa PS : 0x00060030 A0 : 0x800d5dbc A1 : 0x3ffdc0e0
A2 : 0x00000000 A3 : 0x3fe00000 A4 : 0x00000140 A5 : 0x00000140
A6 : 0x00000000 A7 : 0x00000001 A8 : 0x800d62aa A9 : 0x3ffdc0d0
A10 : 0x37ca20bd A11 : 0x3ef94417 A12 : 0x21700000 A13 : 0x37ca20bd
A14 : 0x00000000 A15 : 0x00000000 SAR : 0x0000001d EXCCAUSE: 0x0000001d
EXCVADDR: 0x00000000 LBEG : 0x400029ac LEND : 0x400029cb LCOUNT : 0x00000000
ELF file SHA256: 0000000000000000
Backtrace: 0x400d62aa:0x3ffdc0e0 0x400d5db9:0x3ffdc110 0x400d1c52:0x3ffdc140 0x400d2f61:0x3ffdc160 0x400dafee:0x3ffdc1b0 0x40090a72:0x3ffdc1d0
Rebooting...
␇P�␌��
�ڔ␙␙␒�␀!�-------> Loaded Voice Prefs!
Created Neral Net
Guru Meditation Error: Core 1 panic'ed (StoreProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x400d62aa PS : 0x00060030 A0 : 0x800d5dbc A1 : 0x3ffdc0e0
A2 : 0x00000000 A3 : 0x3fe00000 A4 : 0x00000140 A5 : 0x00000140
A6 : 0x00000000 A7 : 0x00000001 A8 : 0x800d62aa A9 : 0x3ffdc0d0
A10 : 0x37ca20bd A11 : 0x3ef94417 A12 : 0x21700000 A13 : 0x37ca20bd
A14 : 0x00000000 A15 : 0x00000000 SAR : 0x0000001d EXCCAUSE: 0x0000001d
EXCVADDR: 0x00000000 LBEG : 0x400029ac LEND : 0x400029cb LCOUNT : 0x00000000
ELF file SHA256: 0000000000000000
Backtrace: 0x400d62aa:0x3ffdc0e0 0x400d5db9:0x3ffdc110 0x400d1c52:0x3ffdc140 0x400d2f61:0x3ffdc160 0x400dafee:0x3ffdc1b0 0x40090a72:0x3ffdc1d0
Rebooting...
Main.cpp Setup
#include <WiFi.h>
#include <Ticker.h>
#include <FastLED.h>
#include <IRremote.h>
#include <Preferences.h>
#include "BluetoothSerial.h"
#include <driver/i2s.h>
#include <esp_task_wdt.h>
#include "I2SMicSampler.h"
#include "config.h"
#include "CommandDetector.h"
#include "CommandProcessor.h"
#include "patterns.h"
#include "switchcase.h"
#include "voice.h"
#include "remote.h"
#define NUM_LEDS 75
#define DATA_PIN 16
// FASTLED no of leds on the strip
CRGB led[NUM_LEDS];
// IR init. Don't connect to spi pin
IRrecv irrecv(4);
// decode_results results; // IR init
// Prefs instance
Preferences preferences;
// This ticker will check for command changes in the backgound
// from BT, IR and Voice
Ticker updater;
// Bluetooth Serial object
BluetoothSerial SerialBT;
// Handle received and sent commands
String command = "p1201";
String command2 = "p1101";
String brightness = "b255";
bool useVoice = true;
bool useColorsList = true;
void receiveIRCode()
{
decode_results results;
// IR reciever code goes here
if (irrecv.decode(&results))
{
irrecv.resume(); // Receive the next value
Serial.println(results.value, HEX);
for (int c = 0; c < 17; c++)
{
if (IRCodes[c] == results.value)
{
switchIR(results.value);
break;
}
}
}
}
// If new color or pattern command is received, make the change
void makeChange()
{
Serial.println("--------> Making Change");
Serial.println(command2);
//------- Change Color
if ((command.startsWith("0", 0)) & (command.length() == 8))
{
long color = strtol(command.c_str(), NULL, 16);
hexToRGB(command);
fill_solid(led, NUM_LEDS, color);
FastLED.show();
}
//------- Change Pattern
if ((command.startsWith("p", 0)) & (command.length() == 5))
{
switchPatterns(command.substring(1).toInt());
}
//------- Change Voice Assignments
if (command2.startsWith("v"))
{
changeVoiceAssignment();
}
//------- Change Use Voice Status
if (command2.startsWith("u"))
{
useVoiceStatus();
}
}
// Check if a new command has been received
void checkChange()
{
// IR reciever code goes here
receiveIRCode();
// Voice detection code goes here
if (useVoice)
{
Serial.println("Checking voice...");
}
// BT control code goes here
if (SerialBT.available())
{
command2 = SerialBT.readStringUntil('\n');
if (!command2.equals(command))
{
Serial.println("-------->CHANGES! New command is: " + command2);
}
}
}
// Change brightness
void changeBrightness()
{
brightness = command2;
FastLED.setBrightness(brightness.substring(1).toInt());
FastLED.show();
Serial.println("-------> Set new brightness");
command2 = command;
preferences.begin("esp", false);
preferences.putString("bright", brightness);
preferences.end();
}
// Change brightness
void changeColor(int c)
{
if (c == 1)
fill_solid(led, NUM_LEDS, 0xff0000);
if (c == 2)
fill_solid(led, NUM_LEDS, 0x00ff00);
if (c == 3)
fill_solid(led, NUM_LEDS, 0x0000ff);
if (c == 4)
fill_solid(led, NUM_LEDS, 0xffff00);
FastLED.show();
}
// i2s config for reading from both channels of I2S
i2s_config_t i2sMemsConfigBothChannels = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = 16000,
.bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
.channel_format = I2S_MIC_CHANNEL,
.communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S),
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 4,
.dma_buf_len = 64,
.use_apll = false,
.tx_desc_auto_clear = false,
.fixed_mclk = 0};
// i2s microphone pins
i2s_pin_config_t i2s_mic_pins = {
.bck_io_num = I2S_MIC_SERIAL_CLOCK,
.ws_io_num = I2S_MIC_LEFT_RIGHT_CLOCK,
.data_out_num = I2S_PIN_NO_CHANGE,
.data_in_num = I2S_MIC_SERIAL_DATA};
// This task does all the heavy lifting for our application
void applicationTask(void *param)
{
disableCore0WDT();
CommandDetector *commandDetector = static_cast<CommandDetector *>(param);
const TickType_t xMaxBlockTime = pdMS_TO_TICKS(100);
while (true)
{
// wait for some audio samples to arrive
uint32_t ulNotificationValue = ulTaskNotifyTake(pdTRUE, xMaxBlockTime);
if (ulNotificationValue > 0)
{
commandDetector->run();
}
}
}
void setup()
{
Serial.begin(9600);
// Getting Preferences
preferences.begin("esp", false);
command2 = preferences.getString("command2", "p1101");
brightness = preferences.getString("bright", "b255");
useVoice = preferences.getBool("useVoice", true);
useColorsList = preferences.getBool("useColorsList", true);
hexToRGB(preferences.getString("color", "0xffffff"));
loadVoiceAssignments();
preferences.end();
// Serial.println("Command2: " + command2);
// Fastled initialization and settings
FastLED.addLeds<NEOPIXEL, DATA_PIN>(led, NUM_LEDS);
FastLED.setBrightness(brightness.substring(1).toInt());
irrecv.enableIRIn(); // Start the IR receiver
SerialBT.begin("Bonga Lamp A01");
// make sure we don't get killed for our long running tasks
esp_task_wdt_init(10, false);
// Direct i2s input from INMP441
I2SSampler *i2s_sampler = new I2SMicSampler(i2s_mic_pins, false);
// the command processor
CommandProcessor *command_processor = new CommandProcessor();
// create our application
CommandDetector *commandDetector = new CommandDetector(i2s_sampler, command_processor);
// set up the i2s sample writer task
TaskHandle_t applicationTaskHandle;
xTaskCreatePinnedToCore(applicationTask, "Command Detect", 8192, commandDetector, 1, &applicationTaskHandle, 0);
Serial.println("---- 1");
Serial.println("--------");
// portENABLE_INTERRUPTS();
// start sampling from i2s device - use I2S_NUM_0 as that's the one that supports the internal ADC
i2s_sampler->start(I2S_NUM_0, i2sMemsConfigBothChannels, applicationTaskHandle);
Serial.println("---- 2");
Serial.println("--------");
// Bluetooth device name
// Serial.println("Bluetooth Ready for pairing!");
// Serial.println("---- 3");
// Serial.println("--------");
updater.attach_ms(100, checkChange);
Serial.println("---- 4");
Serial.println("--------");
}
void loop()
{
// If command received is different from previous command, change color or pattern
if (!command2.equals(command) & !command2.startsWith("b"))
{
command = command2;
preferences.begin("esp", false);
preferences.putString("command2", command2);
if (command2.startsWith("0", 0))
{
preferences.putString("color", command2);
preferences.end();
}
preferences.end();
makeChange();
}
// If it is a brightness change command
else if (command2.startsWith("b"))
{
changeBrightness();
}
}
Please help if you can. Thank you.

How to get physical page in Solaris 11

I am using mdb on Solaris 11. I have opened a file by using " tail -f file_name" command in another ssh session. I got the pid of tail command and Vnode of the file opened by tail command. After getting the Vnode, I fired "walk page" on this file. Unfortunately, I am not getting any pages in walk. How to get Virtual Pages and Physical pages?
I have done following.
1) Opened the file with 'tail -f'.
2) Get the pid in mdb. Get the Vnode of the opened file.
3) Get the page_t from Vnode_t of the opened file.
4) Left shift to the page number with 0xD, it will give pp2pa effect.
Here are the dcmds in mdb.
> ::pgrep tail
S PID PPID PGID SID UID FLAGS ADDR NAME
R 2889 2882 2889 2850 0 0x4a004000 0000060013f29890 tail
> 0000060013f29890::pfiles
FD TYPE VNODE INFO
0 REG 00000600162f6740 /export/home/chaitanya/OpenSolaris/README.opensolaris
1 CHR 000006001a290400 /devices/pseudo/pts#0:2
2 CHR 000006001a290400 /devices/pseudo/pts#0:2
> 00000600162f6740::walk page
70004781480
700040b0400
> 70004781480::print -at page_t
{
70004781480 u_offset_t p_offset = 0x2000
70004781488 struct vnode *p_vnode = 0x600162f6740
70004781490 selock_t p_selock = 0
70004781494 uint_t p_vpmref = 0x11d9d
70004781498 struct page *p_hash = 0x70002f79b00
700047814a0 struct page *p_vpnext = 0x700040b0400
700047814a8 struct page *p_vpprev = 0x700040b0400
700047814b0 struct page *p_next = 0x70004781480
700047814b8 struct page *p_prev = 0x70004781480
700047814c0 ushort_t p_lckcnt = 0
700047814c2 ushort_t p_cowcnt = 0
700047814c4 kcondvar_t p_cv = {
700047814c4 ushort_t _opaque = 0
}
700047814c6 kcondvar_t p_io_cv = {
700047814c6 ushort_t _opaque = 0
}
700047814c8 uchar_t p_iolock_state = 0
700047814c9 volatile uchar_t p_szc = 0
700047814ca uchar_t p_fsdata = 0
700047814cb uchar_t p_state = 0x40
700047814cc uchar_t p_nrm = 0x2
700047814cd uchar_t p_vcolor = 0x2
700047814ce uchar_t p_index = 0
700047814cf uchar_t p_toxic = 0
700047814d0 void *p_mapping = 0
700047814d8 pfn_t p_pagenum = 0x80f029
700047814e0 uint_t p_share = 0
700047814e4 uint_t p_sharepad = 0
700047814e8 uint_t p_slckcnt = 0
700047814ec uint_t p_kpmref = 0
700047814f0 struct kpme *p_kpmelist = 0
700047814f8 kmutex_t p_ilock = {
700047814f8 void *[1] _opaque = [ 0 ]
}
}
Left shift to the page number 0x80f029 with 0xD, it will give pp2pa
> 101E052000,100::dump -p
\/ 1 2 3 4 5 6 7 8 9 a b c d e f v123456789abcdef
101e052000: 75742069 742e2020 4e6f7220 646f2079 ut it. Nor do y
101e052010: 6f752068 61766520 746f206b 65657020 ou have to keep
101e052020: 7468650a 20202020 206e616d 65206f70 the. name op
101e052030: 656e736f 6c617269 732e7368 2c206275 ensolaris.sh, bu
101e052040: 74207468 61742773 20746865 206e616d t that's the nam
101e052050: 65207765 276c6c20 75736520 696e2074 e we'll use in t
101e052060: 68657365 206e6f74 65732e0a 0a202020 hese notes...
101e052070: 20205468 656e206d 616b6520 74686520 Then make the
101e052080: 666f6c6c 6f77696e 67206368 616e6765 following change
101e052090: 7320696e 20796f75 72206f70 656e736f s in your openso
101e0520a0: 6c617269 732e7368 3a0a0a20 20202d20 laris.sh:.. -
101e0520b0: 6368616e 67652047 41544520 746f2074 change GATE to t
101e0520c0: 6865206e 616d6520 6f662074 68652074 he name of the t
101e0520d0: 6f702d6c 6576656c 20646972 6563746f op-level directo
101e0520e0: 72792028 652e672e 2c0a2020 20202022 ry (e.g.,. "
101e0520f0: 74657374 77732229 2e0a0a20 20202d20 testws")... -

ENC28J60 returning wrong (unexpected) values

I'm trying to create my own library for the ENC28J60. Yes, I know that there are several ready to use libraries out there, but I like to do thing from scratch, so I understand what is going on, how it works.
So, I'm only at the beging and already found someting that I don't understand.
My first test was to send the RCR command to read BANK0. I've recived mixed results.
Over UART(HyperTerminal) I'm getting the following results back:
USART Ready
SPI Ready
1 RCR-ERDPTL Send: 0 "(sending RCR|ERDPTL = 0 over SPI)"
0 11111010 11111010 OK
1 101 101 OK
2 0 0 OK
3 0 0 OK
4 0 0 OK
5 0 0 OK
6 0 0 OK
7 0 0 OK
8 1000 11111010 ERROR
9 101 101 OK
10 11111111 11111111 OK
11 11111 11111 OK
12 110001 11111010 ERROR
13 110011 101 ERROR
14 0 0 OK
15 0 0 OK
The first column is the byte number or the number of the register of BANK0,
The second column is the value that I'm getting from the ENC chip(according to the datasheet),
The third is tha value I should get,
And the fouth is just a simple check to find a mismatch.
As you can see there are 3 values that do not correspond with the datasheet.
Why?
My code is the following:
#include <define.h>
#include <ENC28J60.h>
#define ENC28J60 PB3
#define ENC28J61 PB4
#define DUMMY 0x00
unsigned char i, data, data0[] = {}, data1[] = {}, data2[] = {},
data3[16] = {0b11111010, 0b00000101, 0,0,0,0,0,0,0b11111010,0b00000101,255,0b00011111,0b11111010,0b00000101,0,0};
void ENC28J60_CS(void) // ENC28J60 Select
{
SPI_PORT &= ~(1<<ENC28J60);
}
void ENC28J60_DS(void) // ENC28J60 DeSelect
{
SPI_PORT |= (1<<ENC28J60);
}
void ENC28J61_CS(void) // ENC28J60 Select
{
SPI_PORT &= ~(1<<ENC28J61);
}
void ENC28J61_DS(void) // ENC28J60 DeSelect
{
SPI_PORT |= (1<<ENC28J61);
}
void ENC28J60_SRC(void) // System Reset Command (Soft Reset)
{
ENC28J60_CS(); // Enable
SPIWR(0xFF);
ENC28J60_DS(); // Disable
_delay_ms(50);
}
int main(void)
{
_delay_ms(3000);
USART0_Init(12);
USART0_TX_String("USART Ready");
USART0_TXD(10);
USART0_TXD(13);
SPI_Init();
PORTB ^= 1<<PINB0;
USART0_TX_String("SPI Ready");
USART0_TXD(10);
USART0_TXD(13);
ENC28J60_DS();
ENC28J61_DS();
_delay_ms(250);
ENC28J60_SRC();
ENC28J61_CS(); // Enable
SPIWR(0xFF);
ENC28J61_DS(); // Disable
_delay_ms(250);
ENC28J60_CS();
SPIWR(RCR|ERDPTL);
PORTB ^= 1<<PINB0;
USART0_TX_String("1 RCR-ERDPTL Send: ");
itoa(RCR|ERDPTL, StringA, 10);
USART0_TX_String(StringA);
USART0_TXD(10);
USART0_TXD(13);
data = SPIWRD(0xFF);
for(i = 0;i<15;i++)
{
data0[i] = SPIWRD(0xFF);
}
ENC28J60_DS();
for(i = 0;i<16;i++)
{
PORTB ^= 1<<PINB0;
itoa(i, StringA, 10);
USART0_TX_String(StringA);
USART0_TXD(9);
itoa(data0[i], StringA, 2);
USART0_TX_String(StringA);
USART0_TXD(9);
USART0_TXD(9);
itoa(data3[i], StringA, 2);
USART0_TX_String(StringA);
USART0_TXD(9);
if(data0[i] == data3[i])
{
USART0_TX_String("OK");
}
else
{
USART0_TX_String("ERROR");
}
USART0_TXD(10);
USART0_TXD(13);
}
PORTB |= 1<<PINB0;
while(1)
{
}
}
There is another matter that gives me headaches.
I ha to add an extra SPI junk transmission on line 71, because if I had not done this, I would get the first result twice and so the rest would get out of line.
According to the datasheet(section 4.2.1) only by reading from the MAC or MII registers should I get a dummy byte.
What's up whit that?
I'm using AVR ATMega1284P with WinAVR.
It seems the problem is yet again in the code.
In the declaration of my variables(data0 to 2) I have not set the size of them:
unsigned char i, data, data0[] = {}, data1[] = {}, data2[] = {},
data3[16] = {0b11111010, 0b00000101,0,0,0,0,0,0,0b11111010,0b00000101,
255,0b00011111,0b11111010,0b00000101,0,0};
I should have done this:
unsigned char i, data, data0[16] = {}, data1[16] = {}, data2[16] = {},
data3[16] = {0b11111010, 0b00000101, 0,0,0,0,0,0,0b11111010,0b00000101,
255,0b00011111,0b11111010,0b00000101,0,0};

Exporting information from kernel space to user space via sysfs

I wrote a kernel module memory leak detector that works by adding information about possible memory leaks to a list. I want to be able to loop through the list and write the information the a file for the user, this would be easy to do in user space with the code below but how world I use sysfs to export that information from kernel space to user so that the user can read it in a file?
/*
* writes a memory leak summary to a file
*/
void mem_leak_summary(void)
{
unsigned int i;
MEM_PROFILER_LIST * mem_output;
FILE * fp_write = fopen (SUMMARY_FILE, "wt");
char info[1024];
if(fp_write != NULL)
{
fwrite(info, (strlen(info) + 1) , 1, fp_write);
sprintf(info, "%s\n", "-----------------------------------");
fwrite(info, (strlen(info) + 1) , 1, fp_write);
for(mem_output= ptr_start; mem_output!= NULL; mem_output= mem_output->next)
{
sprintf(info, "address : %d\n", leak_info->mem_output.address);
fwrite(info, (strlen(info) + 1) , 1, fp_write);
sprintf(info, "size : %d bytes\n", leak_info->mem_output.size);
fwrite(info, (strlen(info) + 1) , 1, fp_write);
sprintf(info, "line : %d\n", leak_info->mem_output.line);
fwrite(info, (strlen(info) + 1) , 1, fp_write);
sprintf(info, "%s\n", "-----------------------------------");
fwrite(info, (strlen(info) + 1) , 1, fp_write);
}
}
clear();
}
I can't say for /sys, but for /proc it's rather straightforward to do such things. This site shows how to create a /proc entry which can be cat'd.

How to get COM object for embedded IE browser?

How to translate this function from AutoIt's IE.au3 UDF to Ruby? Intention is to use Watir with an Internet Explorer browser (embedded in another application).
The AutoIt function works fine but I prefer Watir (which is Ruby). I can get the handle of the embedded browser using ControlGetHandle(), which is not available from the AutoIt dll.
Below is the function to translate (also 2 others which I don't need).
;===============================================================================
;
; Function Name: __IEControlGetObjFromHWND()
; Description: Returns a COM Object Window reference to an embebedded Webbrowser control
; Parameter(s): $hWin - HWND of a Internet Explorer_Server1 control obtained for example:
; $hwnd = ControlGetHandle("MyApp","","Internet Explorer_Server1")
; Requirement(s): Windows XP, Windows 2003 or higher.
; Windows 2000; Windows 98; Windows ME; Windows NT may install the
; Microsoft Active Accessibility 2.0 Redistributable:
; http://www.microsoft.com/downloads/details.aspx?FamilyId=9B14F6E1-888A-4F1D-B1A1-DA08EE4077DF&displaylang=en
; Return Value(s): On Success - Returns DOM Window object
; On Failure - 0 and sets #ERROR = 1
; Author(s): Larry with thanks to Valik
;
;===============================================================================
Func __IEControlGetObjFromHWND(ByRef $hWin)
DllCall("ole32.dll", "int", "CoInitialize", "ptr", 0)
Local Const $WM_HTML_GETOBJECT = __IERegisterWindowMessage("WM_HTML_GETOBJECT")
Local Const $SMTO_ABORTIFHUNG = 0x0002
Local $lResult, $typUUID, $aRet, $oIE
MsgBox(0, "msg", $WM_HTML_GETOBJECT)
__IESendMessageTimeout($hWin, $WM_HTML_GETOBJECT, 0, 0, $SMTO_ABORTIFHUNG, 1000, $lResult)
$typUUID = DllStructCreate("int;short;short;byte[8]")
DllStructSetData($typUUID, 1, 0x626FC520)
DllStructSetData($typUUID, 2, 0xA41E)
DllStructSetData($typUUID, 3, 0x11CF)
DllStructSetData($typUUID, 4, 0xA7, 1)
DllStructSetData($typUUID, 4, 0x31, 2)
DllStructSetData($typUUID, 4, 0x0, 3)
DllStructSetData($typUUID, 4, 0xA0, 4)
DllStructSetData($typUUID, 4, 0xC9, 5)
DllStructSetData($typUUID, 4, 0x8, 6)
DllStructSetData($typUUID, 4, 0x26, 7)
DllStructSetData($typUUID, 4, 0x37, 8)
MsgBox(0, "lResult", $lResult)
$aRet = DllCall("oleacc.dll", "long", "ObjectFromLresult", "lresult", $lResult, "ptr", DllStructGetPtr($typUUID), _
"wparam", 0, "idispatch*", 0)
MsgBox(0, "aRet4", $aRet[4])
If IsObj($aRet[4]) Then
$oIE = $aRet[4] .Script()
; $oIE is now a valid IDispatch object
Return $oIE.Document.parentwindow
Else
SetError(1)
Return 0
EndIf
EndFunc ;==>__IEControlGetObjFromHWND
;===============================================================================
; Function Name: __IERegisterWindowMessage()
; Description: Required by __IEControlGetObjFromHWND()
; Author(s): Larry with thanks to Valik
;===============================================================================
Func __IERegisterWindowMessage($sMsg)
Local $aRet = DllCall("user32.dll", "int", "RegisterWindowMessage", "str", $sMsg)
If #error Then Return SetError(#error, #extended, 0)
Return $aRet[0]
EndFunc ;==>__IERegisterWindowMessage
;===============================================================================
; Function Name: __IESendMessageTimeout()
; Description: Required by __IEControlGetObjFromHWND()
; Author(s): Larry with thanks to Valik
;===============================================================================
Func __IESendMessageTimeout($hWnd, $msg, $wParam, $lParam, $nFlags, $nTimeout, ByRef $vOut, $r = 0, $t1 = "int", $t2 = "int")
Local $aRet
$aRet = DllCall("user32.dll", "long", "SendMessageTimeout", "hwnd", $hWnd, "int", $msg, $t1, $wParam, _
$t2, $lParam, "int", $nFlags, "int", $nTimeout, "int*", "")
If #error Then
$vOut = 0
Return SetError(#error, #extended, 0)
EndIf
$vOut = $aRet[7]
If $r >= 0 And $r <= 4 Then Return $aRet[$r]
Return $aRet
EndFunc ;==>__IESendMessageTimeout
My code so far:
def get_control_from_hwnd(hnd)
Win32API.new("ole32", "CoInitialize", ['P'] , 'I').call(0)
reg_msg = Win32API.new("user32", "RegisterWindowMessage", ['P'] ,'I').call("WM_HTML_GETOBJECT")
puts "msg: " + reg_msg.to_s
result=" "*16
aInt = [0xA7, 0x31, 0x0, 0xA0, 0xC9, 0x8, 0x26, 0x37].pack 'I*'
a = [0x626FC520, 0xA41E, 0x11CF, aInt].pack 'IIIP'
sendMessagetimeout = Win32API.new("user32", "SendMessageTimeout", ['L','I','I','I','I','I','P'] , 'L')
sendMessagetimeout.call(hnd.hex, reg_msg, 0, 0, SMTO_ABORTIFHUNG, 1000, result)
puts "result unpacked: " + result.unpack("L").to_s #i can confirm this is the same as the lResult from the autoit functioin
idisp=0
#the problem is likely either here or the next line afterwards
oIE = Win32API.new("oleacc", "ObjectFromLresult", ['P','P','I','P'] , 'L')
oIE.call(result, a, 0, idisp)
puts "idisp: " + idisp.to_s
# returning zero
puts idisp.unpack("L")
end
Can't believe we are doing the same, albeit I'm trying to do it in Perl. I dunno Ruby but looking at the script, it almost looks like similar to Perl. Take a look at this thread at autoIt, where I am still trying to tackle the issue http://www.autoitscript.com/forum/index.php?showtopic=104894. But I think I might have gotten the idisp though. Two changes:
1) The way I am packing the struct is a bit different. My $iid looks like this:
pack('LSSC8',0x626FC520,0xA41E,0x11CF,0xA7,0x31,0x00,0xA0,0xC9,0x08,0x26,0x37). So in Ruby I guess it'd be [0x626FC520,0xA41E,0x11CF,0xA7,0x31,0x00,0xA0,0xC9,0x08,0x26,0x37].pack 'LSSC8'? I dunno the right syntax, but you get the idea.
2) I unpack the "result" from SendMessageTimeout & then pass it to ObjectFromLresult. If I pass the result directly, I get 0 as you were getting it.
But that is as far as I've gone.

Resources