Formatting a byte array as a C-89 initializer expression in LLDB - c

I have an array which is initialized with a regular C89 initializer:
uint8_t data[] = {0x05,0x48,0x45,0x4c,0x4c,0x4f,0x01,0x00 ... }
When I print this array in lldb, I get this monstrosity:
(lldb) p data
(uint8_t [200]) $0 = {
[0] = '\x05'
[1] = 'H'
[2] = 'E'
[3] = 'L'
[4] = 'L'
[5] = 'O'
[6] = '\x01'
...
I'm trying to coerce lldb's output into the original C89 syntax so I can simply paste contents of the array from lldb back into my code (e.g. so I can write unit tests that use arrays I catch during debugging).
How can I tell lldb to format its output to look like a normal C89 initializer?

You can write a python summary printer to print the contents of the array in the correct format but the SBValue object that is passed in to the python won't have the name of the variable available.
(lldb) type summ add uint8_t[] -P
[...]
print '{',
for i in xrange(0, valobj.GetNumChildren()):
print '0x%02x' % valobj.GetChildAtIndex(i).GetValueAsUnsigned(),
if (i != valobj.GetNumChildren() - 1):
print ',',
print '};'
DONE
(lldb) p data
{ 0x05 , 0x48 , 0x45 , 0x4c , 0x4c , 0x4f , 0x01 , 0x00 };
(uint8_t [8]) $1 = {
[0] = 0x05
[1] = 0x48
[2] = 0x45
[3] = 0x4c
[4] = 0x4c
[5] = 0x4f
[6] = 0x01
[7] = 0x00
}

Use type format add -f x uint8_t to get nearly what you want:
(lldb) p data
(uint8_t [8]) $4 = {
[0] = 0x05
[1] = 0x48
[2] = 0x45
[3] = 0x4c
[4] = 0x4c
[5] = 0x4f
[6] = 0x01
[7] = 0x00
}
You just need to add "," after each line to have a source code line (for the array) that will compile. If this is too bothersome, I suspect you will have to write something in python.
To see what other formats (besides "x" used above, which stands for hex), use help format.
EDIT: following Brandin's hint above, it turns out you can format your array in the way that you want by additionally using
(lldb) type summary add --summary-string "," uint8_t
This will add a "," after each line:
(lldb) p data
(uint8_t [8]) $3 = {
[0] = 0x05 ,
[1] = 0x48 ,
[2] = 0x45 ,
[3] = 0x4c ,
[4] = 0x4c ,
[5] = 0x4f ,
[6] = 0x01 ,
[7] = 0x00 ,
}
which you can copy & paste 1:1 into your source code (final semicolon needs to be added of course).

Another quick way to get pretty much the same thing Jason showed without having to know any Python is to use the -c and -O options to type summary add, like:
(lldb) type summary add -c -O uint8_t[]
(lldb) expr array
(uint8_t [8]) $2 = ('\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\a', '\b')
This is generally useful if you have some type that you just want to view all the elements of a structure or array "flat" like this rather than in turned out form.

Related

Converting bytes to string in clojure

I am converting a byte array in clojure into a string and I am facing a weird problem and I don't know the reason why.
The byte array is defined as
(def a (byte-array (byte 72) (byte 105)))
when I convert it into a vector it shows
(vec a)
output: (105, 105, 105, ......68 times ...., 105)
The output is an array of 105 with 72 elements. Why is it so? I am trying to convert a byte array into a string and using
(String. (byte-array (byte 72) (byte 105)))
yields 72 i's. On the other hand when I do
(map char [(byte 72) (byte 105)])
I get the output H and I. That's why I am trying to convert the byte array into a vector. If there is an alternate way of doing it please let me know.
You are calling the two-arity version and therefor your first argument
sets the size of the array to be created and your second argument is
no sequence so it is considered the init-val; see:
user=> (doc byte-array)
-------------------------
clojure.core/byte-array
([size-or-seq] [size init-val-or-seq])
Creates an array of bytes
Also the initial values are taken from a sequence (as the argument name
suggests). So you can do:
user=> (String. (byte-array [(byte 72) (byte 105)]))
"Hi"
#cfrick has already answered how to properly construct a byte array in Clojure.
As a convenience, there are many string and character functions available in the Tupelo library that may be useful. These work in both Clojure and ClojureScript, which have different notions of what a "String" is. See the following:
char->codepoint and friends
functions in the tupelo.chars namespace
the tupelo.string namespace
The following code shows some of the ways you can manipulate values of type java.lang.String, java.lang.Character, Byte, Long, and Java byte array:
(ns tst.demo.core
(:use tupelo.test)
(:require
[cambium.core :as log]
[clojure.string :as str]
[tupelo.core :as t] ))
(dotest
(let [chars-vec (vec "Hi") ; a vector of Character vals
byte-vec (mapv byte chars-vec) ; a vector of Byte vals
long-vec (mapv long chars-vec) ; a vector of Long vals
; Any sequence of numeric values is acceptable to the `byte-array` function.
; The function `tupelo.core/char->codepoint` works in both CLJ and CLJS
ba-nums (byte-array (mapv t/char->codepoint chars-vec))
ba-longs (byte-array long-vec)
; a sequence of Characters can be made into a String in 2 ways
str-0 (apply str chars-vec)
str-1 (str/join chars-vec)
; Whether we have a vector or a byte-array, the values must be converted into
; a sequence of Characters before using `(apply str ...)` of `(str/join ...)`
; to construct a String object.
str-2 (str/join (mapv char byte-vec))
str-3 (str/join (mapv t/codepoint->char long-vec))
str-4 (str/join (mapv char ba-nums))
str-5 (str/join (mapv t/codepoint->char ba-longs))]
print the results:
(disp-types chars-vec)
(disp-types byte-vec)
(disp-types long-vec)
(disp-types ba-nums)
(disp-types ba-longs)
(println "result type: " (type str-0))
All of the above produce the same result "Hi"
(is= "Hi"
str-0
str-1
str-2
str-3
str-4
str-5)))
with result
-------------------------------
Clojure 1.10.1 Java 13
-------------------------------
Testing tst.demo.core
chars-vec type: clojure.lang.PersistentVector value: [H i] content types: [java.lang.Character java.lang.Character]
byte-vec type: clojure.lang.PersistentVector value: [72 105] content types: [java.lang.Byte java.lang.Byte]
long-vec type: clojure.lang.PersistentVector value: [72 105] content types: [java.lang.Long java.lang.Long]
ba-nums type: [B value: #object[[B 0x24a2bb25 [B#24a2bb25] content types: [java.lang.Byte java.lang.Byte]
ba-longs type: [B value: #object[[B 0x2434f548 [B#2434f548] content types: [java.lang.Byte java.lang.Byte]
result type: java.lang.String
Ran 2 tests containing 1 assertions.
0 failures, 0 errors.
And all of the results are of type java.lang.String.
For completeness, here is the display code:
(defn disp-types-impl
[item]
`(do
(println '~item " type: " (type ~item) " value: " ~item
" content types: " (mapv type ~item))))
(defmacro disp-types
[item]
(disp-types-impl item))

lldb: Displaying array as hex

In lldb is it possible to display a uint8_t array of bytes in a concatenated hex?
For instance the default behaviour for displaying the uint256 type described here is
{
[14] = '['
[15] = '\xbf'
[16] = '('
[17] = '\xc3'
[18] = 'O'
[19] = ':'
[20] = '^'
[21] = '3'
[22] = '*'
[23] = '\x1f'
[24] = '\xc7'
[25] = '\xb2'
[26] = '\xb7'
[27] = '<'
[28] = '\xf1'
[29] = '\x88'
[30] = '\x91'
[31] = '\x0f'
}
by running type summary add --summary-string "${var.data[0-31]%x}" uint256 I can display it like this:
[0x06,0x22,0x6e,0x46,0x11,0x1a,0x0b,0x59,0xca,0xaf,0x12,0x60,0x43,0xeb,0x5b,0xbf,0x28,0xc3,0x4f,0x3a,0x5e,0x33,0x2a,0x1f,0xc7,0xb2,0xb7,0x3c,0xf1,0x88,0x91,0x0f]
but I wanted something like this:
0x06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f
I can't think of a way to do this with the summary string formatters. We do some special purpose magic like this for char[] but that's behind the %s specifier which you don't want.
However, it is fairly easy to write a python summary to do this. Here's a simple example for the type uint8_t [32]:
def unvector_32 (valobj,internal_dict):
str = "0x"
for i in range(0,31):
str += ("%x"%(valobj.GetChildAtIndex(i).GetValueAsUnsigned())).zfill(2)
return str
def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand('type category define -e my_formatters')
debugger.HandleCommand('type summary add -w my_formatters -F %s.unvector_32 "uint8_t [32]" -v'%(__name__))
Put that in a .py file somewhere (I put all these in ~/.lldb) and do:
(lldb) com scr imp ~/.lldb/my_formatters.py
either in your lldb session or in your ~/.lldbinit. Then you will see:
(lldb) fr v data
(uint8_t [32]) data = 0x01020304050600000000000000000000000000000000000000000000000000
(lldb)
I think that's roughly the output you wanted. To apply this to the uint256 class you can change the match type to "uint256" when you add the summary, and have the summary function first get the data member using GetChildMemberWithName("data") then print the individual vector elements. You could also use a regex match against uint([0-9]+) and then get the number of elements in data with the GetNumChildren call if you want the formatter to be more general...
BTW, I find it handy to put all my formatters in a category so I can list them easily (type summary list -w my_formatters) and turn them all off easily if I've messed something up...
More on the SB API's is here:
http://lldb.llvm.org/python_reference/index.html
You can change formate of lldb debugger to another format
type format add -f bytes uint8_t
Bytes format to use
uiint8_t type to apply format on
For more details Link :- https://lldb.llvm.org/use/variable.html

Merging two index into one index in QByteArray in QT

I have a QByteArray which contains data like below:
[0] --> A
[1] --> B
[2] --> C
[3] --> D
I want to do it like below:
[0] --> AB
[1] --> CD
Is it possible. How can I do it. Thanks
There are many ways of doing this. You can't directly just use the QByteArray to achieve what you want as each index only stores one byte.
One solution is to let each index in a vector correspond to a QByteArray (including the merge):
QByteArray byteArray("ABCDEFG");
QVector<QByteArray> vectorByteArray;
for (auto i = 0; i < byteArray.size(); i += 2) {
vectorByteArray << QByteArray(byteArray.constData() + i, (i + 1 == byteArray.size()) ? 1 : 2);
}
for (auto & element : vectorByteArray) {
qDebug() << element.constData();
}

Convert a cell array of cells to cell arrays of doubles

Let's say, that i have a cell array of cells containing only numeric values. Its name is Q.
Q = { {[0] [1] [0] [238]} }
Q{1}
ans =
[0] [1] [0] [238]
What i would like to do, is to combine all these 4 cells into just one.
In that case, it would be something like the one below:
Q{1}
ans =
0 1 0 238
Any help would be really appreciated.
You have a double-nested cell array:
Q = { {[0] [1] [0] [238]} }
and you need comma-separated lists to transform it into an array. I assume you have multiple cell arrays within Q, so you can use cellfun:
out = cellfun(#(x) [x{:}], Q,'uni',0)
and you get
Q{1} =
[0] [1] [0] [238]
out{1} =
0 1 0 238
For one element this is equivalent to:
Q{1} = [Q{1}{:}]
as the x in the cellfun operation is equivalent to Q{i} where i is the running variable.
But if you you just have this one array in your cell array, consider:
out = cell2mat(Q{:})
as you don't need it to be a cell array at all.
Try doing this:
Q{1} = [Q{1}{:}]

ProC compile on 10g and running on 11g

I compiled a pro*c source with oracle 10g and run the application where 11g is installed. Application gives core dump. I get the following trace from DBX debugging:
(dbx) where
current thread: t#1
[1] _smalloc(0x30, 0x0, 0x1dad44, 0xffffffff7b56350c, 0x0, 0xffffffff7b74eac0), at 0xffffffff7b563350
[2] malloc(0x2c, 0x23e0, 0x1dac88, 0xffffffff7b5633d8, 0xffffffff7b73e000, 0x2000), at 0xffffffff7b5633c8
[3] sqlalc(0xffffffff7e79dc20, 0x8, 0x1003bf920, 0x200, 0x0, 0x541c), at 0xffffffff7c2a23c8
[4] sqlbrl(0xffffffff7e79dc20, 0x1003c0300, 0x1003c0328, 0x1003c02a0, 0xffffffff7fffeab0, 0x1), at 0xffffffff7c2ab1d4
[5] sqlhvdsc(0x1003c0290, 0xffffffff7e79dc20, 0x8, 0xffffffff7ffff040, 0x122, 0xffffffff7e79dc20), at 0xffffffff7c2c5194
[6] sqlshv(0xffffffff7e2fb350, 0x1, 0x1003c0290, 0xffffffff7fffec86, 0xa, 0x0), at 0xffffffff7c2c59cc
[7] sqlatm(0xffffffff7e79df78, 0x100151022, 0x100354330, 0x1, 0x5, 0x1003813c0), at 0xffffffff7c2c72cc
[8] sqlnst(0xffffffff7c2b5288, 0x85, 0x100150f18, 0x1, 0x0, 0xffffffff7ffff040), at 0xffffffff7c2b5618
[9] sqlcmex(0x6, 0x1003813c0, 0x910, 0x1, 0x100150f18, 0x0), at 0xffffffff7c2a61ec
[10] sqlcxt(0x0, 0x100150ec0, 0xffffffff7ffff040, 0x100152312, 0x4d, 0x0), at 0xffffffff7c2a6c44
=>[11] upd_prog_status(status = 30), line 476 in "CCFILT_x.pc"
[12] main(argc = 3, argv = 0xffffffff7ffff918), line 3698 in "CCFILT_x.pc"
My question is either it is possible that compile source with 10g and run it on 11g?
What about this malloc error. I read some where that you have to give definition of malloc in your code in oracle 11g?
Thanks and regards
Yes, it is possible that an application compiled with Oracle 10G, also run on Oracle 11G. But is vice versa will not work.
The above error indicates that there is some memory leak in application but the trace does not tell you the exact place. The leak have been long away from the trace.

Resources